Merge "Fix checkListKey not checking actual/expected values"
authorTony Tkacik <ttkacik@cisco.com>
Wed, 25 Feb 2015 15:27:51 +0000 (15:27 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 25 Feb 2015 15:27:51 +0000 (15:27 +0000)
243 files changed:
benchmarks/pom.xml
code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/DataObjectCodecContext.java
code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/EncapsulatedValueCodec.java
code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/EnumerationCodec.java
code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/IdentifiableItemCodec.java
code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/LazyDataObject.java
code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/UnionTypeCodec.java
code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/UnionValueOptionContext.java
code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/ValueContext.java
code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/Types.java
code-generator/binding-java-api-generator/pom.xml
code-generator/binding-parent/pom.xml
code-generator/maven-sal-api-gen-plugin/pom.xml
code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/maven/sal/api/gen/plugin/CodeGeneratorImpl.java
code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/unified/doc/generator/maven/DocumentationGeneratorImpl.java
code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/wadl/generator/maven/WadlGenerator.java
code-generator/maven-sal-api-gen-plugin/src/test/java/org/opendaylight/yangtools/yang/unified/doc/generator/maven/DocGenTest.java
code-generator/maven-sal-api-gen-plugin/src/test/java/org/opendaylight/yangtools/yang/wadl/generator/maven/WadlGenTest.java
code-generator/pom.xml
common/concepts/pom.xml
common/concepts/src/main/java/org/opendaylight/yangtools/concepts/Path.java
common/features-builder/pom.xml [deleted file]
common/features-test/pom.xml
common/features/pom.xml
common/features/src/main/features/features.xml [moved from common/features/src/main/feature/features.xml with 100% similarity]
common/parent/pom.xml
common/pom.xml
common/util/src/main/java/org/opendaylight/yangtools/util/concurrent/AsyncNotifyingListeningExecutorService.java
common/util/src/main/java/org/opendaylight/yangtools/util/concurrent/CachedThreadPoolExecutor.java
common/util/src/main/java/org/opendaylight/yangtools/util/concurrent/FastThreadPoolExecutor.java
common/util/src/test/java/org/opendaylight/yangtools/util/concurrent/QueuedNotificationManagerTest.java
common/util/src/test/java/org/opendaylight/yangtools/util/concurrent/ThreadPoolExecutorTest.java
integration-test/bundle-test/pom.xml
integration-test/pom.xml
model/ietf/ietf-netconf/pom.xml [deleted file]
model/ietf/ietf-topology/src/main/yang/network-topology@2013-10-21.yang
model/ietf/pom.xml
pom.xml
yang/pom.xml
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/OperationFailedException.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/QNameModule.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/RpcResultBuilder.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/YangConstants.java [new file with mode: 0644]
yang/yang-common/src/test/java/org/opendaylight/yangtools/yang/common/RpcResultBuilderTest.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/AbstractJSONCodec.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/BooleanJSONCodec.java [new file with mode: 0644]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONCodec.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONCodecFactory.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONLeafrefCodec.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONNormalizedNodeStreamWriter.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterContext.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterInvisibleContext.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterListContext.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterNamedObjectContext.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterObjectContext.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterRootContext.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterURIContext.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStringIdentityrefCodec.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStringInstanceIdentifierCodec.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonWriterFactory.java [new file with mode: 0644]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/NumberJSONCodec.java [moved from yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/UnquotedJSONCodec.java with 58% similarity]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/QuotedJSONCodec.java
yang/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/NormalizedNodeToJsonStreamTest.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/SchemaTracker.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XMLStreamNormalizedNodeStreamWriter.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlDocumentUtils.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/AbstractImmutableDataContainerAttrNode.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/AbstractImmutableNormalizedNode.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/AbstractImmutableNormalizedValueAttrNode.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/DataTreeState.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTree.java
yang/yang-maven-plugin-it/src/test/resources/test-parent/InvalidVersion/pom.xml
yang/yang-maven-plugin-spi/pom.xml
yang/yang-maven-plugin-spi/src/main/java/org/opendaylight/yangtools/yang2sources/spi/BasicCodeGenerator.java [new file with mode: 0644]
yang/yang-maven-plugin-spi/src/main/java/org/opendaylight/yangtools/yang2sources/spi/CodeGenerator.java
yang/yang-maven-plugin-spi/src/main/java/org/opendaylight/yangtools/yang2sources/spi/MavenLogAware.java [new file with mode: 0644]
yang/yang-maven-plugin-spi/src/main/java/org/opendaylight/yangtools/yang2sources/spi/MavenProjectAware.java [new file with mode: 0644]
yang/yang-maven-plugin-spi/src/test/java/org/opendaylight/yangtools/yang2sources/spi/CodeGeneratorTestImpl.java
yang/yang-maven-plugin/pom.xml
yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/Util.java
yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangToSourcesProcessor.java
yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/GenerateSourcesTest.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/ContainerSchemaNode.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/Rfc6020Mapping.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/SchemaPath.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/DeclaredStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/EffectiveStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/IdentifierNamespace.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/ModelStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/StatementDefinition.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/StatementSource.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/package-info.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/package-info.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/AnyxmlStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ArgumentStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/AugmentStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BaseStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BelongsToStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BitStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BodyGroup.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/CaseStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ChoiceStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ConditionalDataDefinition.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ConditionalFeature.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ConfigStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ContactStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ContainerStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataDefinitionContainer.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataDefinitionStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DefaultStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DescriptionStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DeviateStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DeviationStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DocumentationGroup.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DocumentedConstraintGroup.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/EnumStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ErrorAppTagStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ErrorMessageStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ExtensionStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FeatureStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FractionDigitsStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/GroupingStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IfFeatureStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ImportStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IncludeStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/InputStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/KeyStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LeafListStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LeafStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LengthStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LinkageGroup.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ListStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MandatoryStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MaxElementsStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MetaGroup.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MinElementsStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ModuleHeaderGroup.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ModuleStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MultipleElementsGroup.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MustStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NamespaceStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NotificationStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/OrderedByStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/OrganizationStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/OutputStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PathStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PatternStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PositionStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PrefixStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PresenceStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RangeStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ReferenceStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RefineStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RequireInstanceStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RevisionDateStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RevisionGroup.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RevisionStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/Rfc6020AbnfRule.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RpcStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaNodeIdentifier.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/StatusStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SubmoduleStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeGroup.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UniqueStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UnitsStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UnknownStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UsesStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ValueStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/WhenStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/YangVersionStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/YinElementStatement.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/repo/api/SchemaResolutionException.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/repo/api/YangTextSchemaSource.java
yang/yang-model-export/pom.xml [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedBinary.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedBits.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedBoolean.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedDecimal.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedEnum.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedIdentityref.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedInstanceIdentifier.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedInteger.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedLeafref.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedString.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedUnion.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedUnsignedInteger.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/ExtensionStatement.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/NormalizatedDerivedType.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/Rfc6020ModuleWriter.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/SchemaContextEmitter.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/SchemaToStatementWriterAdaptor.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/SingleModuleYinStatementWriter.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/StatementTextWriter.java [new file with mode: 0644]
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/YinExportUtils.java [new file with mode: 0644]
yang/yang-model-export/src/test/java/org/opendaylight/yangtools/yang/model/export/test/SimpleModuleTest.java [new file with mode: 0644]
yang/yang-model-export/src/test/resources/yang/ietf-inet-types@2010-09-24.yang [new file with mode: 0644]
yang/yang-model-util/pom.xml
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/repo/util/FilesystemSchemaSourceCache.java
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/AbstractSchemaContext.java [new file with mode: 0644]
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/FilteringSchemaContextProxy.java [new file with mode: 0644]
yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/repo/util/FilesystemSchemaSourceCacheTest.java
yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/SchemaContextProxyTest.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/CopyUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/SchemaContextImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserListenerImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/DependencyResolver.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/URLSchemaContextResolver.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractDeclaredStatement.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractStatementSupport.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ImportedNamespaceContext.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/InferenceException.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelActionBuilder.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelProcessingPhase.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceNotAvailableException.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ReactorException.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/SomeModifiersUnresolvedException.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementFactory.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementNamespace.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupportBundle.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/DeclarationInTextSource.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/PrefixToModule.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinition.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/SourceException.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/StatementSourceReference.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/StatementStreamSource.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/StatementWriter.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/TextToASTTransformer.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/GroupingTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/TestUtils.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/TypesResolutionTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/ResourceYangSource.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/SharedSchemaRepositoryTest.java
yang/yang-parser-impl/src/test/resources/added-by-uses-leaf-test/foo.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/added-by-uses-leaf-test/import-module.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/types/union-in-list/unioninlisttest.yang [new file with mode: 0644]

index 0e444405b5ff1e69e702145db0c1f6d3e40c8ee5..1c5b45ef603938fb728381de38df4292b5941f42 100644 (file)
@@ -1,82 +1,89 @@
 <?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">
-  <parent>
+    <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
         <version>0.7.0-SNAPSHOT</version>
         <relativePath>../common/parent</relativePath>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
 
-  <groupId>org.opendaylight.yangtools</groupId>
-  <artifactId>benchmarks</artifactId>
+    <artifactId>benchmarks</artifactId>
 
-  <properties>
-    <yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
-    <yang.maven.plugin.version>0.7.0-SNAPSHOT</yang.maven.plugin.version>
-    <java.source.version>1.7</java.source.version>
-    <java.target.version>1.7</java.target.version>
-    <jmh.version>0.9.7</jmh.version>
-  </properties>
+    <properties>
+        <yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
+        <yang.maven.plugin.version>0.7.0-SNAPSHOT</yang.maven.plugin.version>
+        <java.source.version>1.7</java.source.version>
+        <java.target.version>1.7</java.target.version>
+        <jmh.version>0.9.7</jmh.version>
+    </properties>
 
-  <dependencies>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>yang-data-impl</artifactId>
-      <version>${yangtools.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>yang-parser-impl</artifactId>
-      <version>${yangtools.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.openjdk.jmh</groupId>
-      <artifactId>jmh-core</artifactId>
-      <version>${jmh.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.openjdk.jmh</groupId>
-      <artifactId>jmh-generator-annprocess</artifactId>
-      <version>${jmh.version}</version>
-    </dependency>
-  </dependencies>
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>yang-data-impl</artifactId>
+            <version>${yangtools.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>yang-parser-impl</artifactId>
+            <version>${yangtools.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjdk.jmh</groupId>
+            <artifactId>jmh-core</artifactId>
+            <version>${jmh.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjdk.jmh</groupId>
+            <artifactId>jmh-generator-annprocess</artifactId>
+            <version>${jmh.version}</version>
+        </dependency>
+    </dependencies>
 
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <configuration>
-          <source>${java.source.version}</source>
-          <target>${java.source.version}</target>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>exec-maven-plugin</artifactId>
-        <configuration>
-          <classpathScope>test</classpathScope>
-          <executable>java</executable>
-          <arguments>
-            <argument>-classpath</argument>
-            <classpath/>
-            <argument>org.openjdk.jmh.Main</argument>
-            <argument>.*</argument>
-          </arguments>
-        </configuration>
-        <executions>
-          <execution>
-            <id>run-benchmarks</id>
-            <phase>integration-test</phase>
-            <goals>
-              <goal>exec</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${java.source.version}</source>
+                    <target>${java.source.version}</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <configuration>
+                    <classpathScope>test</classpathScope>
+                    <executable>java</executable>
+                    <arguments>
+                        <argument>-classpath</argument>
+                        <classpath/>
+                        <argument>org.openjdk.jmh.Main</argument>
+                        <argument>.*</argument>
+                    </arguments>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>run-benchmarks</id>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
index f3ebb96489ee62303290e7c06972b778ab7bcfa2..e5d58cc82f3cd15e60fcae946e588d9e20bcd47b 100644 (file)
@@ -9,11 +9,14 @@ package org.opendaylight.yangtools.binding.data.codec.impl;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSortedMap;
-import java.lang.reflect.Constructor;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
 import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.util.Collection;
@@ -48,7 +51,9 @@ import org.slf4j.LoggerFactory;
 
 abstract class DataObjectCodecContext<T extends DataNodeContainer> extends DataContainerCodecContext<T> {
     private static final Logger LOG = LoggerFactory.getLogger(DataObjectCodecContext.class);
-    private static final Class<?>[] CONSTRUCTOR_ARGS = new Class[] { InvocationHandler.class };
+    private static final Lookup LOOKUP = MethodHandles.publicLookup();
+    private static final MethodType CONSTRUCTOR_TYPE = MethodType.methodType(void.class, InvocationHandler.class);
+    private static final MethodType DATAOBJECT_TYPE = MethodType.methodType(DataObject.class, InvocationHandler.class);
     private static final Comparator<Method> METHOD_BY_ALPHABET = new Comparator<Method>() {
         @Override
         public int compare(final Method o1, final Method o2) {
@@ -61,7 +66,7 @@ abstract class DataObjectCodecContext<T extends DataNodeContainer> extends DataC
     private final ImmutableSortedMap<Method, NodeContextSupplier> byMethod;
     private final ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byStreamClass;
     private final ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byBindingArgClass;
-    private final Constructor<?> proxyConstructor;
+    private final MethodHandle proxyConstructor;
 
     // FIXME: this field seems to be unused
     private final Method augmentationGetter;
@@ -123,9 +128,9 @@ abstract class DataObjectCodecContext<T extends DataNodeContainer> extends DataC
 
         final Class<?> proxyClass = Proxy.getProxyClass(bindingClass().getClassLoader(),  new Class[] { bindingClass() });
         try {
-            proxyConstructor = proxyClass.getConstructor(CONSTRUCTOR_ARGS);
-        } catch (NoSuchMethodException | SecurityException e) {
-            throw new IllegalStateException("Failed to find constructor");
+            proxyConstructor = LOOKUP.findConstructor(proxyClass, CONSTRUCTOR_TYPE).asType(DATAOBJECT_TYPE);
+        } catch (NoSuchMethodException | IllegalAccessException e) {
+            throw new IllegalStateException("Failed to find contructor for class " + proxyClass);
         }
     }
 
@@ -271,9 +276,9 @@ abstract class DataObjectCodecContext<T extends DataNodeContainer> extends DataC
 
     protected final DataObject createBindingProxy(final NormalizedNodeContainer<?, ?, ?> node) {
         try {
-            return (DataObject) proxyConstructor.newInstance(new Object[] { new LazyDataObject(this, node) });
-        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-            throw new IllegalStateException("Failed to construct proxy for " + node, e);
+            return (DataObject) proxyConstructor.invokeExact((InvocationHandler)new LazyDataObject(this, node));
+        } catch (Throwable e) {
+            throw Throwables.propagate(e);
         }
     }
 
index 0b3b4678ad407aa4604bbb8a064f7ac667c6a093..3de5085c1d7c9f8decb1b407e91453781f6957a0 100644 (file)
@@ -7,8 +7,12 @@
  */
 package org.opendaylight.yangtools.binding.data.codec.impl;
 
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
 import java.lang.reflect.Method;
 import java.util.concurrent.Callable;
 import org.opendaylight.yangtools.binding.data.codec.impl.ValueTypeCodec.SchemaUnawareCodec;
@@ -19,26 +23,26 @@ import org.opendaylight.yangtools.binding.data.codec.impl.ValueTypeCodec.SchemaU
  * types, which are same as in NormalizedNode model.
  *
  */
-class EncapsulatedValueCodec extends ReflectionBasedCodec implements SchemaUnawareCodec {
+final class EncapsulatedValueCodec extends ReflectionBasedCodec implements SchemaUnawareCodec {
+    private static final Lookup LOOKUP = MethodHandles.publicLookup();
+    private static final MethodType OBJ_METHOD = MethodType.methodType(Object.class, Object.class);
+    private final MethodHandle constructor;
+    private final MethodHandle getter;
 
-    private final Method getter;
-    private final Constructor<?> constructor;
-
-    EncapsulatedValueCodec(final Class<?> typeClz) {
+    private EncapsulatedValueCodec(final Class<?> typeClz, final MethodHandle constructor, final MethodHandle getter) {
         super(typeClz);
-        try {
-            this.getter = typeClz.getMethod("getValue");
-            this.constructor = typeClz.getConstructor(getter.getReturnType());
-        } catch (NoSuchMethodException | SecurityException e) {
-            throw new IllegalStateException("Could not resolve required method.", e);
-        }
+        this.constructor = Preconditions.checkNotNull(constructor);
+        this.getter = Preconditions.checkNotNull(getter);
     }
 
     static Callable<EncapsulatedValueCodec> loader(final Class<?> typeClz) {
         return new Callable<EncapsulatedValueCodec>() {
             @Override
             public EncapsulatedValueCodec call() throws Exception {
-                return new EncapsulatedValueCodec(typeClz);
+                final Method m = typeClz.getMethod("getValue");
+                final MethodHandle getter = LOOKUP.unreflect(m).asType(OBJ_METHOD);
+                final MethodHandle constructor = LOOKUP.findConstructor(typeClz, MethodType.methodType(void.class, m.getReturnType())).asType(OBJ_METHOD);
+                return new EncapsulatedValueCodec(typeClz, constructor, getter);
             }
         };
     }
@@ -46,18 +50,18 @@ class EncapsulatedValueCodec extends ReflectionBasedCodec implements SchemaUnawa
     @Override
     public Object deserialize(final Object input) {
         try {
-            return constructor.newInstance(input);
-        } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
-            throw new IllegalStateException(e);
+            return constructor.invokeExact(input);
+        } catch (Throwable e) {
+            throw Throwables.propagate(e);
         }
     }
 
     @Override
     public Object serialize(final Object input) {
         try {
-            return getter.invoke(input);
-        } catch (IllegalAccessException | InvocationTargetException e) {
-            throw new IllegalStateException(e);
+            return getter.invokeExact(input);
+        } catch (Throwable e) {
+            throw Throwables.propagate(e);
         }
     }
 }
\ No newline at end of file
index e5788fe11c8eb504616d5253c91952cad641eaf3..a35a5621a2d904b49fa2e861c9b4a5bfba164769 100644 (file)
@@ -17,16 +17,15 @@ import org.opendaylight.yangtools.yang.binding.BindingMapping;
 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
 
-class EnumerationCodec extends ReflectionBasedCodec implements SchemaUnawareCodec {
+final class EnumerationCodec extends ReflectionBasedCodec implements SchemaUnawareCodec {
 
-    ImmutableBiMap<String, Enum<?>> yangValueToBinding;
+    private final ImmutableBiMap<String, Enum<?>> yangValueToBinding;
 
     public EnumerationCodec(final Class<? extends Enum<?>> enumeration, final Map<String, Enum<?>> schema) {
         super(enumeration);
         yangValueToBinding = ImmutableBiMap.copyOf(schema);
     }
 
-
     static Callable<EnumerationCodec> loader(final Class<?> returnType,
             final EnumTypeDefinition enumSchema) {
         Preconditions.checkArgument(Enum.class.isAssignableFrom(returnType));
@@ -51,7 +50,6 @@ class EnumerationCodec extends ReflectionBasedCodec implements SchemaUnawareCode
         };
     }
 
-
     @Override
     public Object deserialize(final Object input) {
         Enum<?> value = yangValueToBinding.get(input);
index ebaaf7ab4bd07e6ff9034bea44ddddcc6ca20aa6..09231179d2a4731fe48f1cf8311ff7d18da13f63 100644 (file)
@@ -7,12 +7,18 @@
  */
 package org.opendaylight.yangtools.binding.data.codec.impl;
 
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import org.opendaylight.yangtools.concepts.Codec;
@@ -23,16 +29,32 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdent
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 
 final class IdentifiableItemCodec implements Codec<NodeIdentifierWithPredicates, IdentifiableItem<?, ?>> {
+    private static final Comparator<QName> KEYARG_COMPARATOR = new Comparator<QName>() {
+        @Override
+        public int compare(final QName q1, final QName q2) {
+            return q1.getLocalName().compareToIgnoreCase(q2.getLocalName());
+        }
+    };
+    private static final Lookup LOOKUP = MethodHandles.publicLookup();
     private final Map<QName, ValueContext> keyValueContexts;
+    private final List<QName> keysInBindingOrder;
     private final ListSchemaNode schema;
-    private final Constructor<? extends Identifier<?>> constructor;
     private final Class<?> identifiable;
+    private final MethodHandle ctorInvoker;
+    private final MethodHandle ctor;
 
     public IdentifiableItemCodec(final ListSchemaNode schema, final Class<? extends Identifier<?>> keyClass,
             final Class<?> identifiable, final Map<QName, ValueContext> keyValueContexts) {
         this.schema = schema;
         this.identifiable = identifiable;
-        this.constructor = getConstructor(keyClass);
+
+        try {
+            ctor = LOOKUP.unreflectConstructor(getConstructor(keyClass));
+        } catch (IllegalAccessException e) {
+            throw new IllegalArgumentException("Missing construct in class " + keyClass);
+        }
+        final MethodHandle inv = MethodHandles.spreadInvoker(ctor.type(), 0);
+        this.ctorInvoker = inv.asType(inv.type().changeReturnType(Identifier.class));
 
         /*
          * We need to re-index to make sure we instantiate nodes in the order in which
@@ -43,22 +65,49 @@ final class IdentifiableItemCodec implements Codec<NodeIdentifierWithPredicates,
             keys.put(qname, keyValueContexts.get(qname));
         }
         this.keyValueContexts = ImmutableMap.copyOf(keys);
+
+        /*
+         * When instantiating binding objects we need to specify constructor arguments
+         * in alphabetic order. We play a couple of tricks here to optimize CPU/memory
+         * trade-offs.
+         *
+         * We do not have to perform a sort if the source collection has less than two
+         * elements.
+
+         * We always perform an ImmutableList.copyOf(), as that will turn into a no-op
+         * if the source is already immutable. It will also produce optimized implementations
+         * for empty and singleton collections.
+         *
+         * BUG-2755: remove this if order is made declaration-order-dependent
+         */
+        final List<QName> unsortedKeys = schema.getKeyDefinition();
+        final List<QName> sortedKeys;
+        if (unsortedKeys.size() > 1) {
+            final List<QName> tmp = new ArrayList<>(unsortedKeys);
+            Collections.sort(tmp, KEYARG_COMPARATOR);
+            sortedKeys = tmp;
+        } else {
+            sortedKeys = unsortedKeys;
+        }
+
+        this.keysInBindingOrder = ImmutableList.copyOf(sortedKeys);
     }
 
     @Override
     public IdentifiableItem<?, ?> deserialize(final NodeIdentifierWithPredicates input) {
-        final Collection<QName> keys = schema.getKeyDefinition();
-        final ArrayList<Object> bindingValues = new ArrayList<>(keys.size());
-        for (final QName key : keys) {
+        final Object[] bindingValues = new Object[keysInBindingOrder.size()];
+        int offset = 0;
+
+        for (final QName key : keysInBindingOrder) {
             final Object yangValue = input.getKeyValues().get(key);
-            bindingValues.add(keyValueContexts.get(key).deserialize(yangValue));
+            bindingValues[offset++] = keyValueContexts.get(key).deserialize(yangValue);
         }
 
         final Identifier<?> identifier;
         try {
-            identifier = constructor.newInstance(bindingValues.toArray());
-        } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
-            throw new IllegalStateException(String.format("Failed to instantiate key class %s", constructor.getDeclaringClass()), e);
+            identifier = (Identifier<?>) ctorInvoker.invokeExact(ctor, bindingValues);
+        } catch (Throwable e) {
+            throw Throwables.propagate(e);
         }
 
         @SuppressWarnings({ "rawtypes", "unchecked" })
index 9a3f24feb27f0909b77b93c5b9cc6886285bcb97..5cfc6f056c63a08d4a9f05c5c4f3fba196c4d6e4 100644 (file)
@@ -7,7 +7,8 @@
  */
 package org.opendaylight.yangtools.binding.data.codec.impl;
 
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
@@ -166,7 +167,7 @@ class LazyDataObject implements InvocationHandler, AugmentationReader {
     }
 
     public String bindingToString() {
-        final ToStringHelper helper = com.google.common.base.Objects.toStringHelper(context.bindingClass()).omitNullValues();
+        final ToStringHelper helper = MoreObjects.toStringHelper(context.bindingClass()).omitNullValues();
 
         for (final Method m :context.getHashCodeAndEqualsMethods()) {
             helper.add(m.getName(), getBindingData(m));
index ed8a2bc80ae37a632f03bb3024d5d129ed202c98..00702f07296d5e92d886d9020a746f9d67e3bd3a 100644 (file)
@@ -8,14 +8,12 @@
 package org.opendaylight.yangtools.binding.data.codec.impl;
 
 import com.google.common.collect.ImmutableSet;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.concurrent.Callable;
-
 import org.opendaylight.yangtools.concepts.Codec;
 import org.opendaylight.yangtools.yang.binding.BindingMapping;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
@@ -24,8 +22,8 @@ import org.opendaylight.yangtools.yang.model.util.UnionType;
 
 final class UnionTypeCodec extends ReflectionBasedCodec {
 
-    private Constructor<?> charConstructor;
-    private ImmutableSet<UnionValueOptionContext> typeCodecs;
+    private final ImmutableSet<UnionValueOptionContext> typeCodecs;
+    private final Constructor<?> charConstructor;
 
     private UnionTypeCodec(final Class<?> unionCls,final Set<UnionValueOptionContext> codecs) {
         super(unionCls);
@@ -37,7 +35,7 @@ final class UnionTypeCodec extends ReflectionBasedCodec {
         }
     }
 
-    static final Callable<UnionTypeCodec> loader(final Class<?> unionCls, final UnionTypeDefinition unionType) {
+    static Callable<UnionTypeCodec> loader(final Class<?> unionCls, final UnionTypeDefinition unionType) {
         return new Callable<UnionTypeCodec>() {
             @Override
             public UnionTypeCodec call() throws NoSuchMethodException, SecurityException {
@@ -54,7 +52,7 @@ final class UnionTypeCodec extends ReflectionBasedCodec {
         };
     }
 
-    private static Codec<Object, Object> getCodecForType(Class valueType, TypeDefinition subtype) {
+    private static Codec<Object, Object> getCodecForType(final Class<?> valueType, final TypeDefinition<?> subtype) {
         if (subtype.getBaseType() instanceof UnionType) {
             try {
                 return UnionTypeCodec.loader(valueType, (UnionType) subtype.getBaseType()).call();
@@ -77,10 +75,10 @@ final class UnionTypeCodec extends ReflectionBasedCodec {
 
     @Override
     public Object serialize(final Object input) {
-        if(input != null) {
-            for(UnionValueOptionContext valCtx : typeCodecs) {
+        if (input != null) {
+            for (UnionValueOptionContext valCtx : typeCodecs) {
                 Object domValue = valCtx.serialize(input);
-                if(domValue != null) {
+                if (domValue != null) {
                     return domValue;
                 }
             }
index f1cb431f58cd8314129336d05f5a361258e695fe..7c4c14453f8649ae8b55fe8002a656d567de9d2e 100644 (file)
@@ -7,35 +7,48 @@
  */
 package org.opendaylight.yangtools.binding.data.codec.impl;
 
-import java.lang.reflect.InvocationTargetException;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
 import java.lang.reflect.Method;
 import org.opendaylight.yangtools.concepts.Codec;
 
 final class UnionValueOptionContext {
+    private static final Lookup LOOKUP = MethodHandles.publicLookup();
+    private static final MethodType OBJECT_TYPE = MethodType.methodType(Object.class, Object.class);
+    private final Class<?> bindingType;
+    // FIXME: migrate to invocation
+    private final MethodHandle getter;
+    private final Codec<Object,Object> codec;
 
-    final Method getter;
-    final Class<?> bindingType;
-    final Codec<Object,Object> codec;
+    UnionValueOptionContext(final Class<?> valueType, final Method getter, final Codec<Object, Object> codec) {
+        this.bindingType = Preconditions.checkNotNull(valueType);
+        this.codec = Preconditions.checkNotNull(codec);
 
-    UnionValueOptionContext(final Class<?> valueType,final Method getter, final Codec<Object, Object> codec) {
-        this.getter = getter;
-        this.bindingType = valueType;
-        this.codec = codec;
+        try {
+            this.getter = LOOKUP.unreflect(getter).asType(OBJECT_TYPE);
+        } catch (IllegalAccessException e) {
+            throw new IllegalStateException("Failed to access method " + getter, e);
+        }
     }
 
-    public Object serialize(final Object input) {
-        Object baValue = getValueFrom(input);
-        if(baValue != null) {
-            return codec.serialize(baValue);
+    Object serialize(final Object input) {
+        final Object baValue = getValueFrom(input);
+        if (baValue == null) {
+            return null;
         }
-        return null;
+
+        return codec.serialize(baValue);
     }
 
-    public Object getValueFrom(final Object input) {
+    Object getValueFrom(final Object input) {
         try {
-            return getter.invoke(input);
-        } catch (IllegalAccessException  | InvocationTargetException e) {
-            throw new IllegalStateException(e);
+            return getter.invokeExact(input);
+        } catch (Throwable e) {
+            throw Throwables.propagate(e);
         }
     }
 
@@ -49,13 +62,11 @@ final class UnionValueOptionContext {
         if (this == obj) {
             return true;
         }
-        if (obj == null) {
+        if (!(obj instanceof UnionValueOptionContext)) {
             return false;
         }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        UnionValueOptionContext other = (UnionValueOptionContext) obj;
+
+        final UnionValueOptionContext other = (UnionValueOptionContext) obj;
         return bindingType.equals(other.bindingType);
     }
 }
\ No newline at end of file
index 86c0057031c1af45a302af9c06d4051c9a518450..1308846cc8ebb79351382e93cf51e14850c704f9 100644 (file)
@@ -8,36 +8,45 @@
 package org.opendaylight.yangtools.binding.data.codec.impl;
 
 import com.google.common.base.Preconditions;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
+import com.google.common.base.Throwables;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
 import org.opendaylight.yangtools.concepts.Codec;
 import org.opendaylight.yangtools.yang.binding.BindingMapping;
 
 final class ValueContext {
+    private static final Lookup LOOKUP = MethodHandles.publicLookup();
+    private static final MethodType OBJECT_METHOD = MethodType.methodType(Object.class, Object.class);
     private final Codec<Object, Object> codec;
-    private final Method getter;
+    private final MethodHandle getter;
+    private final Class<?> identifier;
+    private final String getterName;
 
     ValueContext(final Class<?> identifier, final LeafNodeCodecContext leaf) {
-        final String getterName = BindingCodecContext.GETTER_PREFIX
-                + BindingMapping.getClassName(leaf.getDomPathArgument().getNodeType());
+        getterName = BindingCodecContext.GETTER_PREFIX + BindingMapping.getClassName(leaf.getDomPathArgument().getNodeType());
         try {
-            getter = identifier.getMethod(getterName);
-        } catch (NoSuchMethodException | SecurityException e) {
-            throw new IllegalStateException(e);
+            getter = LOOKUP.unreflect(identifier.getMethod(getterName)).asType(OBJECT_METHOD);
+        } catch (IllegalAccessException | NoSuchMethodException | SecurityException e) {
+            throw new IllegalStateException(String.format("Cannot find method %s in class %s", getterName, identifier), e);
         }
+        this.identifier = identifier;
         codec = leaf.getValueCodec();
     }
 
     Object getAndSerialize(final Object obj) {
+        final Object value;
         try {
-            final Object value = getter.invoke(obj);
-            Preconditions.checkArgument(value != null,
-                    "All keys must be specified for %s. Missing key is %s. Supplied key is %s",
-                    getter.getDeclaringClass(), getter.getName(), obj);
-            return codec.serialize(value);
-        } catch (IllegalAccessException | InvocationTargetException e) {
-            throw new IllegalArgumentException(e);
+            value = getter.invokeExact(obj);
+        } catch (Throwable e) {
+            throw Throwables.propagate(e);
         }
+
+        Preconditions.checkArgument(value != null,
+                "All keys must be specified for %s. Missing key is %s. Supplied key is %s",
+                identifier, getterName, obj);
+        return codec.serialize(value);
     }
 
     Object deserialize(final Object obj) {
index 123287cf503249d1875d60f6da006ace646e9cee..def0b2766a782fb9894d7324afbc10f37ee4e3a8 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.yangtools.binding.generator.util;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -271,7 +270,7 @@ public final class Types {
         public ParametrizedTypeImpl(final Type rawType, final Type[] actTypes) {
             super(rawType.getPackageName(), rawType.getName());
             this.rawType = rawType;
-            this.actualTypes = Arrays.copyOf(actTypes, actTypes.length);
+            this.actualTypes = actTypes.clone();
         }
 
     }
index b31e1122cabe8c64f6d206f437be83a856ebaff2..51aa5c7629c587f4ef3310e688d9044adaf504eb 100644 (file)
         </dependency>
         <dependency>
             <groupId>org.codehaus.plexus</groupId>
-            <artifactId>plexus-slf4j-logging</artifactId>
+            <artifactId>plexus-container-default</artifactId>
+            <version>1.5.6</version>
+            <scope>provided</scope>
+            <exclusions>
+                <!-- plexus-build-api pulls in version 1.5.8, while this pulls in 3.0.20.
+                     Dependency convergence would break if we did not specify this. -->
+                <exclusion>
+                    <groupId>org.codehaus.plexus</groupId>
+                    <artifactId>plexus-utils</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
+
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
index 0723bc8416a016545b50de5fd2502a4440afc884..c38481e8d499af78d692e66f4c70d63ac1e3ed8c 100644 (file)
         <salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath>
     </properties>
 
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yangtools-artifacts</artifactId>
+                <version>${yangtools.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
     <profiles>
         <profile>
             <activation>
                     <exists>src/main/yang</exists>
                 </file>
             </activation>
-            <dependencyManagement>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.opendaylight.yangtools</groupId>
-                        <artifactId>yangtools-artifacts</artifactId>
-                        <version>${yangtools.version}</version>
-                        <type>pom</type>
-                        <scope>import</scope>
-                    </dependency>
-                </dependencies>
-            </dependencyManagement>
             <dependencies>
-              <dependency>
-                <groupId>org.opendaylight.yangtools</groupId>
-                <artifactId>yang-binding</artifactId>
-              </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>yang-binding</artifactId>
+                </dependency>
             </dependencies>
             <build>
                 <pluginManagement>
                                 </execution>
                             </executions>
                         </plugin>
-                      <plugin>
-                        <artifactId>maven-clean-plugin</artifactId>
-                        <configuration>
-                          <filesets>
-                            <fileset>
-                              <directory>${salGeneratorPath}</directory>
-                              <includes>
-                                <include>**</include>
-                              </includes>
-                            </fileset>
-                          </filesets>
-                        </configuration>
-                      </plugin>
+                        <plugin>
+                            <artifactId>maven-clean-plugin</artifactId>
+                            <configuration>
+                                <filesets>
+                                    <fileset>
+                                        <directory>${salGeneratorPath}</directory>
+                                        <includes>
+                                            <include>**</include>
+                                        </includes>
+                                    </fileset>
+                                </filesets>
+                            </configuration>
+                        </plugin>
+                        <plugin>
+                            <groupId>org.codehaus.mojo</groupId>
+                            <artifactId>build-helper-maven-plugin</artifactId>
+                            <executions>
+                                <execution>
+                                    <id>add-yang-sources</id>
+                                    <phase>generate-sources</phase>
+                                    <goals>
+                                        <goal>add-source</goal>
+                                    </goals>
+                                    <configuration>
+                                        <sources>
+                                            <source>${salGeneratorPath}</source>
+                                        </sources>
+                                    </configuration>
+                                </execution>
+                            </executions>
+                        </plugin>
                     </plugins>
                 </pluginManagement>
-              <plugins>
-                <plugin>
-                  <groupId>org.opendaylight.yangtools</groupId>
-                  <artifactId>yang-maven-plugin</artifactId>
-                  <version>${yangtools.version}</version>
-                </plugin>
-              </plugins>
+                <plugins>
+                    <plugin>
+                        <groupId>org.opendaylight.yangtools</groupId>
+                        <artifactId>yang-maven-plugin</artifactId>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>build-helper-maven-plugin</artifactId>
+                    </plugin>
+                </plugins>
             </build>
         </profile>
     </profiles>
index f8ccd295a21b245bc927a267b9821857177939cf..67a9e6f05ea0e2d4285dae55d976d6929fa6cb90 100644 (file)
             <groupId>org.sonatype.plexus</groupId>
             <artifactId>plexus-build-api</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.codehaus.plexus</groupId>
-            <artifactId>plexus-slf4j-logging</artifactId>
-        </dependency>
 
         <dependency>
             <groupId>junit</groupId>
index 99f426dcc68c888492f3f730cbab95e8e7e9469d..867aca948f383f42f50c4e83fcee9bd5fc35d681 100644 (file)
@@ -23,7 +23,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.project.MavenProject;
 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
@@ -35,19 +34,19 @@ import org.opendaylight.yangtools.yang.binding.BindingMapping;
 import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
 import org.opendaylight.yangtools.yang2sources.spi.BuildContextAware;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.MavenProjectAware;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonatype.plexus.build.incremental.BuildContext;
 
-public final class CodeGeneratorImpl implements CodeGenerator, BuildContextAware {
+public final class CodeGeneratorImpl implements BasicCodeGenerator, BuildContextAware, MavenProjectAware {
+    private static final Logger logger = LoggerFactory.getLogger(CodeGeneratorImpl.class);
     private static final String FS = File.separator;
     private BuildContext buildContext;
     private File projectBaseDir;
     private Map<String, String> additionalConfig;
-
-    private static final Logger logger = LoggerFactory.getLogger(CodeGeneratorImpl.class);
     private MavenProject mavenProject;
     private File resourceBaseDir;
 
@@ -124,10 +123,6 @@ public final class CodeGeneratorImpl implements CodeGenerator, BuildContextAware
         mavenProject.addCompileSourceRoot(outputBaseDir.getPath());
     }
 
-    @Override
-    public void setLog(final Log log) {
-    }
-
     @Override
     public void setAdditionalConfig(final Map<String, String> additionalConfiguration) {
         this.additionalConfig = additionalConfiguration;
index c3e7d3038236aab0c224c7f3d51c6be00e6233bb..fafb85970837291654a352f817c5f9a05ed3d296 100644 (file)
@@ -13,14 +13,12 @@ import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.maven.plugin.logging.Log;
-import org.apache.maven.project.MavenProject;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.unified.doc.generator.GeneratorImpl;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
 
-public class DocumentationGeneratorImpl extends GeneratorImpl implements CodeGenerator {
+public class DocumentationGeneratorImpl extends GeneratorImpl implements BasicCodeGenerator {
 
     @Override
     public Collection<File> generateSources(SchemaContext arg0, File arg1, Set<Module> arg2) throws IOException {
@@ -28,12 +26,6 @@ public class DocumentationGeneratorImpl extends GeneratorImpl implements CodeGen
          return generate(arg0, arg1, arg2);
     }
 
-    @Override
-    public void setLog(Log log) {
-        // use maven logging if necessary
-
-    }
-
     @Override
     public void setAdditionalConfig(Map<String, String> additionalConfiguration) {
         // no additional config utilized
@@ -43,9 +35,4 @@ public class DocumentationGeneratorImpl extends GeneratorImpl implements CodeGen
     public void setResourceBaseDir(File resourceBaseDir) {
         // no resource processing necessary
     }
-
-    @Override
-    public void setMavenProject(MavenProject project) {
-        // no additional information needed
-    }
 }
index 35fac762257ffd7a7de52730f59b3a49f67a482b..6a05f7577bc53d2b7583eada4840ce9882ccd14f 100644 (file)
@@ -13,14 +13,12 @@ import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.maven.plugin.logging.Log;
-import org.apache.maven.project.MavenProject;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.wadl.generator.WadlRestconfGenerator;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
 
-public class WadlGenerator implements CodeGenerator {
+public class WadlGenerator implements BasicCodeGenerator {
     
     @Override
     public Collection<File> generateSources(SchemaContext context, File outputDir, Set<Module> currentModules)
@@ -28,6 +26,7 @@ public class WadlGenerator implements CodeGenerator {
         
         final File outputBaseDir;
         if (outputDir == null) {
+            // FIXME: this hard-codes the destination
             outputBaseDir = new File("target" + File.separator + "generated-sources" + File.separator
                     + "maven-sal-api-gen" + File.separator + "wadl");
         } else {
@@ -38,12 +37,6 @@ public class WadlGenerator implements CodeGenerator {
         return generator.generate(context, currentModules);
     }
 
-    @Override
-    public void setLog(Log log) {
-        // TODO Auto-generated method stub
-        
-    }
-
     @Override
     public void setAdditionalConfig(Map<String, String> additionalConfiguration) {
         // TODO Auto-generated method stub
@@ -55,11 +48,4 @@ public class WadlGenerator implements CodeGenerator {
         // TODO Auto-generated method stub
         
     }
-
-    @Override
-    public void setMavenProject(MavenProject project) {
-        // TODO Auto-generated method stub
-        
-    }
-
 }
index 1335450395acf9c3929204d8c266dadf46821f72..4e0e2541104256c6ab91f2cde0177bad9b310b11 100644 (file)
@@ -25,7 +25,7 @@ import org.junit.Test;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
 
 public class DocGenTest {
     public static final String FS = File.separator;
@@ -54,7 +54,7 @@ public class DocGenTest {
         final List<File> sourceFiles = getSourceFiles("/doc-gen");
         final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
         final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
-        final CodeGenerator generator = new DocumentationGeneratorImpl();
+        final BasicCodeGenerator generator = new DocumentationGeneratorImpl();
         Collection<File> generatedFiles = generator.generateSources(context, GENERATOR_OUTPUT_DIR, modulesToBuild);
         assertEquals(4, generatedFiles.size());
     }
index 756ba674ac8ba9f28be2ba4000d7566f41cfe589..4485b429a67a2b0eb1a1d387cd0f4e79e6912ecb 100644 (file)
@@ -25,7 +25,7 @@ import org.junit.Test;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
 
 public class WadlGenTest {
     public static final String FS = File.separator;
@@ -54,7 +54,7 @@ public class WadlGenTest {
         final List<File> sourceFiles = getSourceFiles("/wadl-gen");
         final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
         final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
-        final CodeGenerator generator = new WadlGenerator();
+        final BasicCodeGenerator generator = new WadlGenerator();
         Collection<File> generatedWadlFiles = generator.generateSources(context, GENERATOR_OUTPUT_DIR, modulesToBuild);
         assertEquals(3, generatedWadlFiles.size());
     }
index 4adede243f295e0d547aefb8ee496ceafcc5a5ef..324088dc7d3cffba53ada40b6ead92b7cf8f5f2e 100644 (file)
         <module>binding-data-codec</module>
         <module>binding-parent</module>
     </modules>
-
-    <build>
-        <pluginManagement>
-            <plugins>
-                <plugin>
-                    <groupId>org.apache.felix</groupId>
-                    <artifactId>maven-bundle-plugin</artifactId>
-                    <version>${maven.bundle.version}</version>
-                    <extensions>true</extensions>
-                    <executions>
-                        <execution>
-                            <id>bundle-manifest</id>
-                            <phase>process-classes</phase>
-                            <goals>
-                                <goal>manifest</goal>
-                            </goals>
-                        </execution>
-                    </executions>
-                </plugin>
-                <plugin>
-                    <groupId>org.eclipse.m2e</groupId>
-                    <artifactId>lifecycle-mapping</artifactId>
-                    <version>1.0.0</version>
-                    <configuration>
-                        <lifecycleMappingMetadata>
-                            <pluginExecutions>
-                                <pluginExecution>
-                                    <pluginExecutionFilter>
-                                        <groupId>org.apache.felix</groupId>
-                                        <artifactId>maven-bundle-plugin</artifactId>
-                                        <versionRange>[1.0,)</versionRange>
-                                        <goals>
-                                            <goal>manifest</goal>
-                                        </goals>
-                                    </pluginExecutionFilter>
-                                    <action>
-                                        <execute />
-                                    </action>
-                                </pluginExecution>
-                            </pluginExecutions>
-                        </lifecycleMappingMetadata>
-                    </configuration>
-                </plugin>
-            </plugins>
-        </pluginManagement>
-        <plugins>
-           <plugin>
-             <groupId>org.apache.maven.plugins</groupId>
-             <artifactId>maven-checkstyle-plugin</artifactId>
-           </plugin>
-        </plugins>
-    </build>
-
 </project>
index d0968de0960700a7ee8a3b3737468c9c48664020..d2b0867d8cb680838202e21192532e87b393dd86 100644 (file)
     <name>${project.artifactId}</name>
     <description>Common concepts</description>
 
+    <dependencies>
+        <dependency>
+            <groupId>com.google.code.findbugs</groupId>
+            <artifactId>jsr305</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
     <build>
         <plugins>
             <plugin>
index d73326432d5f97eb6d2279e91de3b9c80cc7fd5d..394f1b493ef43e8f9f906826ea17ad3737cc1f60 100644 (file)
@@ -7,7 +7,23 @@
  */
 package org.opendaylight.yangtools.concepts;
 
-public interface Path<P extends Path<P>> {
+import javax.annotation.Nonnull;
 
-    boolean contains(P other);
+/**
+ * Conceptual representation of a logical path in a tree-like structure, similar to a
+ * {@link java.nio.file.Path}, but more general in terms of what objects it can be applied to.
+ * Paths have an equivalence class, which is captured in the defining type. Paths also have the
+ * notion of containment, where one path is said to contain another path if it the data set
+ * identified by the former contains all elements of the data set represented by later.
+ *
+ * @param <P> Path equivalence class
+ */
+public interface Path<P extends Path<P>> {
+    /**
+     * Check if this path contains some other.
+     *
+     * @param other Other path, may not be null.
+     * @return True if this path contains the other.
+     */
+    boolean contains(@Nonnull P other);
 }
diff --git a/common/features-builder/pom.xml b/common/features-builder/pom.xml
deleted file mode 100644 (file)
index 0576893..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- 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
--->
-<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>
-    <parent>
-        <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>odlparent</artifactId>
-        <version>1.5.0-SNAPSHOT</version>
-    </parent>
-
-    <groupId>org.opendaylight.yangtools</groupId>
-    <artifactId>features-builder</artifactId>
-    <packaging>pom</packaging>
-    <version>0.7.0-SNAPSHOT</version>
-
-    <properties>
-        <features.file>features.xml</features.file>
-    </properties>
-
-    <build>
-        <resources>
-            <resource>
-                <directory>src/main/resources</directory>
-                <filtering>true</filtering>
-            </resource>
-        </resources>
-
-        <pluginManagement>
-            <plugins>
-                <!-- generate dependencies versions -->
-                <plugin>
-                    <artifactId>maven-dependency-plugin</artifactId>
-                      <executions>
-                          <execution>
-                              <phase>generate-resources</phase>
-                              <goals><goal>resolve</goal></goals>
-                              <configuration>
-                                  <outputFile>${project.build.directory}/dependencies.txt</outputFile>
-                              </configuration>
-                          </execution>
-                      </executions>
-                </plugin>
-                <plugin>
-                    <groupId>com.alexecollins.maven.plugin</groupId>
-                    <artifactId>script-maven-plugin</artifactId>
-                    <version>1.0.0</version>
-                    <executions>
-                        <execution>
-                        <id>add-version-to-features</id>
-                        <phase>generate-resources</phase>
-                            <goals>
-                                 <goal>execute</goal>
-                            </goals>
-                            <configuration>
-                                <language>groovy</language>
-                                <script>
-                                    /**
-                                     * Placeholder, which is used in src/feature/features.xml
-                                     * to mark version which should be inserted from dependencies.
-                                     * Currently works only for bundle and configfile tags
-                                     * with mvn: url schema, and needs to be used 
-                                     * as third component of schema.
-                                     * eg. mvn:group/artefact/{{VERSION}}
-                                     */
-                                    def versionPlaceholder = "{{VERSION}}"
-                                    /**
-                                     * Path to features.xml which uses versionPlaceholder.
-                                     * This will be processed by this script.
-                                     *
-                                     */
-                                    def featureFilePath = "src/main/feature/features.xml"
-                                    // Contains mapping of groupID:artefactID to versoin
-                                    def versionMap = new HashMap();
-                                    /* Loads transitive dependency list generated from
-                                     * maven-dependency-plugin resolve goal
-                                     * and populates map
-                                     */
-                                    def dependencies = new File(project.build.directory,"dependencies.txt")
-                                    dependencies.eachLine {
-                                        def cmps = it.trim().split(":")
-                                        // 0 - groupId
-                                        // 1 - artifactId
-                                        // 2 - Type
-                                        // 3 - Version
-                                        if(cmps.length >= 4) {
-                                            def id = cmps[0] + ":" + cmps[1]
-                                            versionMap[id] = cmps[3]
-                                        }
-                                    }
-
-                                    /*
-                                     * Takes splitted mvn: URL, looks for placeholder
-                                     * and returns new mvn: URL with version learned
-                                     * from dependency plugin.
-                                     *
-                                     * If referenced bundle is not dependency (direct or transitive)
-                                     * throws an exception and fails build.
-                                     *
-                                     */
-                                    def updatedURLFromProject = { args ->
-                                        // 0 - groupID, 1 - artifactID
-                                        // 2 - version, 3 - type, 4 - Classifier
-
-                                        def groupId = args[0];
-                                        def artifactId = args[1];
-                                        def id = groupId + ":" + artifactId
-                                        def dependencyVersion = versionMap[id]
-                                        if(dependencyVersion != null) {
-                                            // Overriding version
-                                            args[2] = dependencyVersion
-                                            return "mvn:" + args.join("/")
-                                        }
-                                        throw new IllegalArgumentException("Feature dependency $groupId:$artifactId is not dependecy of project.")
-                                    }
-
-
-                                    def updateMavenDependency  = { dep ->
-                                       def mvnUrl = dep.text()
-                                       if(mvnUrl.startsWith("mvn:")) {
-                                         def components =  mvnUrl.substring(4).split("/")
-                                         if(components[2] == versionPlaceholder) {
-                                         dep.value = updatedURLFromProject(components)
-                                         }
-                                       }
-                                    }
-
-                                    def featureFile = new File(project.basedir,featureFilePath)
-                                    def root = new XmlParser().parse(featureFile)
-
-                                    root.feature.each { feature ->
-                                        println "[INFO] Processing feature: ${feature.@name}"
-                                        feature.bundle.each updateMavenDependency
-                                        feature.configfile.each updateMavenDependency
-                                    }
-
-                                    def outDir = new File(project.build.directory,"generated-resources/script")
-                                    outDir.mkdirs();
-                                    def outFile = new File(outDir,"features.xml")
-                                    def outWriter = outFile.newPrintWriter("ASCII");
-                                    xmlPrinter = new XmlNodePrinter(outWriter);
-                                    xmlPrinter.preserveWhitespace = true
-                                    xmlPrinter.print(root)
-                                    outWriter.close();
-                                </script>
-                            </configuration>
-                        </execution>
-                    </executions>
-                    <dependencies>
-                        <dependency>
-                            <groupId>org.codehaus.groovy</groupId>
-                            <artifactId>groovy</artifactId>
-                            <version>1.8.6</version>
-                        </dependency>
-                    </dependencies>
-                </plugin>
-                <plugin>
-                    <groupId>org.apache.karaf.tooling</groupId>
-                    <artifactId>karaf-maven-plugin</artifactId>
-                    <version>${karaf.version}</version>
-                    <extensions>true</extensions>
-                    <executions>
-                        <execution>
-                            <id>features-create-kar</id>
-                            <goals>
-                                <goal>features-create-kar</goal>
-                            </goals>
-                            <configuration>
-                                <featuresFile>${project.build.directory}/classes/${features.file}</featuresFile>
-                            </configuration>
-                        </execution>
-                    </executions>
-                    <!-- There is no useful configuration for the kar mojo. The features-generate-descriptor mojo configuration may be useful -->
-                </plugin>
-                <plugin>
-                    <groupId>org.codehaus.mojo</groupId>
-                    <artifactId>build-helper-maven-plugin</artifactId>
-                    <executions>
-                        <execution>
-                        <phase>generate-resources</phase>
-                        <goals><goal>add-resource</goal></goals>
-                        <configuration>
-                            <resources>
-                              <resource>
-                                <directory>${project.build.directory}/generated-resources/script</directory>
-                                <filtering>true</filtering>
-                              </resource>
-                            </resources>
-                        </configuration>
-                        </execution>
-                        <execution>
-                            <id>attach-artifacts</id>
-                            <phase>package</phase>
-                            <goals>
-                                <goal>attach-artifact</goal>
-                            </goals>
-                            <configuration>
-                                <artifacts>
-                                    <artifact>
-                                        <file>${project.build.directory}/classes/${features.file}</file>
-                                        <type>xml</type>
-                                        <classifier>features</classifier>
-                                    </artifact>
-                                </artifacts>
-                            </configuration>
-                        </execution>
-                    </executions>
-                </plugin>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-resources-plugin</artifactId>
-                    <executions>
-                        <execution>
-                            <id>filter</id>
-                            <phase>generate-resources</phase>
-                            <goals>
-                                <goal>resources</goal>
-                            </goals>
-                        </execution>
-                    </executions>
-                </plugin>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-surefire-plugin</artifactId>
-                    <configuration>
-                        <dependenciesToScan>
-                            <dependency>org.opendaylight.yangtools:features-test</dependency>
-                        </dependenciesToScan>
-                    </configuration>
-                </plugin>
-            </plugins>
-        </pluginManagement>
-    </build>
-
-    <dependencies>
-        <!-- test the features.xml -->
-        <dependency>
-            <groupId>org.opendaylight.yangtools</groupId>
-            <artifactId>features-test</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
index d96aca0a24161a022d314c3a22978041b500d62a..50ff2715034365bf65876ad73328533e238b8ae6 100644 (file)
    <properties>
       <pax.exam.version>3.5.0</pax.exam.version>
    </properties>
+
+   <!-- Migrated to odlparent -->
+   <distributionManagement>
+     <relocation>
+       <groupId>org.opendaylight.odlparent</groupId>
+       <artifactId>features-test</artifactId>
+       <version>1.5.0-SNAPSHOT</version>
+       <message>This artifact has been migrated to odlparent and will be removed in Lithium release</message>
+     </relocation>
+   </distributionManagement>
+
    <dependencies>
      <!-- Dependencies for pax exam karaf container -->
 
index dbf95156e7ee86a1fee7419e863edf9167ebd6ca..3af9851fa23f660c6ba1417a6b43a2f378fd18af 100644 (file)
 <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>
     <parent>
-        <groupId>org.opendaylight.yangtools</groupId>
-        <artifactId>features-builder</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
-        <relativePath>../features-builder/pom.xml</relativePath>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>features-parent</artifactId>
+        <version>1.5.0-SNAPSHOT</version>
+        <relativePath/>
     </parent>
 
+    <groupId>org.opendaylight.yangtools</groupId>
     <artifactId>features-yangtools</artifactId>
+    <version>0.7.0-SNAPSHOT</version>
     <packaging>jar</packaging>
 
     <build>
index a5b37272aca40df9a2d384f917a80fe7f478a0d2..d0e43ef25f2e4acf51af270696092dba4c700079 100644 (file)
                                          <ignore/>
                                      </action>
                                  </pluginExecution>
+                                 <pluginExecution>
+                                    <pluginExecutionFilter>
+                                        <groupId>org.apache.maven.plugins</groupId>
+                                        <artifactId>maven-checkstyle-plugin</artifactId>
+                                        <versionRange>[2.12,)</versionRange>
+                                        <goals>
+                                            <goal>check</goal>
+                                        </goals>
+                                     </pluginExecutionFilter>
+                                     <action>
+                                         <execute/>
+                                     </action>
+                                 </pluginExecution>
                             </pluginExecutions>
                         </lifecycleMappingMetadata>
                     </configuration>
             </plugin>
         </plugins>
     </reporting>
-
-
-    <!-- Note: we can not use variables for these URLs because we need to
-         be able to download the parent pom from the repository the first
-         time we go to use it (since it is in a different project).
-         To override the settings, use the "mirror" section of the
-         settings.xml. See http://maven.apache.org/settings.html -->
-    <repositories>
-        <!-- OpenDayLight Repo Mirror -->
-        <repository>
-            <id>opendaylight-mirror</id>
-            <name>opendaylight-mirror</name>
-            <url>http://nexus.opendaylight.org/content/groups/public/</url>
-            <snapshots>
-                <enabled>false</enabled>
-            </snapshots>
-            <releases>
-                <enabled>true</enabled>
-                <updatePolicy>never</updatePolicy>
-            </releases>
-        </repository>
-
-        <!-- OpenDayLight Snapshot artifact -->
-        <repository>
-            <id>opendaylight-snapshot</id>
-            <name>opendaylight-snapshot</name>
-            <url>http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
-            <snapshots>
-                <enabled>true</enabled>
-            </snapshots>
-            <releases>
-                <enabled>false</enabled>
-            </releases>
-        </repository>
-    </repositories>
 </project>
index 986dea0b08df0929dccece3c39e1c180da3d3d6a..8c0bf84b1bcfeb4183fc1474e8ef45feff2b9d0d 100644 (file)
@@ -25,7 +25,6 @@
         <module>checkstyle-logging</module>
         <module>concepts</module>
         <module>features</module>
-        <module>features-builder</module>
         <module>features-test</module>
         <module>mockito-configuration</module>
         <module>object-cache-api</module>
index b0af84b907e1c0af3329347b7f9f79af5913b882..c5d00771ea27bde932207f741e3c76f910629ee8 100644 (file)
@@ -16,8 +16,8 @@ import java.util.concurrent.TimeUnit;
 
 import javax.annotation.Nullable;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.AbstractListeningExecutorService;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -144,7 +144,7 @@ public class AsyncNotifyingListeningExecutorService extends AbstractListeningExe
 
     @Override
     public final String toString(){
-        return addToStringAttributes( Objects.toStringHelper( this )
+        return addToStringAttributes( MoreObjects.toStringHelper( this )
                 .add( "delegate", delegate ) ).toString();
     }
 }
index a7dd4af009e06457925d305483c1bcb048455c62..66d332b5d7c6468b0aff6a1088dcd380fdef30a0 100644 (file)
@@ -14,8 +14,8 @@ import java.util.concurrent.RejectedExecutionHandler;
 import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 
@@ -102,7 +102,7 @@ public class CachedThreadPoolExecutor extends ThreadPoolExecutor {
 
     @Override
     public final String toString() {
-        return addToStringAttributes( Objects.toStringHelper( this )
+        return addToStringAttributes( MoreObjects.toStringHelper( this )
                 .add( "Thread Prefix", threadPrefix )
                 .add( "Current Thread Pool Size", getPoolSize() )
                 .add( "Largest Thread Pool Size", getLargestPoolSize() )
index 67b89aab516dc6b79f93e6d4356397db80636618..60a1b674609f6ef8268439e952f3fbdb260b432b 100644 (file)
@@ -11,8 +11,8 @@ package org.opendaylight.yangtools.util.concurrent;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 
 /**
@@ -95,7 +95,7 @@ public class FastThreadPoolExecutor extends ThreadPoolExecutor {
 
     @Override
     public final String toString() {
-        return addToStringAttributes( Objects.toStringHelper( this )
+        return addToStringAttributes( MoreObjects.toStringHelper( this )
                 .add( "Thread Prefix", threadPrefix )
                 .add( "Current Thread Pool Size", getPoolSize() )
                 .add( "Largest Thread Pool Size", getLargestPoolSize() )
index d7e0e503fe1c51c5a86735f904b553aa28f89905..7cc028a9f0ae1caee48b58f8f57f1e218440b275 100644 (file)
@@ -201,8 +201,7 @@ public class QueuedNotificationManagerTest {
             notifications[i-1] = Integer.valueOf( i );
         }
 
-        Stopwatch stopWatch = new Stopwatch();
-        stopWatch.start();
+        Stopwatch stopWatch = Stopwatch.createStarted();
 
         List<TestListener<Integer>> listeners = Lists.newArrayList();
         for( int i = 1; i <= nListeners; i++ ) {
index 4d280536a1c865b4896d764b235f69d442e86cd2..71258b87adc0f47f654dfdca3ec60ccd658a24fb 100644 (file)
@@ -108,8 +108,7 @@ public class ThreadPoolExecutorTest {
         final ConcurrentMap<Thread, AtomicLong> taskCountPerThread = new ConcurrentHashMap<>();
         final AtomicReference<AssertionError> threadError = new AtomicReference<>();
 
-        Stopwatch stopWatch = new Stopwatch();
-        stopWatch.start();
+        Stopwatch stopWatch = Stopwatch.createStarted();
 
         new Thread() {
             @Override
index 63de755288a069f5c5548348daca887848b6c388..42235ace5c538515a5a26f7758e4fc5cb337f41e 100644 (file)
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.codehaus.plexus</groupId>
-            <artifactId>plexus-slf4j-logging</artifactId>
-        </dependency>
 
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
index 1f81d960545412b6c752a705d9b8c66d25cb66de..0871e056e70544e2a207d4fd5daa8a73f3a7bb8d 100644 (file)
@@ -8,10 +8,10 @@
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
     <parent>
-      <groupId>org.opendaylight.yangtools</groupId>
-      <artifactId>yangtools-parent</artifactId>
-      <version>0.7.0-SNAPSHOT</version>
-      <relativePath>../common/parent</relativePath>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>yangtools-parent</artifactId>
+        <version>0.7.0-SNAPSHOT</version>
+        <relativePath>../common/parent</relativePath>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
         <module>regression-test-model</module>
         <module>yang-runtime-tests</module>
     </modules>
-
-    <build>
-        <plugins>
-           <plugin>
-             <groupId>org.apache.maven.plugins</groupId>
-             <artifactId>maven-checkstyle-plugin</artifactId>
-           </plugin>
-        </plugins>
-    </build>
 </project>
diff --git a/model/ietf/ietf-netconf/pom.xml b/model/ietf/ietf-netconf/pom.xml
deleted file mode 100644 (file)
index b1e051c..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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">
-
-    <parent>
-        <artifactId>model-ietf</artifactId>
-        <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
-    </parent>
-
-    <modelVersion>4.0.0</modelVersion>
-    <artifactId>ietf-netconf</artifactId>
-    <version>1.0-SNAPSHOT</version>
-    <name>${project.artifactId}</name>
-    <description>${project.artifactId}</description>
-
-    <packaging>bundle</packaging>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.opendaylight.yangtools.model</groupId>
-            <artifactId>ietf-inet-types</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.yangtools.model</groupId>
-            <artifactId>ietf-yang-types</artifactId>
-        </dependency>
-    </dependencies>
-</project>
index c11433446561f738641c037db4333cb0288c65be..a5103aa2a31efe6d05e04b39256aede8540688c6 100644 (file)
@@ -165,7 +165,12 @@ module network-topology  {
                 to provide room for augmentations, e.g. for
                 statistics or priorization information associated with
                 supporting nodes.";
-            key "node-ref";
+            // This is not what was published in the initial draft,
+            // added topology-ref leaf and added it to the key
+            key "topology-ref node-ref";
+            leaf topology-ref {
+                type topology-ref;
+            }
             leaf node-ref {
                 type node-ref;
             }
index b2a66bb5227cd0c744461f802bc34c0b6db3c4b1..fe4328cd0230a946799a825a4c19f9d3fab37894 100644 (file)
@@ -31,6 +31,5 @@
         <module>ietf-topology-l3-unicast-igp</module>
         <module>ietf-topology-ospf</module>
         <module>ietf-restconf</module>
-        <!--module>ietf-netconf</module -->
     </modules>
 </project>
diff --git a/pom.xml b/pom.xml
index e53e27146f3e6697a52fad57aaa73e2abf3d693b..faa849b89020ac81451ed49dbcd478d922030906 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -58,7 +58,6 @@
                 <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-checkstyle-plugin</artifactId>
-                 <version>2.12</version>
                  <configuration>
                    <failOnViolation>false</failOnViolation>
                    <configLocation>checkstyle-logging.xml</configLocation>
index b2c26631842b09e088070f835bb95462813d8109..a229553f39fe9466bf576498a7ddaa72835c2a19 100644 (file)
@@ -35,6 +35,7 @@
         <module>yang-model-util</module>
         <module>yang-parser-api</module>
         <module>yang-parser-impl</module>
+        <module>yang-model-export</module>
         <module>yang-data-composite-node</module>
     </modules>
     <build>
index 445e2e6aaad6fb58ab5a125ddb3ac2ebe57d9189..f2744cc1b873dbc7aa56662e373cd4b83cfe4f8a 100644 (file)
@@ -7,8 +7,8 @@
  */
 package org.opendaylight.yangtools.yang.binding;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableList;
@@ -172,7 +172,7 @@ public class InstanceIdentifier<T extends DataObject> implements Path<InstanceId
 
     @Override
     public final String toString() {
-        return addToStringAttributes(Objects.toStringHelper(this)).toString();
+        return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
     }
 
     /**
@@ -666,6 +666,7 @@ public class InstanceIdentifier<T extends DataObject> implements Path<InstanceId
          *
          * @return
          */
+        @Override
         InstanceIdentifier<T> build();
 
         /*
index e1f0b710f766e67e5d8d39e99350d4ca3606275f..b1ea0e437bbdc4b8cbaa445591d6994ed1810fa0 100644 (file)
@@ -8,17 +8,13 @@
 
 package org.opendaylight.yangtools.yang.common;
 
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
 import java.util.Arrays;
 import java.util.List;
-
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-
 /**
  * A general base exception for an operation failure.
  *
@@ -74,7 +70,7 @@ public class OperationFailedException extends Exception {
 
     @Override
     public String toString() {
-        return Objects.toStringHelper( this ).add( "message", getMessage() )
+        return MoreObjects.toStringHelper( this ).add( "message", getMessage() )
                 .add( "errorList", errorList ).toString();
     }
 }
index 628af0c4ebfe964116ae6130ed4b0dcc57bff75e..cd6c0e9ef855f74ae7dac5ea26314312ad2a7d22 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.common;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import java.io.Serializable;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -165,6 +165,6 @@ public final class QNameModule implements Immutable, Serializable {
 
     @Override
     public String toString() {
-        return Objects.toStringHelper(this).omitNullValues().add("ns", getNamespace()).add("rev", getFormattedRevision()).toString();
+        return MoreObjects.toStringHelper(this).omitNullValues().add("ns", getNamespace()).add("rev", getFormattedRevision()).toString();
     }
 }
index 47a64eac793719d53ee41035d7b8dbbe03f0fc5e..c063366a476945a068e3795718712085d8c0aa04 100644 (file)
@@ -11,8 +11,11 @@ package org.opendaylight.yangtools.yang.common;
 import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
+
+import java.io.Serializable;
 import java.util.Collection;
 import java.util.Collections;
+
 import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
@@ -26,7 +29,8 @@ import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
  */
 public final class RpcResultBuilder<T> implements Builder<RpcResult<T>> {
 
-    private static class RpcResultImpl<T> implements RpcResult<T> {
+    private static class RpcResultImpl<T> implements RpcResult<T>, Serializable {
+        private static final long serialVersionUID = 1L;
 
         private final Collection<RpcError> errors;
         private final T result;
@@ -61,7 +65,8 @@ public final class RpcResultBuilder<T> implements Builder<RpcResult<T>> {
         }
     }
 
-    private static class RpcErrorImpl implements RpcError {
+    private static class RpcErrorImpl implements RpcError, Serializable {
+        private static final long serialVersionUID = 1L;
 
         private final String applicationTag;
         private final String tag;
diff --git a/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/YangConstants.java b/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/YangConstants.java
new file mode 100644 (file)
index 0000000..dbc25eb
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.common;
+
+import java.net.URI;
+
+/**
+ * Constant definitions present in RFC documents related to the YANG language.
+ */
+public final class YangConstants {
+    /**
+     * YANG namespace, as defined in RFC 6020.
+     */
+    public static final URI RFC6020_YANG_NAMESPACE = URI.create("urn:ietf:params:xml:ns:yang:1");
+
+    /**
+     * YIN namespace, as defined in RFC 6020.
+     */
+    public static final URI RFC6020_YIN_NAMESPACE = URI.create("urn:ietf:params:xml:ns:yang:yin:1");
+
+    /**
+     * Base QNameModule for all YANG statements.
+     */
+    public static final QNameModule RFC6020_YANG_MODULE = QNameModule.cachedReference(QNameModule.create(RFC6020_YANG_NAMESPACE, null));
+
+    /**
+     * Base QNameModule for all YIN statements.
+     */
+    public static final QNameModule RFC6020_YIN_MODULE = QNameModule.cachedReference(QNameModule.create(RFC6020_YIN_NAMESPACE, null));
+
+    private YangConstants() {
+        throw new UnsupportedOperationException("Utility class");
+    }
+
+}
index 6eee59a9183021da2440c7dbde55ddf5696611e0..2ff4fb5e5c7a259020a132fd768960d5bd84adba 100644 (file)
@@ -10,6 +10,10 @@ package org.opendaylight.yangtools.yang.common;
 
 import static org.junit.Assert.*;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -107,6 +111,37 @@ public class RpcResultBuilderTest {
                         "error message", null, null, null );
     }
 
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testSerialization() throws Exception {
+        RpcResult<String> result = RpcResultBuilder.<String>success().withResult( "foo" ).build();
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(bos);
+        out.writeObject(result);
+
+        ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
+        RpcResult<String> clone = (RpcResult<String>) in.readObject();
+
+        verifyRpcResult(clone, true, "foo");
+
+        Throwable cause = new Throwable( "mock cause" );
+        result = RpcResultBuilder.<String>failed()
+                .withError( ErrorType.RPC, "in-use", "error message", "my-app-tag", "my-info", cause )
+                .build();
+
+        bos = new ByteArrayOutputStream();
+        out = new ObjectOutputStream(bos);
+        out.writeObject(result);
+
+        in = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
+        clone = (RpcResult<String>) in.readObject();
+
+        verifyRpcResult(clone, false, null);
+        verifyRpcError( result, 0, ErrorSeverity.ERROR, ErrorType.RPC, "in-use",
+                "error message", "my-app-tag", "my-info", cause );
+    }
+
     void verifyRpcError( RpcResult<?> result, int errorIndex, ErrorSeverity expSeverity,
             ErrorType expErrorType, String expTag, String expMessage, String expAppTag,
             String expInfo, Throwable expCause ) {
index 94646531a8cf0ed607b00af1620abada67117b58..9b3f3d2ac4e12f942b43eb4943b048c677f08bc8 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
 import com.google.common.base.Preconditions;
-
 import org.opendaylight.yangtools.concepts.Codec;
 import org.opendaylight.yangtools.yang.data.api.codec.BooleanCodec;
 import org.opendaylight.yangtools.yang.data.api.codec.DecimalCodec;
@@ -39,16 +38,18 @@ abstract class AbstractJSONCodec<T> implements JSONCodec<T> {
      * @param codec underlying codec
      * @return A JSONCodec instance
      */
-    public static <T> JSONCodec<T> create(final Codec<String, T> codec) {
-        if (codec instanceof BooleanCodec || codec instanceof DecimalCodec ||
-                codec instanceof Int8Codec || codec instanceof Int16Codec ||
-                codec instanceof Int32Codec || codec instanceof Int64Codec ||
-                codec instanceof Uint8Codec || codec instanceof Uint16Codec ||
-                codec instanceof Uint32Codec || codec instanceof Uint64Codec) {
-            return new UnquotedJSONCodec<>(codec);
+    public static JSONCodec<?> create(final Codec<String, ?> codec) {
+        if (codec instanceof BooleanCodec) {
+            return new BooleanJSONCodec((BooleanCodec<String>) codec);
+        } else if (codec instanceof DecimalCodec || codec instanceof Int8Codec
+                || codec instanceof Int16Codec || codec instanceof Int32Codec
+                || codec instanceof Int64Codec || codec instanceof Uint8Codec
+                || codec instanceof Uint16Codec || codec instanceof Uint32Codec
+                || codec instanceof Uint64Codec) {
+            return new NumberJSONCodec(codec);
+        } else {
+            return new QuotedJSONCodec<>(codec);
         }
-
-        return new QuotedJSONCodec<>(codec);
     }
 
     @Override
diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/BooleanJSONCodec.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/BooleanJSONCodec.java
new file mode 100644 (file)
index 0000000..0840cd4
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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.codec.gson;
+
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import org.opendaylight.yangtools.concepts.Codec;
+
+/**
+ * A {@link JSONCodec} which does not need double quotes in output representation.
+ *
+ * @param <T> Deserialized value type
+ */
+final class BooleanJSONCodec extends AbstractJSONCodec<Boolean> {
+    BooleanJSONCodec(final Codec<String, Boolean> codec) {
+        super(codec);
+    }
+
+    @Override
+    public boolean needQuotes() {
+        return false;
+    }
+
+    /**
+     * Serialize specified value with specified JsonWriter.
+     *
+     * @param writer JsonWriter
+     * @param value
+     */
+    @Override
+    public void serializeToWriter(JsonWriter writer, Boolean value) throws IOException {
+        writer.value(value);
+    };
+}
\ No newline at end of file
index aa52259c588a72d6411f7f26f87f877c2e90809d..003684cbf69d1c0179bbfeabf79816c191963a96 100644 (file)
@@ -7,8 +7,20 @@
  */
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
 import org.opendaylight.yangtools.concepts.Codec;
 
 interface JSONCodec<T> extends Codec<String, T> {
+    // FIXME: Unused, remove once we are sure we do not need this anymore.
     boolean needQuotes();
+
+
+    /**
+     * Serialize specified value with specified JsonWriter.
+     *
+     * @param writer JsonWriter
+     * @param value
+     */
+    void serializeToWriter(JsonWriter writer, T value) throws IOException;
 }
index 8ee9517ec2db90f976aa64e5b26a883abe3a7c4e..c99d46404885c0b6c9b9e04dc24a64e0dbe0106f 100644 (file)
@@ -12,7 +12,8 @@ import com.google.common.base.Preconditions;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
-
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
 import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
@@ -45,6 +46,12 @@ public final class JSONCodecFactory {
         public boolean needQuotes() {
             return false;
         }
+
+        @Override
+        public void serializeToWriter(JsonWriter writer, Object value) throws IOException {
+            // NOOP since codec is unkwown.
+            LOG.warn("Call of the serializeToWriter method on JSONCodecFactory.NULL_CODEC object. No operation performed.");
+        }
     };
 
     private static TypeDefinition<?> resolveBaseTypeFrom(final TypeDefinition<?> type) {
@@ -78,7 +85,7 @@ public final class JSONCodecFactory {
                 return NULL_CODEC;
             }
 
-            return AbstractJSONCodec.create(codec);
+            return (JSONCodec<Object>) AbstractJSONCodec.create(codec);
         }
     });
 
index 5613433bbe5cc148d9e2e6f7ce8ae5f3af5d75e7..51fc686513b091a5901cf23fca0565e8306fa968 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
 import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
 
 final class JSONLeafrefCodec implements JSONCodec<Object>, LeafrefCodec<String> {
@@ -24,4 +26,15 @@ final class JSONLeafrefCodec implements JSONCodec<Object>, LeafrefCodec<String>
     public boolean needQuotes() {
         return true;
     }
+
+    /**
+     * Serialize specified value with specified JsonWriter.
+     *
+     * @param writer JsonWriter
+     * @param value
+     */
+    @Override
+    public void serializeToWriter(JsonWriter writer, Object value) throws IOException {
+        writer.value(serialize(value));
+    }
 }
\ No newline at end of file
index 087a99655967721682925c097474b3e70e6b2312..079b8e324aeba0638e2832596059b50c3f279f68 100644 (file)
@@ -7,32 +7,28 @@
  */
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
-import com.google.common.base.CharMatcher;
 import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
 import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.net.URI;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.codec.SchemaTracker;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 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 java.io.IOException;
-import java.io.Writer;
-import java.net.URI;
-
 /**
  * This implementation will create JSON output as output stream.
  *
  * Values of leaf and leaf-list are NOT translated according to codecs.
  *
- * FIXME: rewrite this in terms of {@link JsonWriter}.
  */
 public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWriter {
     /**
@@ -41,27 +37,13 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
      */
     private static final boolean DEFAULT_EMIT_EMPTY_CONTAINERS = true;
 
-    /**
-     * Matcher used to check if a string needs to be escaped.
-     */
-    private static final CharMatcher JSON_ILLEGAL_STRING_CHARACTERS = CharMatcher.anyOf("\\\"\n\r");
-
     private final SchemaTracker tracker;
     private final JSONCodecFactory codecs;
-    private final Writer writer;
-    private final String indent;
+    private final JsonWriter writer;
     private JSONStreamWriterContext context;
 
-    private JSONNormalizedNodeStreamWriter(final JSONCodecFactory codecFactory, final SchemaPath path,
-            final Writer writer, final URI initialNs, final int indentSize) {
-        this.writer = Preconditions.checkNotNull(writer);
-
-        Preconditions.checkArgument(indentSize >= 0, "Indent size must be non-negative");
-        if (indentSize != 0) {
-            indent = Strings.repeat(" ", indentSize);
-        } else {
-            indent = null;
-        }
+    private JSONNormalizedNodeStreamWriter(final JSONCodecFactory codecFactory, final SchemaPath path, final URI initialNs, JsonWriter JsonWriter) {
+        this.writer = JsonWriter;
         this.codecs = Preconditions.checkNotNull(codecFactory);
         this.tracker = SchemaTracker.create(codecFactory.getSchemaContext(), path);
         this.context = new JSONStreamWriterRootContext(initialNs);
@@ -75,7 +57,7 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
      * @return A stream writer instance
      */
     public static NormalizedNodeStreamWriter create(final SchemaContext schemaContext, final Writer writer) {
-        return new JSONNormalizedNodeStreamWriter(JSONCodecFactory.create(schemaContext), SchemaPath.ROOT, writer, null, 0);
+        return create(schemaContext, SchemaPath.ROOT, null, writer);
     }
 
     /**
@@ -87,7 +69,7 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
      * @return A stream writer instance
      */
     public static NormalizedNodeStreamWriter create(final SchemaContext schemaContext, final SchemaPath path, final Writer writer) {
-        return new JSONNormalizedNodeStreamWriter(JSONCodecFactory.create(schemaContext), path, writer, null, 0);
+        return create(schemaContext, path, null, writer);
     }
 
     /**
@@ -101,7 +83,7 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
      */
     public static NormalizedNodeStreamWriter create(final SchemaContext schemaContext, final SchemaPath path,
             final URI initialNs, final Writer writer) {
-        return new JSONNormalizedNodeStreamWriter(JSONCodecFactory.create(schemaContext), path, writer, initialNs, 0);
+        return create(JSONCodecFactory.create(schemaContext), path, initialNs, JsonWriterFactory.createJsonWriter(writer));
     }
 
     /**
@@ -113,7 +95,7 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
      * @return A stream writer instance
      */
     public static NormalizedNodeStreamWriter create(final SchemaContext schemaContext, final Writer writer, final int indentSize) {
-        return new JSONNormalizedNodeStreamWriter(JSONCodecFactory.create(schemaContext), SchemaPath.ROOT, writer, null, indentSize);
+        return create(JSONCodecFactory.create(schemaContext), SchemaPath.ROOT, null,JsonWriterFactory.createJsonWriter(writer, indentSize));
     }
 
     /**
@@ -126,7 +108,35 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
      * @return A stream writer instance
      */
     public static NormalizedNodeStreamWriter create(final JSONCodecFactory codecFactory, final Writer writer, final int indentSize) {
-        return new JSONNormalizedNodeStreamWriter(codecFactory, SchemaPath.ROOT, writer, null, indentSize);
+        return create(codecFactory, SchemaPath.ROOT, null, JsonWriterFactory.createJsonWriter(writer,indentSize));
+    }
+
+    /**
+     * Create a new stream writer, which writes to the specified output stream.
+     *
+     * @param schemaContext Schema context
+     * @param path Schema Path
+     * @param initialNs Initial namespace
+     * @param jsonWriter JsonWriter
+     * @return A stream writer instance
+     */
+    public static NormalizedNodeStreamWriter create(SchemaContext schemaContext, SchemaPath path, URI initialNs,
+            JsonWriter jsonWriter) {
+        return create(JSONCodecFactory.create(schemaContext), path, initialNs, jsonWriter);
+    }
+
+    /**
+     * Create a new stream writer, which writes to the specified output stream. The codec factory
+     * can be reused between multiple writers.
+     *
+     * @param codecFactory JSON codec factory
+     * @param path Schema Path
+     * @param initialNs Initial namespace
+     * @param jsonWriter JsonWriter
+     * @return A stream writer instance
+     */
+    public static NormalizedNodeStreamWriter create(JSONCodecFactory codecFactory, SchemaPath path, URI initialNs, JsonWriter jsonWriter) {
+        return new JSONNormalizedNodeStreamWriter(codecFactory, path, initialNs, jsonWriter);
     }
 
     @Override
@@ -134,9 +144,10 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
         final LeafSchemaNode schema = tracker.leafNode(name);
         final JSONCodec<Object> codec = codecs.codecFor(schema.getType());
 
-        context.emittingChild(codecs.getSchemaContext(), writer, indent);
+        context.emittingChild(codecs.getSchemaContext(), writer);
         context.writeChildJsonIdentifier(codecs.getSchemaContext(), writer, name.getNodeType());
-        writeValue(codec.serialize(value), codec.needQuotes());
+
+        writeValue(value, codec);
     }
 
     @Override
@@ -150,8 +161,9 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
         final LeafListSchemaNode schema = tracker.leafSetEntryNode();
         final JSONCodec<Object> codec = codecs.codecFor(schema.getType());
 
-        context.emittingChild(codecs.getSchemaContext(), writer, indent);
-        writeValue(codec.serialize(value), codec.needQuotes());
+        context.emittingChild(codecs.getSchemaContext(), writer);
+
+        writeValue(value, codec);
     }
 
     /*
@@ -161,8 +173,11 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
     @SuppressWarnings("unused")
     @Override
     public void startContainerNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
-        final ContainerSchemaNode schema = tracker.startContainerNode(name);
-        context = new JSONStreamWriterNamedObjectContext(context, name, DEFAULT_EMIT_EMPTY_CONTAINERS || schema.isPresenceContainer());
+        final SchemaNode schema = tracker.startContainerNode(name);
+
+        // FIXME this code ignores presence for containers
+        // but datastore does as well and it needs be fixed first (2399)
+        context = new JSONStreamWriterNamedObjectContext(context, name, DEFAULT_EMIT_EMPTY_CONTAINERS);
     }
 
     @Override
@@ -214,42 +229,23 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
         final AnyXmlSchemaNode schema = tracker.anyxmlNode(name);
         // FIXME: should have a codec based on this :)
 
-        context.emittingChild(codecs.getSchemaContext(), writer, indent);
+        context.emittingChild(codecs.getSchemaContext(), writer);
         context.writeChildJsonIdentifier(codecs.getSchemaContext(), writer, name.getNodeType());
-        writeValue(String.valueOf(value), true);
+        writer.value(String.valueOf(value));
     }
 
     @Override
     public void endNode() throws IOException {
         tracker.endNode();
-        context = context.endNode(codecs.getSchemaContext(), writer, indent);
+        context = context.endNode(codecs.getSchemaContext(), writer);
+        if(context instanceof JSONStreamWriterRootContext) {
+            context.emitEnd(writer);
+        }
     }
 
-    private void writeValue(final String str, final boolean needQuotes) throws IOException {
-        if (needQuotes) {
-            writer.append('"');
-
-            final int needEscape = JSON_ILLEGAL_STRING_CHARACTERS.countIn(str);
-            if (needEscape != 0) {
-                final char[] escaped = new char[str.length() + needEscape];
-                int offset = 0;
-
-                for (int i = 0; i < str.length(); i++) {
-                    final char c = str.charAt(i);
-                    if (JSON_ILLEGAL_STRING_CHARACTERS.matches(c)) {
-                        escaped[offset++] = '\\';
-                    }
-                    escaped[offset++] = c;
-                }
-                writer.write(escaped);
-            } else {
-                writer.append(str);
-            }
-
-            writer.append('"');
-        } else {
-            writer.append(str);
-        }
+    private void writeValue(Object value, JSONCodec<Object> codec)
+            throws IOException {
+        codec.serializeToWriter(writer,value);
     }
 
     @Override
@@ -263,4 +259,6 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
         writer.close();
     }
 
+
+
 }
index a3ad80dfb3f28473b523f3b12c1a1cc335063715..a29972aa939e84a88f435225a559ed59ac1eb9f6 100644 (file)
@@ -8,8 +8,9 @@
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
 import com.google.common.base.Preconditions;
+import com.google.gson.stream.JsonWriter;
 import java.io.IOException;
-import java.io.Writer;
+import java.io.StringWriter;
 import java.net.URI;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -26,7 +27,6 @@ abstract class JSONStreamWriterContext {
     private final boolean mandatory;
     private final int depth;
     private boolean emittedMyself = false;
-    private boolean haveChild = false;
 
     /**
      * Construct a new context.
@@ -55,21 +55,21 @@ abstract class JSONStreamWriterContext {
      * @param qname Namespace/name tuple
      * @throws IOException when the writer reports it
      */
-    final void writeChildJsonIdentifier(final SchemaContext schema, final Writer writer, final QName qname) throws IOException {
-        writer.append('"');
+    final void writeChildJsonIdentifier(final SchemaContext schema, final JsonWriter writer, final QName qname) throws IOException {
 
+        StringWriter strWriter = new StringWriter();
         // Prepend module name if namespaces do not match
         final URI ns = qname.getNamespace();
         if (!ns.equals(getNamespace())) {
             final Module module = schema.findModuleByNamespaceAndRevision(ns, null);
             Preconditions.checkArgument(module != null, "Could not find module for namespace {}", ns);
 
-            writer.append(module.getName());
-            writer.append(':');
+            strWriter.append(module.getName());
+            strWriter.append(':');
         }
+        strWriter.append(qname.getLocalName());
 
-        writer.append(qname.getLocalName());
-        writer.append("\":");
+        writer.name(strWriter.toString());
     }
 
     /**
@@ -81,7 +81,7 @@ abstract class JSONStreamWriterContext {
      * @param qname Namespace/name tuple
      * @throws IOException when the writer reports it
      */
-    protected final void writeMyJsonIdentifier(final SchemaContext schema, final Writer writer, final QName qname) throws IOException {
+    protected final void writeMyJsonIdentifier(final SchemaContext schema, final JsonWriter writer, final QName qname) throws IOException {
         parent.writeChildJsonIdentifier(schema, writer, qname);
     }
 
@@ -99,7 +99,7 @@ abstract class JSONStreamWriterContext {
      * @param writer Output writer
      * @throws IOException
      */
-    protected abstract void emitStart(final SchemaContext schema, final Writer writer) throws IOException;
+    protected abstract void emitStart(final SchemaContext schema, final JsonWriter writer) throws IOException;
 
     /**
      * Emit the end of an element.
@@ -108,12 +108,12 @@ abstract class JSONStreamWriterContext {
      * @param writer Output writer
      * @throws IOException
      */
-    protected abstract void emitEnd(final Writer writer) throws IOException;
+    protected abstract void emitEnd(final JsonWriter writer) throws IOException;
 
-    private final void emitMyself(final SchemaContext schema, final Writer writer, final String indent) throws IOException {
+    private final void emitMyself(final SchemaContext schema, final JsonWriter writer) throws IOException {
         if (!emittedMyself) {
             if (parent != null) {
-                parent.emittingChild(schema, writer, indent);
+                parent.emittingChild(schema, writer);
             }
 
             emitStart(schema, writer);
@@ -128,23 +128,10 @@ abstract class JSONStreamWriterContext {
      *
      * @param schema Schema context
      * @param writer Output writer
-     * @param indent Indentation string
      * @throws IOException when writer reports it
      */
-    final void emittingChild(final SchemaContext schema, final Writer writer, final String indent) throws IOException {
-        emitMyself(schema, writer, indent);
-        if (haveChild) {
-            writer.append(',');
-        }
-
-        if (indent != null) {
-            writer.append('\n');
-
-            for (int i = 0; i < depth; i++) {
-                writer.append(indent);
-            }
-        }
-        haveChild = true;
+    final void emittingChild(final SchemaContext schema, final JsonWriter writer) throws IOException {
+        emitMyself(schema, writer);
     }
 
     /**
@@ -153,14 +140,13 @@ abstract class JSONStreamWriterContext {
      *
      * @param schema Schema context
      * @param writer Output writer
-     * @param indent Indentation string
      * @return Parent node context
      * @throws IOException when writer reports it
      * @throws IllegalArgumentException if this node cannot be ended (e.g. root)
      */
-    final JSONStreamWriterContext endNode(final SchemaContext schema, final Writer writer, final String indent) throws IOException {
+    final JSONStreamWriterContext endNode(final SchemaContext schema, final JsonWriter writer) throws IOException {
         if (!emittedMyself && mandatory) {
-            emitMyself(schema, writer, indent);
+            emitMyself(schema, writer);
         }
 
         if (emittedMyself) {
index 7f22c194664637e2916e521849d8d59d9380cdcd..e43aead9f449496235284f17dbbba6aa474b644b 100644 (file)
@@ -8,8 +8,9 @@
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
 import com.google.common.base.Preconditions;
+import com.google.gson.stream.JsonWriter;
+
 
-import java.io.Writer;
 
 /**
  * A virtual recursion level in {@link JSONNormalizedNodeStreamWriter}, used for nodes
@@ -21,7 +22,7 @@ final class JSONStreamWriterInvisibleContext extends JSONStreamWriterURIContext
     }
 
     @Override
-    protected void emitEnd(final Writer writer) {
+    protected void emitEnd(final JsonWriter writer) {
         // No-op
     }
 }
\ No newline at end of file
index 9c0be476b1bb332e4d91a2a36f85a6e47cced61a..e1505c7b10898d097b75783314b6f8f136c8ec92 100644 (file)
@@ -8,8 +8,8 @@
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
 import com.google.common.base.Preconditions;
+import com.google.gson.stream.JsonWriter;
 import java.io.IOException;
-import java.io.Writer;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
@@ -23,13 +23,13 @@ final class JSONStreamWriterListContext extends JSONStreamWriterQNameContext {
     }
 
     @Override
-    protected void emitStart(final SchemaContext schema, final Writer writer) throws IOException {
+    protected void emitStart(final SchemaContext schema, final JsonWriter writer) throws IOException {
         writeMyJsonIdentifier(schema, writer, getQName());
-        writer.append('[');
+        writer.beginArray();
     }
 
     @Override
-    protected void emitEnd(final Writer writer) throws IOException {
-        writer.append(']');
+    protected void emitEnd(final JsonWriter writer) throws IOException {
+        writer.endArray();
     }
 }
index 91c6ca70ae2c5a613984610bbdba44ae5aeca598..fe08410cafa5620cc7b3e2b1a1d8dfa72f0455df 100644 (file)
@@ -7,11 +7,12 @@
  */
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
+import com.google.gson.stream.JsonWriter;
 import java.io.IOException;
-import java.io.Writer;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
+
 /**
  * A recursion level of {@link JSONNormalizedNodeStreamWriter}, which represents
  * a JSON object which has to be prefixed with its identifier -- such as a
@@ -23,7 +24,7 @@ final class JSONStreamWriterNamedObjectContext extends JSONStreamWriterObjectCon
     }
 
     @Override
-    protected void emitStart(final SchemaContext schema, final Writer writer) throws IOException {
+    protected void emitStart(final SchemaContext schema, final JsonWriter writer) throws IOException {
         writeMyJsonIdentifier(schema, writer, getQName());
         super.emitStart(schema, writer);
     }
index d12f0449dd89e58ee4e6f3fd66be552dfb7ab919..fb4e48ed6091073550c02154113496c318e8016c 100644 (file)
@@ -8,10 +8,8 @@
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
 import com.google.common.base.Preconditions;
-
+import com.google.gson.stream.JsonWriter;
 import java.io.IOException;
-import java.io.Writer;
-
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
@@ -26,12 +24,12 @@ class JSONStreamWriterObjectContext extends JSONStreamWriterQNameContext {
     }
 
     @Override
-    protected void emitStart(final SchemaContext schema, final Writer writer) throws IOException {
-        writer.append('{');
+    protected void emitStart(final SchemaContext schema, final JsonWriter writer) throws IOException {
+        writer.beginObject();
     }
 
     @Override
-    protected void emitEnd(final Writer writer) throws IOException {
-        writer.append('}');
+    protected void emitEnd(final JsonWriter writer) throws IOException {
+        writer.endObject();
     }
 }
\ No newline at end of file
index 36c3ff38c349d7ad05f4474aa024c02d8aff9db6..bb0d49dc8674ea728c8a4951f5598732b76d7e33 100644 (file)
@@ -7,8 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
-import java.io.Writer;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
 import java.net.URI;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
 
 /**
  * The root node of a particular {@link JSONNormalizedNodeStreamWriter} instance.
@@ -20,7 +23,12 @@ final class JSONStreamWriterRootContext extends JSONStreamWriterURIContext {
     }
 
     @Override
-    protected void emitEnd(final Writer writer) {
-        throw new IllegalArgumentException("Top-level node reached");
+    protected void emitStart(final SchemaContext schema, final JsonWriter writer) throws IOException {
+        writer.beginObject();
+    }
+
+    @Override
+    protected void emitEnd(final JsonWriter writer) throws IOException {
+        writer.endObject();
     }
 }
index 06c32bf26d3ab37bef9738bc2749f30252103b16..f0d286a42781509bf61cce87fcfa0e1b4c0d4e82 100644 (file)
@@ -7,12 +7,12 @@
  */
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
+import com.google.gson.stream.JsonWriter;
 import java.io.IOException;
-import java.io.Writer;
 import java.net.URI;
-
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
+
 /**
  * Abstract class tracking a virtual level of {@link JSONNormalizedNodeStreamWriter}
  * recursion. It only tracks the namespace associated with this node.
@@ -31,7 +31,7 @@ abstract class JSONStreamWriterURIContext extends JSONStreamWriterContext {
     }
 
     @Override
-    protected final void emitStart(final SchemaContext schema, final Writer writer) throws IOException {
+    protected void emitStart(final SchemaContext schema, final JsonWriter writer) throws IOException {
         // No-op
     }
 }
\ No newline at end of file
index fcbe473cca8dc6b414814a2e05ed3f92d9e3673e..7e099b4e2d8aa96f35f732e728ee2e9412681ce7 100644 (file)
@@ -8,9 +8,9 @@
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
 import com.google.common.base.Preconditions;
-
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
 import java.net.URI;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.util.AbstractModuleStringIdentityrefCodec;
 import org.opendaylight.yangtools.yang.model.api.Module;
@@ -38,4 +38,15 @@ final class JSONStringIdentityrefCodec extends AbstractModuleStringIdentityrefCo
     public boolean needQuotes() {
         return true;
     }
+
+    /**
+     * Serialize QName with specified JsonWriter.
+     *
+     * @param writer JsonWriter
+     * @param value QName
+     */
+    @Override
+    public void serializeToWriter(JsonWriter writer, QName value) throws IOException {
+        writer.value(serialize(value));
+    }
 }
index a1580dd5bb2c3f5681569c1c3541e68d38f51cbf..77fa797efa4f3036d89c93f3063c25433003865a 100644 (file)
@@ -8,9 +8,9 @@
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
 import com.google.common.base.Preconditions;
-
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
 import java.net.URI;
-
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.util.AbstractModuleStringInstanceIdentifierCodec;
 import org.opendaylight.yangtools.yang.model.api.Module;
@@ -38,4 +38,15 @@ final class JSONStringInstanceIdentifierCodec extends AbstractModuleStringInstan
     public boolean needQuotes() {
         return true;
     }
+
+    /**
+     * Serialize YangInstanceIdentifier with specified JsonWriter.
+     *
+     * @param writer JsonWriter
+     * @param value YangInstanceIdentifier
+     */
+    @Override
+    public void serializeToWriter(JsonWriter writer, YangInstanceIdentifier value) throws IOException {
+        writer.value(serialize(value));
+    }
 }
diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonWriterFactory.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonWriterFactory.java
new file mode 100644 (file)
index 0000000..3b3bf8d
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.codec.gson;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Strings;
+import com.google.gson.stream.JsonWriter;
+import java.io.Writer;
+
+/**
+ * Factory Method class for JsonWriter creation
+ */
+@Beta
+public final class JsonWriterFactory {
+
+    private JsonWriterFactory() {
+    }
+    /**
+     * Create a new JsonWriter, which writes to the specified output writer.
+     *
+     * @param writer Output writer
+     * @return A JsonWriter instance
+     */
+    public static JsonWriter createJsonWriter(Writer writer) {
+        return new JsonWriter(writer);
+    }
+
+    /**
+     * Create a new JsonWriter, which writes to the specified output writer.
+     *
+     * @param writer Output writer
+     * @param indentSize size of the indent
+     * @return A JsonWriter instance
+     */
+    public static JsonWriter createJsonWriter(Writer writer, int indentSize) {
+        JsonWriter jsonWriter = new JsonWriter(writer);
+        final String indent = Strings.repeat(" ", indentSize);
+        jsonWriter.setIndent(indent);
+        return jsonWriter;
+    }
+
+}
similarity index 58%
rename from yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/UnquotedJSONCodec.java
rename to yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/NumberJSONCodec.java
index f29db5d1eeeea56e38ac9a3db5b26b98c8062a0f..d262a440ce86681bc2d9508f601b8ee74b502abc 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
 import org.opendaylight.yangtools.concepts.Codec;
 
 /**
@@ -14,8 +16,8 @@ import org.opendaylight.yangtools.concepts.Codec;
  *
  * @param <T> Deserialized value type
  */
-final class UnquotedJSONCodec<T> extends AbstractJSONCodec<T> {
-    UnquotedJSONCodec(final Codec<String, T> codec) {
+final class NumberJSONCodec<T extends Number> extends AbstractJSONCodec<T > {
+    NumberJSONCodec(final Codec<String, T> codec) {
         super(codec);
     }
 
@@ -23,4 +25,15 @@ final class UnquotedJSONCodec<T> extends AbstractJSONCodec<T> {
     public boolean needQuotes() {
         return false;
     }
+
+    /**
+     * Serialize specified value with specified JsonWriter.
+     *
+     * @param writer JsonWriter
+     * @param value
+     */
+    @Override
+    public void serializeToWriter(JsonWriter writer, T value) throws IOException {
+        writer.value(value);
+    }
 }
\ No newline at end of file
index e8606f8d9587f4304d752cfe2215e19d5e6ced0b..45782896cf2b3bbe3d9040da4904713519e69365 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
 import org.opendaylight.yangtools.concepts.Codec;
 
 /**
@@ -23,4 +25,15 @@ final class QuotedJSONCodec<T> extends AbstractJSONCodec<T> {
     public boolean needQuotes() {
         return true;
     }
+
+    /**
+     * Serialize specified value with specified JsonWriter.
+     *
+     * @param writer JsonWriter
+     * @param value
+     */
+    @Override
+    public void serializeToWriter(JsonWriter writer, T value) throws IOException {
+        writer.value(serialize(value));
+    }
 }
\ No newline at end of file
index 39a1f1bc7bbe30c9cd131cd581d7269650ed4b0a..484aa70029c1182660de8863616c12cbc205b295 100644 (file)
@@ -382,11 +382,11 @@ public class NormalizedNodeToJsonStreamTest {
 
     private String normalizedNodeToJsonStreamTransformation(final Writer writer,
             final NormalizedNode<?, ?> inputStructure) throws IOException {
-        writer.write("{\n");
+
         final NormalizedNodeStreamWriter jsonStream = JSONNormalizedNodeStreamWriter.create(schemaContext, writer, 2);
         final NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(jsonStream);
         nodeWriter.write(inputStructure);
-        writer.write("\n}");
+
         nodeWriter.close();
         return writer.toString();
     }
index cd7e6d706c08dc5562a62d02c110d99dfd19d892..134557b7c9e544ac1e6706138fc4c88581d95f79 100644 (file)
@@ -8,7 +8,10 @@
 package org.opendaylight.yangtools.yang.data.impl.codec;
 
 import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
 import java.io.IOException;
 import java.util.ArrayDeque;
 import java.util.Deque;
@@ -28,9 +31,11 @@ import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
@@ -48,20 +53,37 @@ public final class SchemaTracker {
     private final DataNodeContainer root;
 
     private SchemaTracker(final SchemaContext context, final SchemaPath path) {
-        DataSchemaNode current = Preconditions.checkNotNull(context);
-        for (QName qname : path.getPathFromRoot()) {
-            final DataSchemaNode child;
+        SchemaNode current = Preconditions.checkNotNull(context);
+        for (final QName qname : path.getPathFromRoot()) {
+            SchemaNode child;
             if(current instanceof DataNodeContainer) {
                 child = ((DataNodeContainer) current).getDataChildByName(qname);
+
+                if (child == null && current instanceof SchemaContext) {
+                    child = tryFindGroupings((SchemaContext) current, qname).orNull();
+                }
+
+                if(child == null && current instanceof SchemaContext) {
+                    child = tryFindNotification((SchemaContext) current, qname)
+                            .orNull();
+                }
             } else if (current instanceof ChoiceNode) {
                 child = ((ChoiceNode) current).getCaseNodeByName(qname);
             } else {
-                throw new IllegalArgumentException(String.format("Schema node %s does not allow children.",current));
+                throw new IllegalArgumentException(String.format("Schema node %s does not allow children.", current));
             }
             current = child;
         }
         Preconditions.checkArgument(current instanceof DataNodeContainer,"Schema path must point to container or list. Supplied path %s pointed to: %s",path,current);
-        this.root = (DataNodeContainer) current;
+        root = (DataNodeContainer) current;
+    }
+
+    private Optional<SchemaNode> tryFindGroupings(final SchemaContext ctx, final QName qname) {
+        return Optional.<SchemaNode> fromNullable(Iterables.find(ctx.getGroupings(), new SchemaNodePredicate(qname), null));
+    }
+
+    private Optional<SchemaNode> tryFindNotification(final SchemaContext ctx, final QName qname) {
+        return Optional.<SchemaNode>fromNullable(Iterables.find(ctx.getNotifications(), new SchemaNodePredicate(qname), null));
     }
 
     /**
@@ -100,9 +122,16 @@ public final class SchemaTracker {
         if(parent instanceof DataNodeContainer) {
             schema = ((DataNodeContainer)parent).getDataChildByName(qname);
 
+            if(schema == null && parent instanceof GroupingDefinition) {
+                schema = ((GroupingDefinition) parent);
+            }
+
+            if(schema == null && parent instanceof NotificationDefinition) {
+                schema = ((NotificationDefinition) parent);
+            }
         } else if(parent instanceof ChoiceNode) {
-            for(ChoiceCaseNode caze : ((ChoiceNode) parent).getCases()) {
-                DataSchemaNode potential = caze.getDataChildByName(qname);
+            for(final ChoiceCaseNode caze : ((ChoiceNode) parent).getCases()) {
+                final DataSchemaNode potential = caze.getDataChildByName(qname);
                 if(potential != null) {
                     schema = potential;
                     break;
@@ -158,13 +187,16 @@ public final class SchemaTracker {
         return (ChoiceNode)schema;
     }
 
-    public ContainerSchemaNode startContainerNode(final NodeIdentifier name) {
+    public SchemaNode startContainerNode(final NodeIdentifier name) {
         LOG.debug("Enter container {}", name);
         final SchemaNode schema = getSchema(name);
 
-        Preconditions.checkArgument(schema instanceof ContainerSchemaNode, "Node %s is not a container", schema.getPath());
+        boolean isAllowed = schema instanceof ContainerSchemaNode;
+        isAllowed |= schema instanceof NotificationDefinition;
+
+        Preconditions.checkArgument(isAllowed, "Node %s is not a container nor a notification", schema.getPath());
         schemaStack.push(schema);
-        return (ContainerSchemaNode)schema;
+        return schema;
     }
 
     public AugmentationSchema startAugmentationNode(final AugmentationIdentifier identifier) {
@@ -174,11 +206,11 @@ public final class SchemaTracker {
         Preconditions.checkArgument(parent instanceof AugmentationTarget, "Augmentation not allowed under %s", parent);
         Preconditions.checkArgument(parent instanceof DataNodeContainer, "Augmentation allowed only in DataNodeContainer",parent);
         final AugmentationSchema schema = SchemaUtils.findSchemaForAugment((AugmentationTarget) parent, identifier.getPossibleChildNames());
-        HashSet<DataSchemaNode> realChildSchemas = new HashSet<>();
-        for(DataSchemaNode child : schema.getChildNodes()) {
+        final HashSet<DataSchemaNode> realChildSchemas = new HashSet<>();
+        for(final DataSchemaNode child : schema.getChildNodes()) {
             realChildSchemas.add(((DataNodeContainer) parent).getDataChildByName(child.getQName()));
         }
-        AugmentationSchema resolvedSchema = new AugmentationSchemaProxy(schema, realChildSchemas);
+        final AugmentationSchema resolvedSchema = new AugmentationSchemaProxy(schema, realChildSchemas);
         schemaStack.push(resolvedSchema);
         return resolvedSchema;
     }
@@ -193,4 +225,17 @@ public final class SchemaTracker {
     public Object endNode() {
         return schemaStack.pop();
     }
+
+    private static final class SchemaNodePredicate implements Predicate<SchemaNode> {
+        private final QName qname;
+
+        public SchemaNodePredicate(final QName qname) {
+            this.qname = qname;
+        }
+
+        @Override
+        public boolean apply(final SchemaNode input) {
+            return input.getQName().equals(qname);
+        }
+    }
 }
index 7f2c3019d35af9356115f33ff3ecc3da77e7a20f..ddc8076d612cd2b4af752920655b9fed58729a4c 100644 (file)
@@ -72,10 +72,12 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
 
     private void writeStartElement( QName qname) throws XMLStreamException {
         String ns = qname.getNamespace().toString();
-        String parentNs = writer.getNamespaceContext().getNamespaceURI(DEFAULT_NS_PREFIX);
         writer.writeStartElement(DEFAULT_NS_PREFIX, qname.getLocalName(), ns);
-        if (!ns.equals(parentNs)) {
-            writer.writeDefaultNamespace(ns);
+        if(writer.getNamespaceContext() != null) {
+            String parentNs = writer.getNamespaceContext().getNamespaceURI(DEFAULT_NS_PREFIX);
+            if (!ns.equals(parentNs)) {
+                writer.writeDefaultNamespace(ns);
+            }
         }
     }
 
index 668869727934ca4cf79d81bef9fb5ede599a2a15..0301f699abe7a9ecfdc18727bb3d575601004a8e 100644 (file)
@@ -8,9 +8,7 @@
 package org.opendaylight.yangtools.yang.data.impl.codec.xml;
 
 import static com.google.common.base.Preconditions.checkState;
-
 import com.google.common.base.Function;
-import com.google.common.base.Objects;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
@@ -22,6 +20,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Objects;
 import java.util.Set;
 import javax.activation.UnsupportedDataTypeException;
 import javax.annotation.Nonnull;
@@ -320,7 +319,7 @@ public final class XmlDocumentUtils {
     }
 
     private static void checkQName(final Element xmlElement, final QName qName) {
-        checkState(Objects.equal(xmlElement.getNamespaceURI(), qName.getNamespace().toString()),  "Not equal: %s to: %s for: %s and: %s", qName.getNamespace(), xmlElement.getNamespaceURI(), qName, xmlElement);
+        checkState(Objects.equals(xmlElement.getNamespaceURI(), qName.getNamespace().toString()),  "Not equal: %s to: %s for: %s and: %s", qName.getNamespace(), xmlElement.getNamespaceURI(), qName, xmlElement);
         checkState(qName.getLocalName().equals(xmlElement.getLocalName()), "Not equal: %s to: %s for: %s and: %s", qName.getLocalName(), xmlElement.getLocalName(), qName, xmlElement);
     }
 
index 1aa5f9a058b19c3a3ff9783e4d41a1ed0799b217..1742c03357aee94c4e503ee98f6c4f427822990e 100644 (file)
@@ -14,7 +14,7 @@ import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects.ToStringHelper;
 
 public abstract class AbstractImmutableDataContainerAttrNode<K extends YangInstanceIdentifier.PathArgument>
         extends AbstractImmutableDataContainerNode<K>
index ac9b03065559b861d481626256b6b02e4fcfa5b3..fbc3aea16fa7d017a2adfa46c6ebc95e9728bfe7 100644 (file)
@@ -7,8 +7,8 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.nodes;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Preconditions;
 
 import org.opendaylight.yangtools.concepts.Immutable;
@@ -35,7 +35,7 @@ public abstract class AbstractImmutableNormalizedNode<K extends YangInstanceIden
 
     @Override
     public final String toString() {
-        return addToStringAttributes(Objects.toStringHelper(this)).toString();
+        return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
     }
 
     protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
index ad951f3333e938fafc6adbdfffd9173786924794..ec615025ebd5def89fdadb5d04cdac283122cb48 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.nodes;
 
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.collect.ImmutableMap;
 import java.util.Map;
 import org.opendaylight.yangtools.yang.common.QName;
index 9790fc2d87f994ca1516bd98927e6f86614ca751..12dfc5f557b751a8e224befb40cad775808f6b0d 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
@@ -60,6 +60,6 @@ final class DataTreeState {
     @Override
     public String toString() {
         final TreeNode r = root;
-        return Objects.toStringHelper(this).add("data", NormalizedNodes.toStringTree(r.getData())).toString();
+        return MoreObjects.toStringHelper(this).add("data", NormalizedNodes.toStringTree(r.getData())).toString();
     }
 }
\ No newline at end of file
index 38e884c0969de9b356d40ba861d5314221b526a7..0ed17c685a8aef53900a0b6a9fb71448f967a102 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import java.util.Collections;
@@ -127,6 +127,6 @@ final class InMemoryDataTree implements DataTree {
 
     @Override
     public String toString() {
-        return Objects.toStringHelper(this).add("object", super.toString()).add("state", state).toString();
+        return MoreObjects.toStringHelper(this).add("object", super.toString()).add("state", state).toString();
     }
 }
index 80dbb94d708cca75f9757e4624fd377a3a19bdc4..89375edf4d801986d160563ba6f9314691c8b4c5 100644 (file)
     <!-- yang-common dependency added here only for purpose of 'artifact version 
         check' test: version of yang-common artifact has to be different than one defined 
         in yang-maven-plugin to make test pass -->
-    <repositories>
-        <repository>
-            <id>opendaylight-mirror</id>
-            <name>opendaylight-mirror</name>
-            <url>http://nexus.opendaylight.org/content/groups/public/</url>
-            <snapshots>
-                <enabled>false</enabled>
-            </snapshots>
-            <releases>
-                <enabled>true</enabled>
-                <updatePolicy>never</updatePolicy>
-            </releases>
-        </repository>
-    </repositories>
     <dependencies>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
index d5f22d93d44f6a40054f60fc0f2d2e2cdae73718..d26ec448ab5178095e851e35ac1f5dd1adf10a46 100644 (file)
             <groupId>org.sonatype.plexus</groupId>
             <artifactId>plexus-build-api</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.codehaus.plexus</groupId>
-            <artifactId>plexus-slf4j-logging</artifactId>
-        </dependency>
     </dependencies>
 
     <build>
diff --git a/yang/yang-maven-plugin-spi/src/main/java/org/opendaylight/yangtools/yang2sources/spi/BasicCodeGenerator.java b/yang/yang-maven-plugin-spi/src/main/java/org/opendaylight/yangtools/yang2sources/spi/BasicCodeGenerator.java
new file mode 100644 (file)
index 0000000..908385e
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang2sources.spi;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * Maven 3.1.x and newer uses SLF4J internally, which means we do not need to pass
+ * a logger instance around.
+ */
+public interface BasicCodeGenerator {
+    /**
+     * Generate sources from provided {@link SchemaContext}
+     *
+     * @param context
+     *            parsed from YANG files
+     * @param outputBaseDir
+     *            expected output directory for generated sources configured by
+     *            user
+     * @param currentModules
+     *            YANG modules parsed from yangFilesRootDir
+     * @return collection of files that were generated from schema context
+     * @throws IOException
+     */
+    Collection<File> generateSources(SchemaContext context, File outputBaseDir, Set<Module> currentModules)
+            throws IOException;
+
+    /**
+     * Provided map contains all configuration that was set in pom for code
+     * generator in additionalConfiguration tag
+     *
+     * @param additionalConfiguration
+     */
+    void setAdditionalConfig(Map<String, String> additionalConfiguration);
+
+    /**
+     * Provided folder is marked as resources and its content will be packaged
+     * in resulting jar. Feel free to add necessary resources
+     *
+     * @param resourceBaseDir
+     */
+    void setResourceBaseDir(File resourceBaseDir);
+}
index d996c96b65eafe60ebe27e032eeaa2cb5c2d8f66..046ea5e52e7e8a7bc56925616e73b77a8ed6ece4 100644 (file)
@@ -7,67 +7,13 @@
  */
 package org.opendaylight.yangtools.yang2sources.spi;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.maven.plugin.logging.Log;
-import org.apache.maven.project.MavenProject;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
 /**
  * Classes implementing this interface can be submitted to maven-yang-plugin's
  * generate-sources goal.
+ *
+ * @deprecated Use {@link BasicCodeGenerator} with appropriate traits.
  */
-public interface CodeGenerator {
-
-    /**
-     * Generate sources from provided {@link SchemaContext}
-     *
-     * @param context
-     *            parsed from yang files
-     * @param outputBaseDir
-     *            expected output directory for generated sources configured by
-     *            user
-     * @param currentModules
-     *            yang modules parsed from yangFilesRootDir
-     * @return collection of files that were generated from schema context
-     * @throws IOException
-     */
-    Collection<File> generateSources(SchemaContext context, File outputBaseDir, Set<Module> currentModules)
-            throws IOException;
-
-    /**
-     * Utilize maven logging if necessary
-     *
-     * @param log
-     */
-    void setLog(Log log);
-
-    /**
-     * Provided map contains all configuration that was set in pom for code
-     * generator in additionalConfiguration tag
-     *
-     * @param additionalConfiguration
-     */
-    void setAdditionalConfig(Map<String, String> additionalConfiguration);
-
-    /**
-     * Provided folder is marked as resources and its content will be packaged
-     * in resulting jar. Feel free to add necessary resources
-     *
-     * @param resourceBaseDir
-     */
-    void setResourceBaseDir(File resourceBaseDir);
+@Deprecated
+public interface CodeGenerator extends BasicCodeGenerator, MavenLogAware, MavenProjectAware {
 
-    /**
-     * Provided maven project object. Any additional information about current
-     * maven project can be accessed from it.
-     *
-     * @param project
-     */
-    void setMavenProject(MavenProject project);
 }
diff --git a/yang/yang-maven-plugin-spi/src/main/java/org/opendaylight/yangtools/yang2sources/spi/MavenLogAware.java b/yang/yang-maven-plugin-spi/src/main/java/org/opendaylight/yangtools/yang2sources/spi/MavenLogAware.java
new file mode 100644 (file)
index 0000000..ef9fb63
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang2sources.spi;
+
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * Bridge compatibility class for plugins using the maven logger functionality.
+ *
+ * @deprecated Use slf4j logging directly.
+ */
+@Deprecated
+public interface MavenLogAware {
+    /**
+     * Utilize maven logging if necessary
+     *
+     * @param log maven log instance
+     */
+    void setLog(Log log);
+}
diff --git a/yang/yang-maven-plugin-spi/src/main/java/org/opendaylight/yangtools/yang2sources/spi/MavenProjectAware.java b/yang/yang-maven-plugin-spi/src/main/java/org/opendaylight/yangtools/yang2sources/spi/MavenProjectAware.java
new file mode 100644 (file)
index 0000000..602f78f
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang2sources.spi;
+
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Bridge for plugins which need access to the underlying maven project.
+ */
+public interface MavenProjectAware {
+    /**
+     * Provided maven project object. Any additional information about current
+     * maven project can be accessed from it.
+     *
+     * @param project
+     */
+    void setMavenProject(MavenProject project);
+}
index 7bfae12b3a6ebc4c5de78d8d3ab13973386b091b..c45fdc8c48ebc2cbe95c5bb7eb211b7b3e498e6e 100644 (file)
@@ -17,7 +17,7 @@ import org.apache.maven.project.MavenProject;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-public class CodeGeneratorTestImpl implements CodeGenerator {
+public class CodeGeneratorTestImpl implements BasicCodeGenerator, MavenLogAware, MavenProjectAware {
 
     private Log log;
 
index 5312ddb5953980240a2c81213fd6cbfbdc3d91f5..a7a611dd71953f57c685489a1c7e786b796b8855 100644 (file)
             <groupId>org.sonatype.plexus</groupId>
             <artifactId>plexus-build-api</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.codehaus.plexus</groupId>
-            <artifactId>plexus-slf4j-logging</artifactId>
-        </dependency>
 
         <dependency>
             <groupId>commons-io</groupId>
index b9287185b3ba47d9d27adb1d9201f13eadc3d1c0..ee9a6897423788f38eeff1bbce37a10103f44411 100644 (file)
@@ -126,21 +126,12 @@ final class Util {
     private static Class<?> resolveClass(String codeGeneratorClass, Class<?> baseType) throws ClassNotFoundException {
         Class<?> clazz = Class.forName(codeGeneratorClass);
 
-        if (!isImplemented(baseType, clazz)) {
+        if (!baseType.isAssignableFrom(clazz)) {
             throw new IllegalArgumentException("Code generator " + clazz + " has to implement " + baseType);
         }
         return clazz;
     }
 
-    private static boolean isImplemented(Class<?> expectedIface, Class<?> byClazz) {
-        for (Class<?> iface : byClazz.getInterfaces()) {
-            if (iface.equals(expectedIface)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     static String message(String message, String logPrefix, Object... args) {
         String innerMessage = String.format(message, args);
         return String.format("%s %s", logPrefix, innerMessage);
index c6c0badda738bebedccbce0340a91ece03b56cbc..0402e8b8a36517b6378e1bb2082a23208adbfe64 100644 (file)
@@ -32,8 +32,10 @@ import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream;
 import org.opendaylight.yangtools.yang2sources.plugin.ConfigArg.CodeGeneratorArg;
 import org.opendaylight.yangtools.yang2sources.plugin.Util.ContextHolder;
 import org.opendaylight.yangtools.yang2sources.plugin.Util.YangsInZipsResult;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
 import org.opendaylight.yangtools.yang2sources.spi.BuildContextAware;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.MavenLogAware;
+import org.opendaylight.yangtools.yang2sources.spi.MavenProjectAware;
 import org.sonatype.plexus.build.incremental.BuildContext;
 import org.sonatype.plexus.build.incremental.DefaultBuildContext;
 
@@ -267,7 +269,7 @@ class YangToSourcesProcessor {
 
         codeGeneratorCfg.check();
 
-        CodeGenerator g = Util.getInstance(codeGeneratorCfg.getCodeGeneratorClass(), CodeGenerator.class);
+        BasicCodeGenerator g = Util.getInstance(codeGeneratorCfg.getCodeGeneratorClass(), BasicCodeGenerator.class);
         log.info(Util.message("Code generator instantiated from %s", LOG_PREFIX,
                 codeGeneratorCfg.getCodeGeneratorClass()));
 
@@ -284,11 +286,15 @@ class YangToSourcesProcessor {
         log.debug(Util.message("Additional configuration picked up for : %s: %s", LOG_PREFIX,
                 codeGeneratorCfg.getCodeGeneratorClass(), codeGeneratorCfg.getAdditionalConfiguration()));
 
+        if (g instanceof MavenLogAware) {
+            ((MavenLogAware)g).setLog(log);
+        }
         if (g instanceof BuildContextAware) {
             ((BuildContextAware)g).setBuildContext(buildContext);
         }
-        g.setLog(log);
-        g.setMavenProject(project);
+        if (g instanceof MavenProjectAware) {
+            ((MavenProjectAware)g).setMavenProject(project);
+        }
         g.setAdditionalConfig(codeGeneratorCfg.getAdditionalConfiguration());
         File resourceBaseDir = codeGeneratorCfg.getResourceBaseDir(project);
 
index 1200e16cc5a2a1660d3348348189d3e9d2d37160..063083eaed20da9e1c01669f3130afb20e1d7f6c 100644 (file)
@@ -37,7 +37,9 @@ import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang2sources.plugin.ConfigArg.CodeGeneratorArg;
 import org.opendaylight.yangtools.yang2sources.plugin.YangToSourcesProcessor.YangProvider;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.MavenLogAware;
+import org.opendaylight.yangtools.yang2sources.spi.MavenProjectAware;
 
 public class GenerateSourcesTest {
 
@@ -81,7 +83,7 @@ public class GenerateSourcesTest {
                 + "generated-sources" + File.separator + "spi"));
     }
 
-    public static class GeneratorMock implements CodeGenerator {
+    public static class GeneratorMock implements BasicCodeGenerator, MavenLogAware, MavenProjectAware {
 
         private static int called = 0;
         private static File outputDir;
index 4a2473cd8dc451187b52db9e92e1f36646d1bb56..3f0f330413c07badf31b9e50d85d779ad3121e5c 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.model.api;
 
+
 /**
  * The ContainerSchemaNode is used to define an interior data node in the schema
  * tree. There are two styles of containers, those that exist only for
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/Rfc6020Mapping.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/Rfc6020Mapping.java
new file mode 100644 (file)
index 0000000..93f97ec
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.YangConstants;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.stmt.AnyxmlStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.BaseStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.BelongsToStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.BitStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ConfigStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ContactStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ContainerStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DefaultStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DeviateStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DeviationStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.EnumStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ErrorAppTagStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ErrorMessageStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.FeatureStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.FractionDigitsStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.IfFeatureStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ImportStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.IncludeStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LeafListStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LeafStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LengthStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ListStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.MaxElementsStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.MinElementsStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.MustStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.NamespaceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.NotificationStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.OrderedByStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.OrganizationStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PathStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PatternStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PositionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PresenceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RangeStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RequireInstanceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RevisionDateStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RevisionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RpcStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.StatusStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.UniqueStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.UnitsStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ValueStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.YinElementStatement;
+
+@Beta
+public enum Rfc6020Mapping implements StatementDefinition {
+    Anyxml(AnyxmlStatement.class, "anyxml", "name"),
+    Argument(ArgumentStatement.class, "argument", "name"),
+    Augment(AugmentStatement.class, "augment", "target-node"),
+    Base(BaseStatement.class, "base", "name"),
+    BelongsTo(BelongsToStatement.class, "belongs-to", "module"),
+    Bit(BitStatement.class, "bit", "name"),
+    Case(CaseStatement.class, "case", "name"),
+    Choice(ChoiceStatement.class, "choice", "name"),
+    Config(ConfigStatement.class, "config", "value"),
+    Contact(ContactStatement.class, "contact", "text", true),
+    Container(ContainerStatement.class, "container", "name"),
+    Default(DefaultStatement.class, "default", "value"),
+    Description(DescriptionStatement.class, "description", "text", true),
+    Deviate(DeviateStatement.class, "deviate", "value"),
+    Deviation(DeviationStatement.class, "deviation", "target-node"),
+    Enum(EnumStatement.class, "enum", "name"),
+    ErrorAppTag(ErrorAppTagStatement.class, "error-app-tag", "value"),
+    ErrorMessage(ErrorMessageStatement.class, "error-message", "value", true),
+    Extension(ExtensionStatement.class, "extension", "name"),
+    Feature(FeatureStatement.class, "feature", "name"),
+    FractionDigits(FractionDigitsStatement.class, "fraction-digits", "value"),
+    Grouping(GroupingStatement.class, "grouping", "name"),
+    Identity(IdentityStatement.class, "identity", "name"),
+    IfFeature(IfFeatureStatement.class, "if-feature", "name"),
+    Import(ImportStatement.class, "import", "module"),
+    Include(IncludeStatement.class, "include", "module"),
+    Input(InputStatement.class, "input"),
+    Key(KeyStatement.class, "key", "value"),
+    Leaf(LeafStatement.class, "leaf", "name"),
+    LeafList(LeafListStatement.class, "leaf-list", "name"),
+    Length(LengthStatement.class, "length", "value"),
+    List(ListStatement.class, "list", "name"),
+    Mandatory(MandatoryStatement.class, "mandatory", "value"),
+    MaxElements(MaxElementsStatement.class, "max-elements", "value"),
+    MinElements(MinElementsStatement.class, "min-elements", "value"),
+    Module(ModuleStatement.class, "module", "name"),
+    Must(MustStatement.class, "must", "condition"),
+    Namespace(NamespaceStatement.class, "namespace", "uri"),
+    Notification(NotificationStatement.class, "notification", "name"),
+    OrderedBy(OrderedByStatement.class, "ordered-by", "value"),
+    Organization(OrganizationStatement.class, "organization", "text", true),
+    Output(OutputStatement.class, "output"),
+    Path(PathStatement.class, "path", "value"),
+    Pattern(PatternStatement.class, "pattern", "value"),
+    Position(PositionStatement.class, "position", "value"),
+    Prefix(PrefixStatement.class, "prefix", "value"),
+    Presence(PresenceStatement.class, "presence", "value"),
+    Range(RangeStatement.class, "range", "value"),
+    Reference(ReferenceStatement.class, "reference", "text", true),
+    Refine(RefineStatement.class, "refine", "target-node"),
+    RequireInstance(RequireInstanceStatement.class, "require-instance", "value"),
+    Revision(RevisionStatement.class, "revision", "date"),
+    RevisionDate(RevisionDateStatement.class, "revision-date", "date"),
+    Rpc(RpcStatement.class, "rpc", "name"),
+    Status(StatusStatement.class, "status", "value"),
+    Submodule(SubmoduleStatement.class, "submodule", "name"),
+    Type(TypeStatement.class, "type", "name"),
+    Typedef(TypedefStatement.class, "typedef", "name"),
+    Unique(UniqueStatement.class, "unique", "tag"),
+    Units(UnitsStatement.class, "units", "name"),
+    Uses(UsesStatement.class, "uses", "name"),
+    Value(ValueStatement.class, "value", "value"),
+    When(WhenStatement.class, "when", "condition"),
+    YangVersion(YangVersionStatement.class, "yang-version", "value"),
+    YinElement(YinElementStatement.class, "yin-element", "value");
+
+    private final @Nonnull Class<? extends DeclaredStatement<?>> type;
+    private final @Nonnull QName name;
+    private final @Nullable QName argument;
+    private final boolean yinElement;
+
+
+    private Rfc6020Mapping(Class<? extends DeclaredStatement<?>> clz, final String nameStr) {
+        type = Preconditions.checkNotNull(clz);
+        name = yinQName(nameStr);
+        argument = null;
+        yinElement = false;
+    }
+
+    private Rfc6020Mapping(Class<? extends DeclaredStatement<?>> clz, final String nameStr, final String argumentStr) {
+        type = Preconditions.checkNotNull(clz);
+        name = yinQName(nameStr);
+        argument = yinQName(argumentStr);
+        this.yinElement = false;
+    }
+
+    private Rfc6020Mapping(Class<? extends DeclaredStatement<?>> clz, final String nameStr, final String argumentStr,
+            final boolean yinElement) {
+        type = Preconditions.checkNotNull(clz);
+        name = yinQName(nameStr);
+        argument = yinQName(argumentStr);
+        this.yinElement = yinElement;
+    }
+
+    private static QName yinQName(String nameStr) {
+        return QName.cachedReference(QName.create(YangConstants.RFC6020_YIN_MODULE, nameStr));
+    }
+
+    @Override
+    public QName getStatementName() {
+        return name;
+    }
+
+    @Override
+    public QName getArgumentName() {
+        return argument;
+    }
+
+    @Override
+    public Class<? extends DeclaredStatement<?>> getDeclaredRepresentationClass() {
+        return type;
+    }
+
+    @Override
+    public Class<? extends DeclaredStatement<?>> getEffectiveRepresentationClass() {
+        // FIXME: Add support once these interfaces are defined.
+        throw new UnsupportedOperationException("Not defined yet.");
+    }
+
+    public boolean isArgumentYinElement() {
+        return yinElement;
+    }
+}
+
index 89dfbf5cf00d2c292f4c1c36b94076c4e79902d9..985a7cdd7d61184e10e6e7825a87acd3628b933b 100644 (file)
@@ -7,8 +7,8 @@
  */
 package org.opendaylight.yangtools.yang.model.api;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
@@ -334,7 +334,7 @@ public abstract class SchemaPath implements Immutable {
 
     @Override
     public final String toString() {
-        return addToStringAttributes(Objects.toStringHelper(this)).toString();
+        return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
     }
 
     protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/DeclaredStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/DeclaredStatement.java
new file mode 100644 (file)
index 0000000..dbe80e9
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.meta;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+/**
+ * Represents declared statement
+ *
+ * @param <A> Argument type ({@link Void} if statement does not have argument.)
+ */
+public interface DeclaredStatement<A> extends ModelStatement<A> {
+
+    /**
+     *
+     * Returns statement argument as was present in original source.
+     *
+     * @return statement argument as was present in original source or null, if statement does not take argument.
+     */
+    @Nullable String rawArgument();
+
+    /**
+     *
+     * Returns collection of explicitly declared child statements, while preserving its original
+     * ordering from original source.
+     *
+     * @return Collection of statements, which were explicitly declared in
+     *         source of model.
+     */
+    @Nonnull Collection<? extends DeclaredStatement<?>> declaredSubstatements();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/EffectiveStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/EffectiveStatement.java
new file mode 100644 (file)
index 0000000..026a0a0
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.meta;
+
+import java.util.Collection;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+/**
+ * Effective model statement which should be used to derive application behaviour.
+ *
+ * @param <A>
+ *            Argument type ({@link Void} if statement does not have argument.)
+ * @param <S>
+ *            Class representing declared version of this statement.
+ */
+public interface EffectiveStatement<A, S extends DeclaredStatement<A>> extends ModelStatement<A> {
+
+    /**
+     * Returns statement, which was explicit declaration of this effective
+     * statement.
+     *
+     *
+     * @return statement, which was explicit declaration of this effective
+     *         statement or null if statement was inferred from context.
+     */
+    @Nullable
+    S getDeclared();
+
+    /**
+     *
+     * Returns value associated with supplied identifier
+     *
+     * @param <K>
+     *            Identifier type
+     * @param <V>
+     *            Value type
+     * @param <N>
+     *            Namespace identifier type
+     * @param namespace
+     *            Namespace type
+     * @param identifier
+     *            Identifier of element.
+     * @return Value if present, null otherwise.
+     *
+     *
+     */
+    @Nullable
+    <K, V, N extends IdentifierNamespace<? super K, ? extends V>> V get(@Nonnull Class<N> namespace,@Nonnull  K identifier);
+
+    /**
+     *
+     * Returns all local values from supplied namespace.
+     *
+     * @param <K>
+     *            Identifier type
+     * @param <V>
+     *            Value type
+     * @param <N>
+     *            Namespace identifier type
+     * @param namespace
+     *            Namespace type
+     * @return Value if present, null otherwise.
+     */
+    @Nullable
+    <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAll(@Nonnull Class<N> namespace);
+
+    /**
+     *
+     * Returns iteration of all effective substatements.
+     *
+     * @return iteration of all effective substatements.
+     */
+    Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/IdentifierNamespace.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/IdentifierNamespace.java
new file mode 100644 (file)
index 0000000..3a28984
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.meta;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+/**
+ *
+ * Model specific namespace which allows access to specific
+ *
+ * {@link IdentifierNamespace} serves as common superclass for YANG model
+ * namespaces, which are type-captured subclasses. This type capture
+ * of namespace allows for handy type-safe reading methods
+ * such as {@link EffectiveStatement#get(Class, Object)} and still
+ * allows introduction of new namespaces without need to change
+ * model APIs.
+ *
+ * @param <K> Identifier type
+ * @param <V> Value type
+ */
+public interface IdentifierNamespace<K,V> {
+
+    /**
+     *
+     * Returns value associated with supplied identifier
+     *
+     * @param identifier Identifier of value
+     * @return value or null, if identifier is not present in namespace.
+     */
+    @Nullable V get(@Nonnull K identifier);
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/ModelStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/ModelStatement.java
new file mode 100644 (file)
index 0000000..7d4127b
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.meta;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+/**
+ *
+ * Model statement
+ *
+ * There are two base types of model statements:
+ * <ul>
+ * <li>{@link DeclaredStatement} - Statement representation as was defined in original
+ * source. This representation could be used during computation of effective model
+ * or during transforming YANG model from one serialization format to other.
+ * </li>
+ * <li>
+ * {@link EffectiveStatement} - Representation of effective statement - this
+ * statement may be different from declared, in such way, that it contains additional
+ * substatements, provides access to model namespaces. Some effective statements may be not
+ * directly declared in YANG source, but could be inferred by semantic processing of
+ * other statements (eg. uses, augment).
+ * </li>
+ * </ul>
+ *
+ * @param <A> Argument type ({@link Void} if statement does not have argument.)
+ */
+public interface ModelStatement<A> {
+
+    /**
+     * Statement Definition of this statement.
+     *
+     * @return definition of this statement.
+     */
+    @Nonnull StatementDefinition statementDefinition();
+
+    /**
+     *
+     * Returns statement argument
+     *
+     * @return statement argument or null if statement does not have argument.
+     */
+    @Nullable A argument();
+
+    /**
+     * Returns statement source, which denotes if statement was
+     * explicitly declared in original model or inferred during
+     * semantic processing of model.
+     *
+     * @return statement source.
+     */
+    @Nonnull StatementSource getStatementSource();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/StatementDefinition.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/StatementDefinition.java
new file mode 100644 (file)
index 0000000..5d5d2da
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.meta;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.QName;
+
+/**
+ *
+ * Definition / model of YANG {@link DeclaredStatement} and {@link EffectiveStatement}.
+ *
+ * Statement concept is defined in RFC6020 section 6.3:
+ * <blockquote> A YANG
+ * module contains a sequence of statements. Each statement starts with a
+ * keyword, followed by zero or one argument
+ * </blockquote>
+ *
+ * Source: <a href="https://tools.ietf.org/html/rfc6020#section-6.3"> </a>
+ *
+ *
+ */
+public interface StatementDefinition extends Immutable {
+
+    /**
+     *
+     * Returns name of the statement
+     *
+     * @return Name of the statement
+     */
+    @Nonnull
+    QName getStatementName();
+
+    /**
+     *
+     * Returns name of statement argument or null, if statement does not have
+     * argument.
+     *
+     * @return argument name or null, if statement does not take argument.
+     */
+    @Nullable
+    QName getArgumentName();
+
+    /**
+     *
+     * Returns class which represents declared version of statement associated
+     * with this definition.
+     *
+     * This class should be interface, which provides convenience access to
+     * declared substatements.
+     *
+     * @return class which represents declared version of statement associated
+     *         with this definition.
+     */
+    @Nonnull
+    Class<? extends DeclaredStatement<?>> getDeclaredRepresentationClass();
+
+    /**
+     *
+     * Returns class which represents supplied statement.
+     *
+     * This class should be interface, which defines convenience access to
+     * statement properties, namespace items and substatements.
+     *
+     * @return class which represents declared version of statement associated
+     *         with this definition
+     */
+    @Nonnull
+    Class<? extends DeclaredStatement<?>> getEffectiveRepresentationClass();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/StatementSource.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/StatementSource.java
new file mode 100644 (file)
index 0000000..315202f
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.meta;
+/**
+ *
+ * Origin of statement
+ *
+ * Represents origin of statement - if it was explicitly present
+ * in model representation or if it was inferred from context.
+ *
+ */
+public enum StatementSource {
+
+    /**
+     *
+     * Statement was explicitly declared by author
+     * of the supplied model.
+     *
+     */
+    DECLARATION,
+    /**
+     *
+     * Statement was derived from context of YANG model / statement
+     * and represents effective model.
+     *
+     * Effective context nodes are derived from applicable {@link #DECLARATION}
+     * statements by interpreting their semantic meaning in context
+     * of current statement.
+     *
+     */
+    CONTEXT
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/package-info.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/package-info.java
new file mode 100644 (file)
index 0000000..d871e3b
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+/**
+ * Meta model of YANG model as was defined in RFC6020 and extracted by analysis
+ * of YANG text.
+ *
+ * <p>
+ * Existence of meta-model allows for better evolution of YANG language as it evolves
+ * and allows for better support of different serializations of YANG model.
+ *
+ * <h2>Statements</h2>
+ * YANG source is defined as sequence of statement in
+ * <a href="https://tools.ietf.org/html/rfc6020#section-6.3">RFC6020, Section 6.3</a>.
+ * this model is also correct for YIN, which is XML serialisation of YANG source.
+ * <p>
+ * Statements are represented as instances / subclasses of {@link org.opendaylight.yangtools.yang.model.api.meta.ModelStatement}
+ * concept and its two subconcepts which are:
+ * <ul>
+ * <li>
+ * {@link org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement} - this contains navigable
+ * set of statements model as they was defined / present in original processed
+ * sources.
+ * </li>
+ * <li>{@link org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement} - navigable set of statements
+ * which represents effective model of parsed YANG sources, which is derived by rules
+ * present in YANG specification and/or was introduced in form of extensions.
+ * </li>
+ * </ul>
+ * <p>
+ * Clear separation of declared / effective model is needed, since statement definition also
+ * contains information how effective model is computed and there is no one to one mapping
+ * between declared and effective model thanks to statements such as {@code uses},
+ * {@code augment},{@code deviate},{@code refine}.
+ *
+ * <h2>Identifiers and Namespaces</h2>
+ * Effective model of YANG has several identifier types and namespaces, which behaves differently
+ * and are mostly used during processing data and/or during computing effective (semantic) model.
+ * <p>
+ * Common abstraction for various types of namespaces is {@link org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace}
+ * from which concrete effective model namespaces are derived.
+ *
+ */
+package org.opendaylight.yangtools.yang.model.api.meta;
\ No newline at end of file
index 16bd01985d298c07086be7f040a982538a46e172..58db208f1b26bb6b8d5eb8acf14b197827f84a9c 100644 (file)
@@ -7,9 +7,27 @@
  */
 
 /**
- * Definition of structures and DOM Like API of processed YANG schema
+ * Definition of structures and DOM like API of effected YANG schema
  *
- * <h3>YANG Statement mapping</h3>
+ * <p>
+ * This package is structured into following logical units:
+ * <dl>
+ * <dt>YANG Meta model</dt>
+ * <dd>Meta model of YANG, which defines basic concepts and building blocks of YANG models
+ * such as {@link org.opendaylight.yangtools.yang.model.api.meta.ModelStatement}.</dd>
+ * <dt>YANG Statement model</dt>
+ * <dd>Concrete java model of YANG statements, which defines basic relationship between statements
+ * and represents these statements.</dd>
+ *
+ * <dt>YANG Effective model</dt>
+ * <dd>Effective model of processed YANG models, which represents semantic interpretation
+ * of YANG models and provides convenience views for interpreting models.
+ * </dd>
+ * </dl>
+ *
+ *
+ * <h2>YANG Effective model</h2>
+ * <h3>Effective model statement mapping</h3>
  *
  * <dl>
  * <dt>anyxml
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/AnyxmlStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/AnyxmlStatement.java
new file mode 100644 (file)
index 0000000..278423d
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nullable;
+
+public interface AnyxmlStatement extends DataDefinitionStatement {
+
+    @Nullable Collection<? extends MustStatement> getMusts();
+
+    @Nullable ConfigStatement getConfig();
+
+    @Nullable MandatoryStatement getMandatory();
+
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ArgumentStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ArgumentStatement.java
new file mode 100644 (file)
index 0000000..2f83adf
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+
+@Rfc6020AbnfRule("argument-stmt")
+public interface ArgumentStatement extends DeclaredStatement<QName> {
+
+    @Nonnull String getName();
+
+    @Nullable YinElementStatement getYinElement();
+
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/AugmentStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/AugmentStatement.java
new file mode 100644 (file)
index 0000000..1764664
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface AugmentStatement extends DeclaredStatement<SchemaNodeIdentifier> , DataDefinitionContainer {
+
+    @Nonnull SchemaNodeIdentifier getTargetNode();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BaseStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BaseStatement.java
new file mode 100644 (file)
index 0000000..e7c5a59
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface BaseStatement extends DeclaredStatement<QName> {
+
+    @Nonnull QName getName();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BelongsToStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BelongsToStatement.java
new file mode 100644 (file)
index 0000000..f9a1dd8
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface BelongsToStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getModule();
+
+    @Nonnull PrefixStatement getPrefix();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BitStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BitStatement.java
new file mode 100644 (file)
index 0000000..2b1862e
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface BitStatement extends DeclaredStatement<String>, DocumentationGroup.WithStatus {
+
+    @Nonnull String getName();
+
+    @Nullable PositionStatement getPosition();
+
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BodyGroup.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BodyGroup.java
new file mode 100644 (file)
index 0000000..9b09c07
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+
+
+@Rfc6020AbnfRule("body-stmts")
+public interface BodyGroup extends DataDefinitionContainer.WithReusableDefinitions {
+
+    @Nonnull Collection<? extends ExtensionStatement> getExtensions();
+
+    @Nonnull Collection<? extends FeatureStatement> getFeatures();
+
+    @Nonnull Collection<? extends IdentityStatement> getIdentities();
+
+    @Nonnull Collection<? extends AugmentStatement> getAugments();
+
+    @Nonnull Collection<? extends RpcStatement> getRpcs();
+
+    @Nonnull Collection<? extends NotificationStatement> getNotifications();
+
+    @Nonnull Collection<? extends DeviationStatement> getDeviations();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/CaseStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/CaseStatement.java
new file mode 100644 (file)
index 0000000..b30f4a3
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+public interface CaseStatement extends DeclaredStatement<QName>, DataDefinitionContainer, DocumentationGroup.WithStatus, ConditionalDataDefinition {
+
+    @Nonnull QName getName();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ChoiceStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ChoiceStatement.java
new file mode 100644 (file)
index 0000000..051865d
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+
+
+public interface ChoiceStatement extends DataDefinitionStatement {
+
+    @Nullable DefaultStatement getDefault();
+
+    @Nullable ConfigStatement getConfig();
+
+    @Nullable MandatoryStatement getMandatory();
+
+    @Nonnull Collection<? extends CaseStatement> getCases();
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ConditionalDataDefinition.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ConditionalDataDefinition.java
new file mode 100644 (file)
index 0000000..ac36fac
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+public interface ConditionalDataDefinition extends ConditionalFeature {
+
+    WhenStatement getWhenStatement();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ConditionalFeature.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ConditionalFeature.java
new file mode 100644 (file)
index 0000000..34cbc50
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+
+
+@Rfc6020AbnfRule("*(if-feature-stmt)")
+public interface ConditionalFeature {
+
+    @Nonnull Collection<? extends IfFeatureStatement> getIfFeatures();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ConfigStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ConfigStatement.java
new file mode 100644 (file)
index 0000000..65a1cd9
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ConfigStatement extends DeclaredStatement<Boolean> {
+
+    @Nonnull Boolean getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ContactStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ContactStatement.java
new file mode 100644 (file)
index 0000000..0a45de0
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ContactStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getText();
+
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ContainerStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ContainerStatement.java
new file mode 100644 (file)
index 0000000..ac50ff3
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nullable;
+
+
+public interface ContainerStatement extends DataDefinitionStatement, DataDefinitionContainer.WithReusableDefinitions {
+
+    @Nullable Collection<? extends MustStatement> getMusts();
+
+    @Nullable PresenceStatement getPresence();
+
+    @Nullable ConfigStatement getConfig();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataDefinitionContainer.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataDefinitionContainer.java
new file mode 100644 (file)
index 0000000..2250ef3
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+
+
+public interface DataDefinitionContainer {
+
+    Collection<? extends DataDefinitionStatement> getDataDefinitions();
+
+
+    public interface WithReusableDefinitions extends DataDefinitionContainer {
+
+        Collection<? extends TypedefStatement> getTypedefs();
+
+        Collection<? extends GroupingStatement> getGroupings();
+
+    }
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataDefinitionStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataDefinitionStatement.java
new file mode 100644 (file)
index 0000000..610be63
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+/**
+ *
+ * Statement that defines new data nodes.
+ *
+ * One of container, leaf, leaf-list, list, choice, case,
+ * augment, uses, and anyxml.
+ *
+ *
+ * Defined in: https://tools.ietf.org/html/rfc6020#section-3
+ *
+ */
+@Rfc6020AbnfRule("data-def-stmt")
+public interface DataDefinitionStatement extends DeclaredStatement<QName>, DocumentationGroup.WithStatus, ConditionalDataDefinition {
+
+    @Nonnull QName getName();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DefaultStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DefaultStatement.java
new file mode 100644 (file)
index 0000000..433d28f
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface DefaultStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DescriptionStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DescriptionStatement.java
new file mode 100644 (file)
index 0000000..fa109f2
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface DescriptionStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getText();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DeviateStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DeviateStatement.java
new file mode 100644 (file)
index 0000000..00ec940
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface DeviateStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DeviationStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DeviationStatement.java
new file mode 100644 (file)
index 0000000..1c92c32
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface DeviationStatement extends DeclaredStatement<SchemaNodeIdentifier> {
+
+
+    @Nonnull SchemaNodeIdentifier getTargetNode();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DocumentationGroup.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DocumentationGroup.java
new file mode 100644 (file)
index 0000000..0d5cb3c
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nullable;
+
+public interface DocumentationGroup {
+
+    @Nullable DescriptionStatement getDescription();
+
+    @Nullable ReferenceStatement getReference();
+
+
+
+    public interface WithStatus extends DocumentationGroup {
+
+        @Nullable StatusStatement getStatus();
+
+    }
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DocumentedConstraintGroup.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DocumentedConstraintGroup.java
new file mode 100644 (file)
index 0000000..0de0711
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nullable;
+
+public interface DocumentedConstraintGroup extends DocumentationGroup {
+
+    @Nullable ErrorAppTagStatement getErrorAppTagStatement();
+
+    @Nullable ErrorMessageStatement getErrorMessageStatement();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/EnumStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/EnumStatement.java
new file mode 100644 (file)
index 0000000..a2e373d
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface EnumStatement extends DeclaredStatement<String>, DocumentationGroup.WithStatus {
+
+    @Nonnull String getName();
+
+    @Nullable ValueStatement getValue();
+
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ErrorAppTagStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ErrorAppTagStatement.java
new file mode 100644 (file)
index 0000000..2fc91b4
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ErrorAppTagStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ErrorMessageStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ErrorMessageStatement.java
new file mode 100644 (file)
index 0000000..ab60f11
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ErrorMessageStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ExtensionStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ExtensionStatement.java
new file mode 100644 (file)
index 0000000..80204f5
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ExtensionStatement extends DeclaredStatement<QName>, DocumentationGroup.WithStatus {
+
+    @Nullable ArgumentStatement getArgument();
+
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FeatureStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FeatureStatement.java
new file mode 100644 (file)
index 0000000..6d6f93e
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface FeatureStatement extends DeclaredStatement<QName>, DocumentationGroup.WithStatus, ConditionalFeature {
+
+    @Nonnull QName getName();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FractionDigitsStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FractionDigitsStatement.java
new file mode 100644 (file)
index 0000000..7e8d1f6
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+public interface FractionDigitsStatement extends DeclaredStatement<String> {
+
+    String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/GroupingStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/GroupingStatement.java
new file mode 100644 (file)
index 0000000..534d581
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+public interface GroupingStatement extends DeclaredStatement<QName>, DocumentationGroup.WithStatus,DataDefinitionContainer.WithReusableDefinitions {
+
+    @Nonnull QName getName();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityStatement.java
new file mode 100644 (file)
index 0000000..07b61c5
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface IdentityStatement extends DeclaredStatement<QName>, DocumentationGroup.WithStatus {
+
+    @Nonnull String getName();
+
+    @Nullable BaseStatement getBase();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IfFeatureStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IfFeatureStatement.java
new file mode 100644 (file)
index 0000000..6604678
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface IfFeatureStatement extends DeclaredStatement<QName> {
+
+    @Nonnull QName getName();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ImportStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ImportStatement.java
new file mode 100644 (file)
index 0000000..5d1550f
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ImportStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getModule();
+
+    @Nonnull PrefixStatement getPrefix();
+
+    @Nullable RevisionDateStatement getRevisionDate();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IncludeStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IncludeStatement.java
new file mode 100644 (file)
index 0000000..eeead85
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface IncludeStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getModule();
+
+    @Nonnull PrefixStatement getPrefix();
+
+    @Nullable RevisionDateStatement getRevisionDate();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/InputStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/InputStatement.java
new file mode 100644 (file)
index 0000000..81122af
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface InputStatement  extends DeclaredStatement<Void>, DataDefinitionContainer.WithReusableDefinitions {
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/KeyStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/KeyStatement.java
new file mode 100644 (file)
index 0000000..e015604
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface KeyStatement extends DeclaredStatement<Collection<SchemaNodeIdentifier>> {
+
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LeafListStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LeafListStatement.java
new file mode 100644 (file)
index 0000000..7c4111e
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nullable;
+
+
+
+public interface LeafListStatement extends DataDefinitionStatement, MultipleElementsGroup, TypeGroup {
+
+    @Nullable Collection<? extends MustStatement> getMusts();
+
+    @Nullable ConfigStatement getConfig();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LeafStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LeafStatement.java
new file mode 100644 (file)
index 0000000..5923819
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nullable;
+
+
+
+public interface LeafStatement extends DataDefinitionStatement, TypeGroup {
+
+    @Nullable Collection<? extends MustStatement> getMusts();
+
+    @Nullable DefaultStatement getDefault();
+
+    @Nullable ConfigStatement getConfig();
+
+    @Nullable MandatoryStatement getMandatory();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LengthStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LengthStatement.java
new file mode 100644 (file)
index 0000000..490b67d
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface LengthStatement extends DeclaredStatement<String>, DocumentedConstraintGroup {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LinkageGroup.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LinkageGroup.java
new file mode 100644 (file)
index 0000000..3f75c62
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+
+
+@Rfc6020AbnfRule("linkage-stms")
+public interface LinkageGroup {
+
+    @Nonnull Collection<? extends ImportStatement> getImports();
+
+    @Nonnull Collection<? extends IncludeStatement> getIncludes();
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ListStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ListStatement.java
new file mode 100644 (file)
index 0000000..4dd9361
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nullable;
+
+public interface ListStatement extends DataDefinitionStatement, MultipleElementsGroup,
+        DataDefinitionContainer.WithReusableDefinitions {
+
+    Collection<? extends MustStatement> getMusts();
+
+    @Nullable KeyStatement getKey();
+
+    Collection<? extends UniqueStatement> getUnique();
+
+    @Nullable ConfigStatement getConfig();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MandatoryStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MandatoryStatement.java
new file mode 100644 (file)
index 0000000..d5ec65e
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface MandatoryStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MaxElementsStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MaxElementsStatement.java
new file mode 100644 (file)
index 0000000..310d4f9
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface MaxElementsStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MetaGroup.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MetaGroup.java
new file mode 100644 (file)
index 0000000..ca8d828
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nullable;
+
+
+@Rfc6020AbnfRule("meta-stmts")
+public interface MetaGroup extends DocumentationGroup {
+
+    @Nullable OrganizationStatement getOrganization();
+
+    @Nullable ContactStatement getContact();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MinElementsStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MinElementsStatement.java
new file mode 100644 (file)
index 0000000..f355cc1
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface MinElementsStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ModuleHeaderGroup.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ModuleHeaderGroup.java
new file mode 100644 (file)
index 0000000..baac658
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+@Rfc6020AbnfRule("module-header-stmts")
+public interface ModuleHeaderGroup {
+
+    @Nullable YangVersionStatement getYangVersion();
+    @Nonnull NamespaceStatement getNamespace();
+    @Nonnull PrefixStatement getPrefix();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ModuleStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ModuleStatement.java
new file mode 100644 (file)
index 0000000..b4264df
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ModuleStatement extends DeclaredStatement<String>, ModuleHeaderGroup, LinkageGroup, MetaGroup,
+        RevisionGroup, BodyGroup
+
+    {
+
+    @Nonnull String getName();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MultipleElementsGroup.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MultipleElementsGroup.java
new file mode 100644 (file)
index 0000000..b4134b6
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nullable;
+
+public interface MultipleElementsGroup {
+
+    @Nullable MinElementsStatement getMinElements();
+
+    @Nullable MaxElementsStatement getMaxElements();
+
+    @Nullable OrderedByStatement getOrderedBy();
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MustStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MustStatement.java
new file mode 100644 (file)
index 0000000..640c0a0
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface MustStatement extends DeclaredStatement<RevisionAwareXPath>, DocumentedConstraintGroup {
+
+    @Nonnull RevisionAwareXPath getCondition();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NamespaceStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NamespaceStatement.java
new file mode 100644 (file)
index 0000000..92a1967
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.net.URI;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface NamespaceStatement extends DeclaredStatement<URI> {
+
+    @Nonnull URI getUri();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NotificationStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NotificationStatement.java
new file mode 100644 (file)
index 0000000..fed0ca6
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface NotificationStatement extends DeclaredStatement<QName> {
+
+    @Nonnull QName getName();
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/OrderedByStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/OrderedByStatement.java
new file mode 100644 (file)
index 0000000..bb3935c
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface OrderedByStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/OrganizationStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/OrganizationStatement.java
new file mode 100644 (file)
index 0000000..20bb371
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface OrganizationStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getText();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/OutputStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/OutputStatement.java
new file mode 100644 (file)
index 0000000..b8ff5c7
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface OutputStatement extends DeclaredStatement<Void>, DataDefinitionContainer.WithReusableDefinitions {
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PathStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PathStatement.java
new file mode 100644 (file)
index 0000000..395ddc2
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface PathStatement extends DeclaredStatement<RevisionAwareXPath> {
+
+    // FIXME: Introduce proper type representing parsed leafref
+    @Nonnull String getValue();
+
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PatternStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PatternStatement.java
new file mode 100644 (file)
index 0000000..fe6d429
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface PatternStatement extends DeclaredStatement<String>, DocumentedConstraintGroup {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PositionStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PositionStatement.java
new file mode 100644 (file)
index 0000000..447590f
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface PositionStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PrefixStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PrefixStatement.java
new file mode 100644 (file)
index 0000000..7f768c2
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface PrefixStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PresenceStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PresenceStatement.java
new file mode 100644 (file)
index 0000000..af5e1d0
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface PresenceStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RangeStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RangeStatement.java
new file mode 100644 (file)
index 0000000..f8ca4ff
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface RangeStatement extends DeclaredStatement<String>, DocumentedConstraintGroup {
+
+    @Nonnull String getRange();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ReferenceStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ReferenceStatement.java
new file mode 100644 (file)
index 0000000..1adbacc
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ReferenceStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getText();
+
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RefineStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RefineStatement.java
new file mode 100644 (file)
index 0000000..790fc87
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+public interface RefineStatement extends DeclaredStatement<SchemaNodeIdentifier>, DocumentationGroup {
+
+    String getTargetNode();
+
+    public interface RefineContainerStatement extends RefineStatement {
+
+        Collection<? extends MustStatement> getMusts();
+
+        @Nullable ConfigStatement getConfig();
+
+        @Nullable PresenceStatement getPresence();
+
+    }
+
+    public interface RefineLeafStatement extends RefineStatement {
+
+        Collection<? extends MustStatement> getMusts();
+
+        @Nullable DefaultStatement getDefault();
+
+        @Nullable ConfigStatement getConfig();
+
+        @Nullable PresenceStatement getPresence();
+
+    }
+
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RequireInstanceStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RequireInstanceStatement.java
new file mode 100644 (file)
index 0000000..b1de1e8
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+public interface RequireInstanceStatement extends DeclaredStatement<Boolean> {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RevisionDateStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RevisionDateStatement.java
new file mode 100644 (file)
index 0000000..96b7b12
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface RevisionDateStatement extends DeclaredStatement<String> {
+
+    String getDate();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RevisionGroup.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RevisionGroup.java
new file mode 100644 (file)
index 0000000..8001c27
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+
+
+@Rfc6020AbnfRule("revision-stmts")
+public interface RevisionGroup {
+
+    Collection<? extends RevisionStatement> getRevisions();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RevisionStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RevisionStatement.java
new file mode 100644 (file)
index 0000000..fd6d850
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface RevisionStatement extends DeclaredStatement<String>, DocumentationGroup {
+
+    String getDate();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/Rfc6020AbnfRule.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/Rfc6020AbnfRule.java
new file mode 100644 (file)
index 0000000..163f2d6
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+*
+* References ABNF rule defined in RFC6020 - YANG Specification.
+*
+* <p>
+* An interface / class annotated with this annotation
+* is Java representation of data represented by ABNF rule
+* provided as {@link #value()}. Java representation
+* does not need to be direct,
+* but must retain all information in some, publicly
+* accessible form for consumers.
+* </p>
+* <p>
+* Note that this annotation is used currently only for documentation
+* and does not affect any runtime behaviour.
+* </p>
+*
+*/
+@Documented
+@Retention(RetentionPolicy.SOURCE)
+@interface Rfc6020AbnfRule {
+
+    String[] value();
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RpcStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RpcStatement.java
new file mode 100644 (file)
index 0000000..45cb506
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface RpcStatement extends DeclaredStatement<QName> {
+
+    String getName();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaNodeIdentifier.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaNodeIdentifier.java
new file mode 100644 (file)
index 0000000..bacf0c4
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.QName;
+
+/**
+ * Represents unique path to the every schema node inside the schema node identifier
+ * namespace.
+ *
+ */
+public abstract class SchemaNodeIdentifier implements Immutable {
+    /**
+     * An absolute schema node identifier.
+     */
+    public static final class Absolute extends SchemaNodeIdentifier {
+        private Absolute(final SchemaNodeIdentifier parent, final QName qname) {
+            super(parent, qname);
+        }
+
+        @Override
+        public boolean isAbsolute() {
+            return true;
+        }
+
+        @Override
+        protected SchemaNodeIdentifier createInstance(final SchemaNodeIdentifier parent, final QName qname) {
+            return new Absolute(parent, qname);
+        }
+    }
+
+    /**
+     * A relative schema node identifier.
+     */
+    public static class Relative extends SchemaNodeIdentifier {
+        private Relative(final SchemaNodeIdentifier parent, final QName qname) {
+            super(parent, qname);
+        }
+
+        @Override
+        public boolean isAbsolute() {
+            return false;
+        }
+
+        @Override
+        protected SchemaNodeIdentifier createInstance(final SchemaNodeIdentifier parent, final QName qname) {
+            return new Relative(parent, qname);
+        }
+    }
+
+    @SuppressWarnings("rawtypes")
+    private static final AtomicReferenceFieldUpdater<SchemaNodeIdentifier, ImmutableList> LEGACYPATH_UPDATER =
+            AtomicReferenceFieldUpdater.newUpdater(SchemaNodeIdentifier.class, ImmutableList.class, "legacyPath");
+
+    /**
+     * Shared instance of the conceptual root schema node.
+     */
+    public static final SchemaNodeIdentifier ROOT = new Absolute(null, null);
+
+    /**
+     * Shared instance of the "same" relative schema node.
+     */
+    public static final SchemaNodeIdentifier SAME = new Relative(null, null);
+
+    /**
+     * Parent path.
+     */
+    private final SchemaNodeIdentifier parent;
+
+    /**
+     * This component.
+     */
+    private final QName qname;
+
+    /**
+     * Cached hash code. We can use this since we are immutable.
+     */
+    private final int hash;
+
+    /**
+     * Cached legacy path, filled-in when {@link #getPath()} or {@link #getPathTowardsRoot()}
+     * is invoked.
+     */
+    private volatile ImmutableList<QName> legacyPath;
+
+    private ImmutableList<QName> getLegacyPath() {
+        ImmutableList<QName> ret = legacyPath;
+        if (ret == null) {
+            ret = ImmutableList.copyOf(getPathTowardsRoot()).reverse();
+            LEGACYPATH_UPDATER.lazySet(this, ret);
+        }
+
+        return ret;
+    }
+
+    /**
+     * Returns the complete path to schema node.
+     *
+     * @return list of <code>QName</code> instances which represents complete
+     *         path to schema node
+     *
+     * @deprecated Use {@link #getPathFromRoot()} instead.
+     */
+    @Deprecated
+    public List<QName> getPath() {
+        return getLegacyPath();
+    }
+
+    protected SchemaNodeIdentifier(final SchemaNodeIdentifier parent, final QName qname) {
+        this.parent = parent;
+        this.qname = qname;
+
+        int h = parent == null ? 0 : parent.hashCode();
+        if (qname != null) {
+            h = h * 31 + qname.hashCode();
+        }
+
+        hash = h;
+    }
+
+    /**
+     * Constructs new instance of this class with the concrete path.
+     *
+     * @param path
+     *            list of QName instances which specifies exact path to the
+     *            module node
+     * @param absolute
+     *            boolean value which specifies if the path is absolute or
+     *            relative
+     *
+     * @return A SchemaPath instance.
+     */
+    public static SchemaNodeIdentifier create(final Iterable<QName> path, final boolean absolute) {
+        final SchemaNodeIdentifier parent = absolute ? ROOT : SAME;
+        return parent.createChild(path);
+    }
+
+    /**
+     * Constructs new instance of this class with the concrete path.
+     *
+     * @param absolute
+     *            boolean value which specifies if the path is absolute or
+     *            relative
+     * @param path
+     *            one or more QName instances which specifies exact path to the
+     *            module node
+     *
+     * @return A SchemaPath instance.
+     */
+    public static SchemaNodeIdentifier create(final boolean absolute, final QName... path) {
+        return create(Arrays.asList(path), absolute);
+    }
+
+    /**
+     * Create a new instance.
+     *
+     * @param parent Parent schema node identifier
+     * @param qname next path element
+     * @return A new SchemaPath instance
+     */
+    protected abstract SchemaNodeIdentifier createInstance(SchemaNodeIdentifier parent, QName qname);
+
+    /**
+     * Create a child path based on concatenation of this path and a relative path.
+     *
+     * @param relative Relative path
+     * @return A new child path
+     */
+    public SchemaNodeIdentifier createChild(final Iterable<QName> relative) {
+        if (Iterables.isEmpty(relative)) {
+            return this;
+        }
+
+        SchemaNodeIdentifier parent = this;
+        for (QName qname : relative) {
+            parent = parent.createInstance(parent, qname);
+        }
+
+        return parent;
+    }
+
+    /**
+     * Create a child path based on concatenation of this path and a relative path.
+     *
+     * @param relative Relative SchemaPath
+     * @return A new child path
+     */
+    public SchemaNodeIdentifier createChild(final SchemaNodeIdentifier relative) {
+        Preconditions.checkArgument(!relative.isAbsolute(), "Child creation requires relative path");
+
+        SchemaNodeIdentifier parent = this;
+        for (QName qname : relative.getPathFromRoot()) {
+            parent = parent.createInstance(parent, qname);
+        }
+
+        return parent;
+    }
+
+    /**
+     * Create a child path based on concatenation of this path and additional
+     * path elements.
+     *
+     * @param elements Relative SchemaPath elements
+     * @return A new child path
+     */
+    public SchemaNodeIdentifier createChild(final QName... elements) {
+        return createChild(Arrays.asList(elements));
+    }
+
+    /**
+     * Returns the list of nodes which need to be traversed to get from the
+     * starting point (root for absolute SchemaPaths) to the node represented
+     * by this object.
+     *
+     * @return list of <code>qname</code> instances which represents
+     *         path from the root to the schema node.
+     */
+    public Iterable<QName> getPathFromRoot() {
+        return getLegacyPath();
+    }
+
+    /**
+     * Returns the list of nodes which need to be traversed to get from this
+     * node to the starting point (root for absolute SchemaPaths).
+     *
+     * @return list of <code>qname</code> instances which represents
+     *         path from the schema node towards the root.
+     */
+    public Iterable<QName> getPathTowardsRoot() {
+        return new Iterable<QName>() {
+            @Override
+            public Iterator<QName> iterator() {
+                return new Iterator<QName>() {
+                    private SchemaNodeIdentifier current = SchemaNodeIdentifier.this;
+
+                    @Override
+                    public boolean hasNext() {
+                        return current.parent != null;
+                    }
+
+                    @Override
+                    public QName next() {
+                        if (current.parent != null) {
+                            final QName ret = current.qname;
+                            current = current.parent;
+                            return ret;
+                        } else {
+                            throw new NoSuchElementException("No more elements available");
+                        }
+                    }
+
+                    @Override
+                    public void remove() {
+                        throw new UnsupportedOperationException("Component removal not supported");
+                    }
+                };
+            }
+        };
+    }
+
+    /**
+     * Returns the immediate parent SchemaPath.
+     *
+     * @return Parent path, null if this SchemaPath is already toplevel.
+     */
+    public SchemaNodeIdentifier getParent() {
+        return parent;
+    }
+
+    /**
+     * Get the last component of this path.
+     *
+     * @return The last component of this path.
+     */
+    public final QName getLastComponent() {
+        return qname;
+    }
+
+    /**
+     * Describes whether schema node identifier is|isn't absolute.
+     *
+     * @return boolean value which is <code>true</code> if schema path is
+     *         absolute.
+     */
+    public abstract boolean isAbsolute();
+
+    @Override
+    public final int hashCode() {
+        return hash;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final SchemaNodeIdentifier other = (SchemaNodeIdentifier) obj;
+
+        if (qname != null) {
+            if (!qname.equals(other.qname)) {
+                return false;
+            }
+        } else {
+            if (other.qname != null) {
+                return false;
+            }
+        }
+
+        if (parent == null) {
+            return other.parent == null;
+        }
+        return parent.equals(other.parent);
+    }
+
+    @Override
+    public final String toString() {
+        return addToStringAttributes(Objects.toStringHelper(this)).toString();
+    }
+
+    protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+        return toStringHelper.add("path", getPathFromRoot());
+    }
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/StatusStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/StatusStatement.java
new file mode 100644 (file)
index 0000000..44e8cb6
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface StatusStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getValue();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SubmoduleStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SubmoduleStatement.java
new file mode 100644 (file)
index 0000000..7853c98
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface SubmoduleStatement extends
+    DeclaredStatement<String>,
+    LinkageGroup,
+    MetaGroup,
+    RevisionGroup,
+    BodyGroup {
+
+    @Nonnull String getName();
+
+    @Nullable YangVersionStatement getYangVersion();
+
+    @Nonnull BelongsToStatement getBelongsTo();
+
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeGroup.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeGroup.java
new file mode 100644 (file)
index 0000000..ef72ffd
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+public interface TypeGroup {
+
+    @Nonnull TypeStatement getType();
+
+    @Nullable UnitsStatement getUnits();
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeStatement.java
new file mode 100644 (file)
index 0000000..a89d1da
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+@Rfc6020AbnfRule("type-stmt")
+public interface TypeStatement extends DeclaredStatement<QName> {
+
+    @Nonnull String getName();
+
+    @Rfc6020AbnfRule("numerical-restrictions")
+    interface NumericalRestrictions extends TypeStatement {
+
+        @Nonnull RangeStatement getRange();
+
+    }
+
+    @Rfc6020AbnfRule("decimal64-specification")
+    interface Decimal64Specification extends TypeStatement {
+
+        @Nonnull FractionDigitsStatement getFractionDigits();
+
+        @Nullable RangeStatement getRange();
+
+    }
+
+    @Rfc6020AbnfRule("string-restrictions")
+    interface StringRestrictions extends TypeStatement {
+
+        @Nullable LengthStatement getLength();
+
+        @Nonnull Collection<? extends PatternStatement> getPatterns();
+    }
+
+    @Rfc6020AbnfRule("enum-specification")
+    interface EnumSpecification extends TypeStatement {
+
+        @Nonnull Collection<? extends EnumStatement> getEnums();
+
+    }
+
+    @Rfc6020AbnfRule("leafref-specification")
+    interface LeafrefSpecification extends TypeStatement {
+
+        @Nullable PathStatement getPath();
+
+    }
+
+    interface InstanceIdentifierSpecification extends TypeStatement {
+
+        @Nullable RequireInstanceStatement getRequireInstance();
+    }
+
+
+    interface IdentityRefSpecification extends TypeStatement {
+
+    }
+    interface BitsSpecification extends TypeStatement {
+
+        @Nonnull Collection<? extends BitStatement> getBits();
+
+    }
+
+    interface UnionSpecification extends TypeStatement {
+
+        @Nonnull Collection<? extends TypeStatement> getTypes();
+
+    }
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefStatement.java
new file mode 100644 (file)
index 0000000..eee2f91
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface TypedefStatement extends DeclaredStatement<QName>,DocumentationGroup.WithStatus, TypeGroup {
+
+
+    @Nonnull String getName();
+
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UniqueStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UniqueStatement.java
new file mode 100644 (file)
index 0000000..726b084
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface UniqueStatement extends DeclaredStatement<Collection<SchemaNodeIdentifier.Relative>> {
+
+    @Nonnull Collection<SchemaNodeIdentifier.Relative> getTag();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UnitsStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UnitsStatement.java
new file mode 100644 (file)
index 0000000..116c72a
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+public interface UnitsStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getName();
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UnknownStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UnknownStatement.java
new file mode 100644 (file)
index 0000000..9ec4d1c
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface UnknownStatement<S> extends DeclaredStatement<S> {
+
+    @Nullable String getArgument();
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UsesStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UsesStatement.java
new file mode 100644 (file)
index 0000000..68c0462
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+
+
+
+public interface UsesStatement extends DataDefinitionStatement {
+
+    @Override
+    @Nonnull QName getName();
+
+    @Nonnull Collection<? extends RefineStatement> getRefines();
+
+    @Nonnull Collection<? extends AugmentStatement> getAugments();
+
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ValueStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ValueStatement.java
new file mode 100644 (file)
index 0000000..1d2ef0c
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+public interface ValueStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getValue();
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/WhenStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/WhenStatement.java
new file mode 100644 (file)
index 0000000..df289fb
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface WhenStatement extends DeclaredStatement<RevisionAwareXPath>, DocumentationGroup {
+
+    @Nonnull RevisionAwareXPath getCondition();
+
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/YangVersionStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/YangVersionStatement.java
new file mode 100644 (file)
index 0000000..ff75fee
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface YangVersionStatement extends DeclaredStatement<String> {
+
+}
+
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/YinElementStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/YinElementStatement.java
new file mode 100644 (file)
index 0000000..949e443
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface YinElementStatement extends DeclaredStatement<String> {
+
+    @Nonnull String getValue();
+}
+
index 42b9d3802e137b3f6be5d71cb58ab3833d8ab98b..42c92d58baaaee64c4122badfe4e329c3f0a24eb 100644 (file)
@@ -8,17 +8,14 @@
 package org.opendaylight.yangtools.yang.model.repo.api;
 
 import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.Multimap;
-
 import java.util.Collection;
 import java.util.Collections;
-
 import javax.annotation.Nonnull;
-
 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
 
 /**
@@ -74,7 +71,7 @@ public class SchemaResolutionException extends SchemaSourceException {
 
     @Override
     public final String toString() {
-        return addToStringAttributes(Objects.toStringHelper(this).add("unsatisfiedImports", unsatisfiedImports)).toString();
+        return addToStringAttributes(MoreObjects.toStringHelper(this).add("unsatisfiedImports", unsatisfiedImports)).toString();
     }
 
     protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
index 50ee12ef4d03358729456081c76216a020f5db71..8ae9c287fb1c1c486f5c0a956603e8047e7e329b 100644 (file)
@@ -10,8 +10,8 @@ package org.opendaylight.yangtools.yang.model.repo.api;
 import static com.google.common.base.Preconditions.checkArgument;
 
 import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.io.ByteSource;
@@ -57,7 +57,7 @@ public abstract class YangTextSchemaSource extends ByteSource implements SchemaS
 
     @Override
     public final String toString() {
-        return addToStringAttributes(Objects.toStringHelper(this).add("identifier", identifier)).toString();
+        return addToStringAttributes(MoreObjects.toStringHelper(this).add("identifier", identifier)).toString();
     }
 
     /**
diff --git a/yang/yang-model-export/pom.xml b/yang/yang-model-export/pom.xml
new file mode 100644 (file)
index 0000000..31f8296
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<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">
+
+    <parent>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>yangtools-parent</artifactId>
+        <version>0.7.0-SNAPSHOT</version>
+        <relativePath>/../../common/parent/pom.xml</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>yang-model-export</artifactId>
+    <name>${project.artifactId}</name>
+    <description>${project.artifactId}</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>yang-model-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>yang-model-util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>yang-parser-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>xmlunit</groupId>
+            <artifactId>xmlunit</artifactId>
+            <version>1.5</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedBinary.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedBinary.java
new file mode 100644 (file)
index 0000000..e7da96d
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedBinary extends NormalizatedDerivedType<BinaryTypeDefinition> implements BinaryTypeDefinition {
+
+    public DerivedBinary(final ExtendedType definition) {
+        super(BinaryTypeDefinition.class, definition);
+    }
+
+    @Override
+    BinaryTypeDefinition createDerived(final ExtendedType base) {
+        return new DerivedBinary(base);
+    }
+
+    @Override
+    public List<LengthConstraint> getLengthConstraints() {
+        return delegate().getLengthConstraints();
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedBits.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedBits.java
new file mode 100644 (file)
index 0000000..b9aa628
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedBits extends NormalizatedDerivedType<BitsTypeDefinition> implements BitsTypeDefinition {
+
+    public DerivedBits(final ExtendedType definition) {
+        super(BitsTypeDefinition.class, definition);
+    }
+
+    @Override
+    BitsTypeDefinition createDerived(final ExtendedType base) {
+        return new DerivedBits(base);
+    }
+
+    @Override
+    public List<Bit> getBits() {
+        return getBaseType().getBits();
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedBoolean.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedBoolean.java
new file mode 100644 (file)
index 0000000..4be3ea2
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedBoolean extends NormalizatedDerivedType<BooleanTypeDefinition> implements BooleanTypeDefinition {
+
+    public DerivedBoolean(final ExtendedType definition) {
+        super(BooleanTypeDefinition.class, definition);
+    }
+
+    @Override
+    BooleanTypeDefinition createDerived(final ExtendedType base) {
+        return new DerivedBoolean(base);
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedDecimal.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedDecimal.java
new file mode 100644 (file)
index 0000000..ee2845f
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedDecimal extends NormalizatedDerivedType<DecimalTypeDefinition> implements DecimalTypeDefinition {
+
+    public DerivedDecimal(final ExtendedType definition) {
+        super(DecimalTypeDefinition.class, definition);
+    }
+
+    @Override
+    DecimalTypeDefinition createDerived(final ExtendedType base) {
+        return new DerivedDecimal(base);
+    }
+
+    @Override
+    public List<RangeConstraint> getRangeConstraints() {
+        return delegate().getRangeConstraints();
+    }
+
+    @Override
+    public Integer getFractionDigits() {
+        return delegate().getFractionDigits();
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedEnum.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedEnum.java
new file mode 100644 (file)
index 0000000..c030eed
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedEnum extends NormalizatedDerivedType<EnumTypeDefinition> implements EnumTypeDefinition {
+
+    public DerivedEnum(final ExtendedType definition) {
+        super(EnumTypeDefinition.class, definition);
+    }
+
+    @Override
+    EnumTypeDefinition createDerived(final ExtendedType base) {
+        return new DerivedEnum(base);
+    }
+
+    @Override
+    public List<EnumPair> getValues() {
+        return getBaseType().getValues();
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedIdentityref.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedIdentityref.java
new file mode 100644 (file)
index 0000000..c17cf58
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedIdentityref extends NormalizatedDerivedType<IdentityrefTypeDefinition> implements
+        IdentityrefTypeDefinition {
+
+    public DerivedIdentityref(final ExtendedType definition) {
+        super(IdentityrefTypeDefinition.class, definition);
+    }
+
+    @Override
+    IdentityrefTypeDefinition createDerived(final ExtendedType base) {
+        return new DerivedIdentityref(base);
+    }
+
+    @Override
+    public IdentitySchemaNode getIdentity() {
+        // FIXME: Is this really correct?
+        return getBaseType().getIdentity();
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedInstanceIdentifier.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedInstanceIdentifier.java
new file mode 100644 (file)
index 0000000..1a065b5
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedInstanceIdentifier extends NormalizatedDerivedType<InstanceIdentifierTypeDefinition> implements
+        InstanceIdentifierTypeDefinition {
+
+    public DerivedInstanceIdentifier(final ExtendedType definition) {
+        super(InstanceIdentifierTypeDefinition.class, definition);
+    }
+
+    @Override
+    InstanceIdentifierTypeDefinition createDerived(final ExtendedType base) {
+        return new DerivedInstanceIdentifier(base);
+    }
+
+    @Override
+    public RevisionAwareXPath getPathStatement() {
+        throw new UnsupportedOperationException("Path statement is not part of instance-identifier type");
+    }
+
+    @Override
+    public boolean requireInstance() {
+        return getBaseType().requireInstance();
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedInteger.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedInteger.java
new file mode 100644 (file)
index 0000000..3709820
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedInteger extends NormalizatedDerivedType<IntegerTypeDefinition> implements IntegerTypeDefinition {
+
+    public DerivedInteger(final ExtendedType definition) {
+        super(IntegerTypeDefinition.class, definition);
+    }
+
+    @Override
+    IntegerTypeDefinition createDerived(final ExtendedType base) {
+        return new DerivedInteger(base);
+    }
+
+    @Override
+    public List<RangeConstraint> getRangeConstraints() {
+        return delegate().getRangeConstraints();
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedLeafref.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedLeafref.java
new file mode 100644 (file)
index 0000000..e582956
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedLeafref extends NormalizatedDerivedType<LeafrefTypeDefinition> implements LeafrefTypeDefinition {
+
+    public DerivedLeafref(final ExtendedType definition) {
+        super(LeafrefTypeDefinition.class, definition);
+    }
+
+    @Override
+    LeafrefTypeDefinition createDerived(final ExtendedType base) {
+        return new DerivedLeafref(base);
+    }
+
+    @Override
+    public RevisionAwareXPath getPathStatement() {
+        return getBaseType().getPathStatement();
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedString.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedString.java
new file mode 100644 (file)
index 0000000..462092e
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+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.StringTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedString extends NormalizatedDerivedType<StringTypeDefinition> implements StringTypeDefinition {
+
+    public DerivedString(final ExtendedType definition) {
+        super(StringTypeDefinition.class, definition);
+    }
+
+    @Override
+    StringTypeDefinition createDerived(final ExtendedType base) {
+        return new DerivedString(base);
+    }
+
+    @Override
+    public List<LengthConstraint> getLengthConstraints() {
+        return delegate().getLengthConstraints();
+    }
+
+    @Override
+    public List<PatternConstraint> getPatternConstraints() {
+        return delegate().getPatternConstraints();
+    }
+
+
+}
\ No newline at end of file
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedUnion.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedUnion.java
new file mode 100644 (file)
index 0000000..76da06f
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedUnion extends NormalizatedDerivedType<UnionTypeDefinition> implements UnionTypeDefinition {
+
+    public DerivedUnion(final ExtendedType definition) {
+        super(UnionTypeDefinition.class, definition);
+    }
+
+    @Override
+    UnionTypeDefinition createDerived(final ExtendedType base) {
+        return new DerivedUnion(base);
+    }
+
+    @Override
+    public List<TypeDefinition<?>> getTypes() {
+        return getBaseType().getTypes();
+    }
+
+}
\ No newline at end of file
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedUnsignedInteger.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/DerivedUnsignedInteger.java
new file mode 100644 (file)
index 0000000..5b531a7
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
+import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedUnsignedInteger extends NormalizatedDerivedType<UnsignedIntegerTypeDefinition> implements
+        UnsignedIntegerTypeDefinition {
+
+    public DerivedUnsignedInteger(final ExtendedType definition) {
+        super(UnsignedIntegerTypeDefinition.class, definition);
+    }
+
+    @Override
+    UnsignedIntegerTypeDefinition createDerived(final ExtendedType base) {
+        return new DerivedUnsignedInteger(base);
+    }
+
+    @Override
+    public List<RangeConstraint> getRangeConstraints() {
+        return delegate().getRangeConstraints();
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/ExtensionStatement.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/ExtensionStatement.java
new file mode 100644 (file)
index 0000000..16b195e
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+
+final class ExtensionStatement implements StatementDefinition {
+
+    private QName argumentName;
+    private QName statementName;
+    private boolean yinElement;
+
+    private ExtensionStatement(final ExtensionDefinition def) {
+        statementName = def.getQName();
+        argumentName = def.getArgument() != null ? QName.create(statementName, def.getArgument()) : null;
+        yinElement = def.isYinElement();
+    }
+
+    static StatementDefinition from(final ExtensionDefinition def) {
+        return new ExtensionStatement(def);
+    }
+
+    static Map<QName,StatementDefinition> mapFrom(final Collection<ExtensionDefinition> definitions) {
+        final HashMap<QName,StatementDefinition> ret = new HashMap<>(definitions.size());
+        for(final ExtensionDefinition def : definitions) {
+            final StatementDefinition value = from(def);
+            ret.put(value.getStatementName(), value);
+        }
+        return ret;
+    }
+
+    @Override
+    public QName getArgumentName() {
+        return argumentName;
+    }
+
+    @Override
+    public QName getStatementName() {
+        return statementName;
+    }
+
+    public boolean isArgumentYinElement() {
+        return yinElement;
+    }
+
+    @Override
+    public Class<? extends DeclaredStatement<?>> getDeclaredRepresentationClass() {
+        throw new UnsupportedOperationException("Not defined");
+    }
+
+    @Override
+    public Class<? extends DeclaredStatement<?>> getEffectiveRepresentationClass() {
+        throw new UnsupportedOperationException("Not defined");
+    }
+
+}
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/NormalizatedDerivedType.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/NormalizatedDerivedType.java
new file mode 100644 (file)
index 0000000..760e0df
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import com.google.common.base.Preconditions;
+import java.util.List;
+import org.opendaylight.yangtools.yang.common.QName;
+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.BinaryTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+/**
+ *
+ * Implementations of derived type.
+ *
+ * This is set of utility classes which implements derived YANG type,
+ * preserving original implemented interface instead of {@link ExtendedType}
+ * which does not preserve final type of data.
+ *
+ *  FIXME: Lithium: Should be move to yang-model-util package or deprecated
+ * if linking parser is reworked to adhere to base type contract
+ */
+abstract class NormalizatedDerivedType<T extends TypeDefinition<T>> implements TypeDefinition<T> {
+
+    private final ExtendedType definition;
+    private final Class<T> publicType;
+
+    NormalizatedDerivedType(final Class<T> publicType, final ExtendedType delegate) {
+        this.definition = Preconditions.checkNotNull(delegate);
+        this.publicType = Preconditions.checkNotNull(publicType);
+    }
+
+    static TypeDefinition<?> from(final ExtendedType type) {
+        TypeDefinition<? extends TypeDefinition<?>> baseType = type;
+        while (baseType.getBaseType() != null) {
+            baseType = baseType.getBaseType();
+        }
+        if (baseType instanceof BinaryTypeDefinition) {
+            return new DerivedBinary(type);
+        }
+        if (baseType instanceof BooleanTypeDefinition) {
+            return new DerivedBoolean(type);
+        }
+        if (baseType instanceof DecimalTypeDefinition) {
+            return new DerivedDecimal(type);
+        }
+        if (baseType instanceof IdentityrefTypeDefinition) {
+            return new DerivedIdentityref(type);
+        }
+        if (baseType instanceof InstanceIdentifierTypeDefinition) {
+            return new DerivedInstanceIdentifier(type);
+        }
+        if (baseType instanceof IntegerTypeDefinition) {
+            return new DerivedInteger(type);
+        }
+        if (baseType instanceof LeafrefTypeDefinition) {
+            return new DerivedLeafref(type);
+        }
+        if (baseType instanceof UnsignedIntegerTypeDefinition) {
+            return new DerivedUnsignedInteger(type);
+        }
+        if (baseType instanceof StringTypeDefinition) {
+            return new DerivedString(type);
+        }
+        if(baseType instanceof UnionTypeDefinition) {
+            return new DerivedUnion(type);
+        }
+        if(baseType instanceof EnumTypeDefinition) {
+            return new DerivedEnum(type);
+        }
+        if(baseType instanceof BitsTypeDefinition) {
+            return new DerivedBits(type);
+        }
+        throw new IllegalArgumentException("Not supported base type of " + baseType.getClass());
+    }
+
+    @Override
+    public final QName getQName() {
+        return definition.getQName();
+    }
+
+    @Override
+    public final SchemaPath getPath() {
+        return definition.getPath();
+    }
+
+    @Override
+    public final List<UnknownSchemaNode> getUnknownSchemaNodes() {
+        return definition.getUnknownSchemaNodes();
+    }
+
+    @Override
+    public final String getDescription() {
+        return definition.getDescription();
+    }
+
+    @Override
+    public final String getReference() {
+        return definition.getReference();
+    }
+
+    @Override
+    public final String getUnits() {
+        return definition.getUnits();
+    }
+
+    @Override
+    public final Object getDefaultValue() {
+        return definition.getDefaultValue();
+    }
+
+    @Override
+    public final Status getStatus() {
+        return definition.getStatus();
+    }
+
+    @Override
+    public final T getBaseType() {
+        final TypeDefinition<?> base = definition.getBaseType();
+        if (publicType.isInstance(base)) {
+            return publicType.cast(base);
+        } else if (base instanceof ExtendedType) {
+            return createDerived((ExtendedType) base);
+        }
+        throw new IllegalStateException("Unsupported base type.");
+    }
+
+    protected ExtendedType delegate() {
+        return definition;
+    }
+
+    /**
+     *
+     * Creates derived type from supplied ExtendedType, which will implement
+     * proper {@link TypeDefinition} interface.
+     *
+     * @param base Base definition, which does not implement concrete API
+     * @return wrapper which implements proper subinterface of {@link TypeDefinition}.
+     */
+    abstract T createDerived(ExtendedType base);
+}
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/Rfc6020ModuleWriter.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/Rfc6020ModuleWriter.java
new file mode 100644 (file)
index 0000000..9c1444a
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import com.google.common.primitives.UnsignedInteger;
+import java.net.URI;
+import java.util.Date;
+import java.util.List;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+
+interface Rfc6020ModuleWriter {
+
+    void endNode();
+
+    void startModuleNode(String identifier);
+
+    void startOrganizationNode(String input);
+
+    void startContactNode(String input);
+
+    void startDescriptionNode(String input);
+
+    void startUnitsNode(String input);
+
+    void startYangVersionNode(String input);
+
+    void startNamespaceNode(URI uri);
+
+    void startKeyNode(List<QName> keyList);
+
+    void startPrefixNode(String input);
+
+    void startFeatureNode(QName qName);
+
+    void startExtensionNode(QName qName);
+
+    void startArgumentNode(String input);
+
+    void startStatusNode(Status status);
+
+    void startTypeNode(QName qName);
+
+    void startLeafNode(QName qName);
+
+    void startContainerNode(QName qName);
+
+    void startGroupingNode(QName qName);
+
+    void startRpcNode(QName qName);
+
+    void startInputNode();
+
+    void startOutputNode();
+
+    void startLeafListNode(QName qName);
+
+    void startListNode(QName qName);
+
+    void startChoiceNode(QName qName);
+
+    void startCaseNode(QName qName);
+
+    void startNotificationNode(QName qName);
+
+    void startIdentityNode(QName qName);
+
+    void startBaseNode(QName qName);
+
+    void startTypedefNode(QName qName);
+
+    void startRevisionNode(Date date);
+
+    void startDefaultNode(String string);
+
+    void startMustNode(RevisionAwareXPath xpath);
+
+    void startErrorMessageNode(String input);
+
+    void startErrorAppTagNode(String input);
+
+    void startPatternNode(String regularExpression);
+
+    void startValueNode(Integer integer);
+
+    void startEnumNode(String name);
+
+    void startRequireInstanceNode(boolean require);
+
+    void startPathNode(RevisionAwareXPath revisionAwareXPath);
+
+    void startBitNode(String name);
+
+    void startPositionNode(UnsignedInteger position);
+
+    void startReferenceNode(String input);
+
+    void startRevisionDateNode(Date date);
+
+    void startImportNode(String moduleName);
+
+    void startUsesNode(QName groupingName);
+
+    void startAugmentNode(SchemaPath targetPath);
+
+    void startConfigNode(boolean config);
+
+    void startLengthNode(String lengthString);
+
+    void startMaxElementsNode(Integer max);
+
+    void startMinElementsNode(Integer min);
+
+    void startPresenceNode(boolean presence);
+
+    void startOrderedByNode(String ordering);
+
+    void startRangeNode(String rangeString);
+
+    void startRefineNode(SchemaPath path);
+
+    void startMandatoryNode(boolean mandatory);
+
+    void startAnyxmlNode(QName qName);
+
+    void startUnknownNode(StatementDefinition def);
+
+    void startUnknownNode(StatementDefinition def, String nodeParameter);
+
+    void startFractionDigitsNode(Integer fractionDigits);
+
+    void startYinElementNode(boolean yinElement);
+
+    void startWhenNode(RevisionAwareXPath revisionAwareXPath);
+
+}
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/SchemaContextEmitter.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/SchemaContextEmitter.java
new file mode 100644 (file)
index 0000000..6ef96bf
--- /dev/null
@@ -0,0 +1,1206 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.primitives.UnsignedInteger;
+import java.net.URI;
+import java.util.Date;
+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 javax.annotation.Nullable;
+import javax.annotation.concurrent.NotThreadSafe;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
+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.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Deviation;
+import org.opendaylight.yangtools.yang.model.api.DocumentedNode;
+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.LeafListSchemaNode;
+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.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.MustDefinition;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+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.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.UsesNode;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
+import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+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.api.type.StringTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
+
+@Beta
+@NotThreadSafe
+class SchemaContextEmitter {
+
+    private final Rfc6020ModuleWriter writer;
+    private final boolean emitInstantiated;
+    private final boolean emitUses;
+    private final Map<QName, StatementDefinition> extensions;
+
+    SchemaContextEmitter(final Rfc6020ModuleWriter writer, final Map<QName, StatementDefinition> extensions) {
+        this(writer, extensions,false, true);
+    }
+
+    SchemaContextEmitter(final Rfc6020ModuleWriter writer, final Map<QName, StatementDefinition> extensions, final boolean emitInstantiated, final boolean emitUses) {
+        this.writer = Preconditions.checkNotNull(writer);
+        this.emitInstantiated = emitInstantiated;
+        this.emitUses = emitUses;
+        this.extensions = Preconditions.checkNotNull(extensions);
+    }
+
+    static void writeToStatementWriter(final Module module, final SchemaContext ctx, final StatementTextWriter statementWriter) {
+        final Rfc6020ModuleWriter yangSchemaWriter = SchemaToStatementWriterAdaptor.from(statementWriter);
+        final Map<QName, StatementDefinition> extensions = ExtensionStatement.mapFrom(ctx.getExtensions());
+        new SchemaContextEmitter(yangSchemaWriter,extensions).emitModule(module);
+    }
+
+    void emitModule(final Module input) {
+        writer.startModuleNode(input.getName());
+        emitModuleHeader(input);
+        emitLinkageNodes(input);
+        emitMetaNodes(input);
+        emitRevisionNodes(input);
+        emitBodyNodes(input);
+        writer.endNode();
+    }
+
+    private void emitModuleHeader(final Module input) {
+        emitYangVersionNode(input.getYangVersion());
+        emitNamespace(input.getNamespace());
+        emitPrefixNode(input.getPrefix());
+    }
+
+    @SuppressWarnings("unused")
+    private void emitSubmodule(final String input) {
+        /*
+         * FIXME: BUG-2444:  Implement submodule export
+         *
+         * submoduleHeaderNodes linkageNodes metaNodes revisionNodes bodyNodes
+         * writer.endNode();
+         */
+    }
+
+    @SuppressWarnings("unused")
+    private void emitSubmoduleHeaderNodes(final Module input) {
+        /*
+         * FIXME: BUG-2444:  Implement submodule headers properly
+         *
+         * :yangVersionNode //Optional
+         *
+         * :belongsToNode
+         */
+    }
+
+    private void emitMetaNodes(final Module input) {
+
+        emitOrganizationNode(input.getOrganization()); // FIXME: BUG-2444: Optional
+        emitContact(input.getContact()); // FIXME: BUG-2444: Optional
+        emitDescriptionNode(input.getDescription());
+        emitReferenceNode(input.getReference());
+    }
+
+    private void emitLinkageNodes(final Module input) {
+        for (final ModuleImport importNode : input.getImports()) {
+            emitImport(importNode);
+        }
+        /*
+         * FIXME: BUG-2444:  Emit include statements
+         */
+    }
+
+    private void emitRevisionNodes(final Module input) {
+        /*
+         * FIXME: BUG-2444:  emit revisions properly, when parsed model will provide enough
+         * information
+         */
+        emitRevision(input.getRevision());
+
+    }
+
+    private void emitBodyNodes(final Module input) {
+
+        for (final ExtensionDefinition extension : input.getExtensionSchemaNodes()) {
+            emitExtension(extension);
+        }
+        for (final FeatureDefinition definition : input.getFeatures()) {
+            emitFeature(definition);
+        }
+        for (final IdentitySchemaNode identity : input.getIdentities()) {
+            emitIdentity(identity);
+        }
+
+        emitDataNodeContainer(input);
+
+        for (final AugmentationSchema augmentation : input.getAugmentations()) {
+            emitAugment(augmentation);
+        }
+        for (final RpcDefinition rpc : input.getRpcs()) {
+            emitRpc(rpc);
+        }
+        for (final NotificationDefinition notification : input.getNotifications()) {
+            emitNotificationNode(notification);
+        }
+        for (final Deviation deviation : input.getDeviations()) {
+            emitDeviation(deviation);
+        }
+
+    }
+
+    private void emitDataNodeContainer(final DataNodeContainer input) {
+        for (final TypeDefinition<?> typedef : input.getTypeDefinitions()) {
+            emitTypedefNode(typedef);
+        }
+        for (final GroupingDefinition grouping : input.getGroupings()) {
+            emitGrouping(grouping);
+        }
+        for (final DataSchemaNode child : input.getChildNodes()) {
+            emitDataSchemaNode(child);
+        }
+        for (final UsesNode usesNode : input.getUses()) {
+            emitUsesNode(usesNode);
+        }
+    }
+
+    private void emitDataSchemaNode(final DataSchemaNode child) {
+        if (!emitInstantiated && (child.isAddedByUses() || child.isAugmenting())) {
+            // We skip instantiated nodes.
+            return;
+        }
+
+        if (child instanceof ContainerSchemaNode) {
+            emitContainer((ContainerSchemaNode) child);
+        } else if (child instanceof LeafSchemaNode) {
+            emitLeaf((LeafSchemaNode) child);
+        } else if (child instanceof LeafListSchemaNode) {
+            emitLeafList((LeafListSchemaNode) child);
+        } else if (child instanceof ListSchemaNode) {
+            emitList((ListSchemaNode) child);
+        } else if (child instanceof ChoiceNode) {
+            emitChoice((ChoiceNode) child);
+        } else if (child instanceof AnyXmlSchemaNode) {
+            emitAnyxml((AnyXmlSchemaNode) child);
+        } else {
+            throw new UnsupportedOperationException("Not supported DataSchemaNode type " + child.getClass());
+        }
+    }
+
+    private void emitYangVersionNode(final String input) {
+        writer.startYangVersionNode(input);
+        writer.endNode();
+    }
+
+    private void emitImport(final ModuleImport importNode) {
+        writer.startImportNode(importNode.getModuleName());
+        emitPrefixNode(importNode.getPrefix());
+        emitRevisionDateNode(importNode.getRevision());
+        writer.endNode();
+    }
+
+    @SuppressWarnings("unused")
+    private void emitInclude(final String input) {
+        /*
+         * FIXME: BUG-2444:  Implement proper export of include statements
+         * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
+         *
+         *
+         * :revisionDateNode :writer.endNode();)
+         */
+    }
+
+    private void emitNamespace(final URI uri) {
+        writer.startNamespaceNode(uri);
+        writer.endNode();
+
+    }
+
+    private void emitPrefixNode(final String input) {
+        writer.startPrefixNode(input);
+        writer.endNode();
+
+    }
+
+    @SuppressWarnings("unused")
+    private void emitBelongsTo(final String input) {
+        /*
+         * FIXME: BUG-2444:  Implement proper export of belongs-to statements
+         * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
+         *
+         *
+         * :writer.startBelongsToNode(IdentifierHelper.getIdentifier(String
+         * :input));
+         *
+         *
+         * :prefixNode
+         * :writer.endNode();
+         *
+         */
+
+    }
+
+    private void emitOrganizationNode(final String input) {
+        writer.startOrganizationNode(input);
+        writer.endNode();
+
+    }
+
+    private void emitContact(final String input) {
+        writer.startContactNode(input);
+        writer.endNode();
+
+    }
+
+    private void emitDescriptionNode(@Nullable final String input) {
+        if (!Strings.isNullOrEmpty(input)) {
+            writer.startDescriptionNode(input);
+            writer.endNode();
+        }
+    }
+
+    private void emitReferenceNode(@Nullable final String input) {
+        if (!Strings.isNullOrEmpty(input)) {
+            writer.startReferenceNode(input);
+            writer.endNode();
+        }
+    }
+
+    private void emitUnitsNode(@Nullable final String input) {
+        if (!Strings.isNullOrEmpty(input)) {
+            writer.startUnitsNode(input);
+            writer.endNode();
+        }
+    }
+
+    private void emitRevision(final Date date) {
+        writer.startRevisionNode(date);
+
+        //
+        // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: descriptionNode //FIXME: BUG-2444: Optional
+        // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: referenceNode //FIXME: BUG-2444: Optional
+        writer.endNode();
+
+    }
+
+    private void emitRevisionDateNode(@Nullable final Date date) {
+        if (date != null) {
+            writer.startRevisionDateNode(date);
+            writer.endNode();
+        }
+    }
+
+    private void emitExtension(final ExtensionDefinition extension) {
+        writer.startExtensionNode(extension.getQName());
+        emitArgument(extension.getArgument(),extension.isYinElement());
+        emitStatusNode(extension.getStatus());
+        emitDescriptionNode(extension.getDescription());
+        emitReferenceNode(extension.getReference());
+        emitUnknownStatementNodes(extension.getUnknownSchemaNodes());
+        writer.endNode();
+
+    }
+
+    private void emitArgument(final @Nullable String input, final boolean yinElement) {
+        if (input != null) {
+            writer.startArgumentNode(input);
+            emitYinElement(yinElement);
+            writer.endNode();
+        }
+
+    }
+
+    private void emitYinElement(final boolean yinElement) {
+        writer.startYinElementNode(yinElement);
+        writer.endNode();
+
+    }
+
+    private void emitIdentity(final IdentitySchemaNode identity) {
+        writer.startIdentityNode(identity.getQName());
+        if (identity.getBaseIdentity() != null) {
+            emitBase(identity.getBaseIdentity().getQName());
+        }
+        emitStatusNode(identity.getStatus());
+        emitDescriptionNode(identity.getDescription());
+        emitReferenceNode(identity.getReference());
+        writer.endNode();
+
+    }
+
+    private void emitBase(final QName qName) {
+        writer.startBaseNode(qName);
+        writer.endNode();
+
+    }
+
+    private void emitFeature(final FeatureDefinition definition) {
+        writer.startFeatureNode(definition.getQName());
+
+        // FIXME: BUG-2444: FIXME: BUG-2444:  Expose ifFeature *(ifFeatureNode )
+        emitStatusNode(definition.getStatus());
+        emitDescriptionNode(definition.getDescription());
+        emitReferenceNode(definition.getReference());
+        writer.endNode();
+
+    }
+
+    @SuppressWarnings("unused")
+    private void emitIfFeature(final String input) {
+        /*
+         * FIXME: BUG-2444:  Implement proper export of include statements
+         * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
+         *
+         */
+    }
+
+    private void emitTypedefNode(final TypeDefinition<?> typedef) {
+        writer.startTypedefNode(typedef.getQName());
+        // Differentiate between derived type and existing type
+        // name.
+        emitTypeNodeDerived(typedef);
+        emitUnitsNode(typedef.getUnits());
+        emitDefaultNode(typedef.getDefaultValue());
+        emitStatusNode(typedef.getStatus());
+        emitDescriptionNode(typedef.getDescription());
+        emitReferenceNode(typedef.getReference());
+        emitUnknownStatementNodes(typedef.getUnknownSchemaNodes());
+        writer.endNode();
+
+    }
+
+    private void emitTypeNode(final SchemaPath parentPath, final TypeDefinition<?> subtype) {
+        final SchemaPath path = subtype.getPath();
+        if (isPrefix(parentPath.getPathFromRoot(), path.getPathFromRoot())) {
+            emitTypeNodeDerived(subtype);
+        } else {
+            emitTypeNodeReferenced(subtype);
+        }
+    }
+
+    private void emitTypeNodeReferenced(final TypeDefinition<?> typeDefinition) {
+        writer.startTypeNode(typeDefinition.getQName());
+        writer.endNode();
+
+    }
+
+    private void emitTypeNodeDerived(final TypeDefinition<?> typeDefinition) {
+        final TypeDefinition<?> baseType;
+        if (typeDefinition.getBaseType() != null) {
+            baseType = typeDefinition.getBaseType();
+        } else {
+            baseType = typeDefinition;
+        }
+        writer.startTypeNode(baseType.getQName());
+        emitTypeBodyNodes(typeDefinition);
+        writer.endNode();
+
+    }
+
+    private void emitTypeBodyNodes(final TypeDefinition<?> typeDef) {
+        if (typeDef instanceof ExtendedType) {
+            emitTypeBodyNodes(NormalizatedDerivedType.from((ExtendedType) typeDef));
+        } else if (typeDef instanceof UnsignedIntegerTypeDefinition) {
+            emitUnsignedIntegerSpecification((UnsignedIntegerTypeDefinition) typeDef);
+        } else if (typeDef instanceof IntegerTypeDefinition) {
+            emitIntegerSpefication((IntegerTypeDefinition) typeDef);
+        } else if (typeDef instanceof DecimalTypeDefinition) {
+            emitDecimal64Specification((DecimalTypeDefinition) typeDef);
+        } else if (typeDef instanceof StringTypeDefinition) {
+            emitStringRestrictions((StringTypeDefinition) typeDef);
+        } else if (typeDef instanceof EnumTypeDefinition) {
+            emitEnumSpecification((EnumTypeDefinition) typeDef);
+        } else if (typeDef instanceof LeafrefTypeDefinition) {
+            emitLeafrefSpecification((LeafrefTypeDefinition) typeDef);
+        } else if (typeDef instanceof IdentityrefTypeDefinition) {
+            emitIdentityrefSpecification((IdentityrefTypeDefinition) typeDef);
+        } else if (typeDef instanceof InstanceIdentifierTypeDefinition) {
+            emitInstanceIdentifierSpecification((InstanceIdentifierTypeDefinition) typeDef);
+        } else if (typeDef instanceof BitsTypeDefinition) {
+            emitBitsSpecification((BitsTypeDefinition) typeDef);
+        } else if (typeDef instanceof UnionTypeDefinition) {
+            emitUnionSpecification((UnionTypeDefinition) typeDef);
+        } else if (typeDef instanceof BinaryTypeDefinition) {
+            // FIXME: BUG-2444:  Is this realy NOOP?
+            // should at least support length statement
+        } else if (typeDef instanceof BooleanTypeDefinition || typeDef instanceof EmptyTypeDefinition) {
+            // NOOP
+        } else {
+            throw new IllegalArgumentException("Not supported type " + typeDef.getClass());
+        }
+    }
+
+    private void emitIntegerSpefication(final IntegerTypeDefinition typeDef) {
+        emitRangeNodeOptional(typeDef.getRangeConstraints());
+    }
+
+    private void emitUnsignedIntegerSpecification(final UnsignedIntegerTypeDefinition typeDef) {
+        emitRangeNodeOptional(typeDef.getRangeConstraints());
+
+    }
+
+    private void emitRangeNodeOptional(final List<RangeConstraint> list) {
+        // FIXME: BUG-2444:  Wrong decomposition in API, should be LenghtConstraint
+        // which contains ranges.
+        if (!list.isEmpty()) {
+            writer.startRangeNode(toRangeString(list));
+            final RangeConstraint first = list.iterator().next();
+            emitErrorMessageNode(first.getErrorMessage());
+            emitErrorAppTagNode(first.getErrorAppTag());
+            emitDescriptionNode(first.getDescription());
+            emitReferenceNode(first.getReference());
+            writer.endNode();
+        }
+
+    }
+
+    private void emitDecimal64Specification(final DecimalTypeDefinition typeDefinition) {
+        emitFranctionDigitsNode(typeDefinition.getFractionDigits());
+        emitRangeNodeOptional(typeDefinition.getRangeConstraints());
+
+    }
+
+    private void emitFranctionDigitsNode(final Integer fractionDigits) {
+        writer.startFractionDigitsNode(fractionDigits);
+        writer.endNode();
+    }
+
+    private void emitStringRestrictions(final StringTypeDefinition typeDef) {
+
+        // FIXME: BUG-2444:  Wrong decomposition in API, should be LenghtConstraint
+        // which contains ranges.
+        emitLength(typeDef.getLengthConstraints());
+
+        for (final PatternConstraint pattern : typeDef.getPatternConstraints()) {
+            emitPatternNode(pattern);
+        }
+
+    }
+
+    private void emitLength(final List<LengthConstraint> list) {
+        if (!list.isEmpty()) {
+            writer.startLengthNode(toLengthString(list));
+            // FIXME: BUG-2444:  Workaround for incorrect decomposition in API
+            final LengthConstraint first = list.iterator().next();
+            emitErrorMessageNode(first.getErrorMessage());
+            emitErrorAppTagNode(first.getErrorAppTag());
+            emitDescriptionNode(first.getDescription());
+            emitReferenceNode(first.getReference());
+            writer.endNode();
+        }
+
+    }
+
+    private String toLengthString(final List<LengthConstraint> list) {
+        final StringBuilder lengthStr = new StringBuilder();
+        final Iterator<LengthConstraint> constIt = list.iterator();
+        while (constIt.hasNext()) {
+            final LengthConstraint current = constIt.next();
+            if (current.getMin() == current.getMax()) {
+                lengthStr.append(current.getMin());
+            } else {
+                lengthStr.append(current.getMin());
+                lengthStr.append("..");
+                lengthStr.append(current.getMax());
+            }
+            if (constIt.hasNext()) {
+                lengthStr.append("|");
+            }
+        }
+        return lengthStr.toString();
+    }
+
+    private String toRangeString(final List<RangeConstraint> list) {
+        final StringBuilder lengthStr = new StringBuilder();
+        final Iterator<RangeConstraint> constIt = list.iterator();
+        while (constIt.hasNext()) {
+            final RangeConstraint current = constIt.next();
+            if (current.getMin() == current.getMax()) {
+                lengthStr.append(current.getMin());
+            } else {
+                lengthStr.append(current.getMin());
+                lengthStr.append("..");
+                lengthStr.append(current.getMax());
+            }
+            if (constIt.hasNext()) {
+                lengthStr.append("|");
+            }
+        }
+        return lengthStr.toString();
+    }
+
+    private void emitPatternNode(final PatternConstraint pattern) {
+        writer.startPatternNode(pattern.getRegularExpression());
+        emitErrorMessageNode(pattern.getErrorMessage()); // FIXME: BUG-2444: Optional
+        emitErrorAppTagNode(pattern.getErrorAppTag()); // FIXME: BUG-2444: Optional
+        emitDescriptionNode(pattern.getDescription());
+        emitReferenceNode(pattern.getReference()); // FIXME: BUG-2444: Optional
+        writer.endNode();
+    }
+
+    private void emitDefaultNode(@Nullable final Object object) {
+        if (object != null) {
+            writer.startDefaultNode(object.toString());
+            writer.endNode();
+        }
+
+    }
+
+    private void emitEnumSpecification(final EnumTypeDefinition typeDefinition) {
+        for (final EnumPair enumValue : typeDefinition.getValues()) {
+            emitEnumNode(enumValue);
+        }
+    }
+
+    private void emitEnumNode(final EnumPair enumValue) {
+        writer.startEnumNode(enumValue.getName());
+        emitValueNode(enumValue.getValue());
+        emitStatusNode(enumValue.getStatus());
+        emitDescriptionNode(enumValue.getDescription());
+        emitReferenceNode(enumValue.getReference());
+        writer.endNode();
+    }
+
+    private void emitLeafrefSpecification(final LeafrefTypeDefinition typeDefinition) {
+        emitPathNode(typeDefinition.getPathStatement());
+        // FIXME: BUG-2444: requireInstanceNode /Optional removed with (RFC6020 - Errata ID
+        // 2949)
+        // Added in Yang 1.1
+    }
+
+    private void emitPathNode(final RevisionAwareXPath revisionAwareXPath) {
+        writer.startPathNode(revisionAwareXPath);
+        writer.endNode();
+    }
+
+    private void emitRequireInstanceNode(final boolean require) {
+        writer.startRequireInstanceNode(require);
+        writer.endNode();
+    }
+
+    private void emitInstanceIdentifierSpecification(final InstanceIdentifierTypeDefinition typeDefinition) {
+        emitRequireInstanceNode(typeDefinition.requireInstance());
+    }
+
+    private void emitIdentityrefSpecification(final IdentityrefTypeDefinition typeDefinition) {
+        emitBase(typeDefinition.getQName());
+    }
+
+    private void emitUnionSpecification(final UnionTypeDefinition typeDefinition) {
+        for (final TypeDefinition<?> subtype : typeDefinition.getTypes()) {
+            // FIXME: BUG-2444:  What if we have locally modified types here?
+            // is solution to look-up in schema path?
+            emitTypeNode(typeDefinition.getPath(), subtype);
+        }
+    }
+
+    private void emitBitsSpecification(final BitsTypeDefinition typeDefinition) {
+        for (final Bit bit : typeDefinition.getBits()) {
+            emitBit(bit);
+        }
+    }
+
+    private void emitBit(final Bit bit) {
+        writer.startBitNode(bit.getName());
+        emitPositionNode(bit.getPosition());
+        emitStatusNode(bit.getStatus());
+        emitDescriptionNode(bit.getDescription());
+        emitReferenceNode(bit.getReference());
+        writer.endNode();
+    }
+
+    private void emitPositionNode(@Nullable final Long position) {
+        if (position != null) {
+            writer.startPositionNode(UnsignedInteger.valueOf(position));
+            writer.endNode();
+        }
+    }
+
+    private void emitStatusNode(@Nullable final Status status) {
+        if (status != null) {
+            writer.startStatusNode(status);
+            writer.endNode();
+        }
+    }
+
+    private void emitConfigNode(final boolean config) {
+        writer.startConfigNode(config);
+        writer.endNode();
+    }
+
+    private void emitMandatoryNode(final boolean mandatory) {
+        writer.startMandatoryNode(mandatory);
+        writer.endNode();
+    }
+
+    private void emitPresenceNode(final boolean presence) {
+        writer.startPresenceNode(presence);
+        writer.endNode();
+    }
+
+    private void emitOrderedBy(final boolean userOrdered) {
+        if (userOrdered) {
+            writer.startOrderedByNode("user");
+        } else {
+            writer.startOrderedByNode("system");
+        }
+        writer.endNode();
+    }
+
+    private void emitMust(@Nullable final MustDefinition mustCondition) {
+        if(mustCondition != null && mustCondition.getXpath() != null) {
+            writer.startMustNode(mustCondition.getXpath());
+            emitErrorMessageNode(mustCondition.getErrorMessage());
+            emitErrorAppTagNode(mustCondition.getErrorAppTag());
+            emitDescriptionNode(mustCondition.getDescription());
+            emitReferenceNode(mustCondition.getReference());
+            writer.endNode();
+        }
+
+    }
+
+    private void emitErrorMessageNode(@Nullable final String input) {
+        if (input != null && !input.isEmpty()) {
+            writer.startErrorMessageNode(input);
+            writer.endNode();
+        }
+    }
+
+    private void emitErrorAppTagNode(final String input) {
+        if (input != null && !input.isEmpty()) {
+            writer.startErrorAppTagNode(input);
+            writer.endNode();
+        }
+    }
+
+    private void emitMinElementsNode(final Integer min) {
+        if (min != null) {
+            writer.startMinElementsNode(min);
+            writer.endNode();
+        }
+    }
+
+    private void emitMaxElementsNode(final Integer max) {
+        if (max != null) {
+            writer.startMaxElementsNode(max);
+            writer.endNode();
+        }
+    }
+
+    private void emitValueNode(@Nullable final Integer value) {
+        if (value != null) {
+            writer.startValueNode(value);
+            writer.endNode();
+        }
+    }
+
+    private void emitDocumentedNode(final DocumentedNode input) {
+        emitStatusNode(input.getStatus());
+        emitDescriptionNode(input.getDescription());
+        emitReferenceNode(input.getReference());
+    }
+
+    private void emitGrouping(final GroupingDefinition grouping) {
+        writer.startGroupingNode(grouping.getQName());
+        emitDocumentedNode(grouping);
+        emitDataNodeContainer(grouping);
+        emitUnknownStatementNodes(grouping.getUnknownSchemaNodes());
+        writer.endNode();
+
+    }
+
+    private void emitContainer(final ContainerSchemaNode child) {
+        writer.startContainerNode(child.getQName());
+
+        //
+
+        emitConstraints(child.getConstraints());
+        // FIXME: BUG-2444: whenNode //:Optional
+        // FIXME: BUG-2444: *(ifFeatureNode )
+        emitMustNodes(child.getConstraints().getMustConstraints());
+        emitPresenceNode(child.isPresenceContainer());
+        emitConfigNode(child.isConfiguration());
+        emitDocumentedNode(child);
+        emitDataNodeContainer(child);
+        emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+        writer.endNode();
+
+    }
+
+    private void emitConstraints(final ConstraintDefinition constraints) {
+        emitWhen(constraints.getWhenCondition());
+        for (final MustDefinition mustCondition : constraints.getMustConstraints()) {
+            emitMust(mustCondition);
+        }
+
+    }
+
+    private void emitLeaf(final LeafSchemaNode child) {
+        writer.startLeafNode(child.getQName());
+        emitWhen(child.getConstraints().getWhenCondition());
+        // FIXME: BUG-2444:  *(ifFeatureNode )
+        emitTypeNode(child.getPath(), child.getType());
+        emitUnitsNode(child.getUnits());
+        emitMustNodes(child.getConstraints().getMustConstraints());
+        emitDefaultNode(child.getDefault());
+        emitConfigNode(child.isConfiguration());
+        emitMandatoryNode(child.getConstraints().isMandatory());
+        emitDocumentedNode(child);
+        emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+        writer.endNode();
+
+    }
+
+    private void emitLeafList(final LeafListSchemaNode child) {
+        writer.startLeafListNode(child.getQName());
+
+        emitWhen(child.getConstraints().getWhenCondition());
+        // FIXME: BUG-2444: *(ifFeatureNode )
+        emitTypeNode(child.getPath(), child.getType());
+        // FIXME: BUG-2444: unitsNode /Optional
+        emitMustNodes(child.getConstraints().getMustConstraints());
+        emitConfigNode(child.isConfiguration());
+
+        emitMinElementsNode(child.getConstraints().getMinElements());
+        emitMaxElementsNode(child.getConstraints().getMaxElements());
+        emitOrderedBy(child.isUserOrdered());
+        emitDocumentedNode(child);
+        emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+        writer.endNode();
+
+    }
+
+    private void emitList(final ListSchemaNode child) {
+        writer.startListNode(child.getQName());
+        emitWhen(child.getConstraints().getWhenCondition());
+
+        // FIXME: BUG-2444: *(ifFeatureNode )
+        emitMustNodes(child.getConstraints().getMustConstraints());
+        emitKey(child.getKeyDefinition());
+        // FIXME: BUG-2444: *(uniqueNode )
+        emitConfigNode(child.isConfiguration());
+        emitMinElementsNode(child.getConstraints().getMinElements());
+        emitMaxElementsNode(child.getConstraints().getMaxElements());
+        emitOrderedBy(child.isUserOrdered());
+        emitDocumentedNode(child);
+        emitDataNodeContainer(child);
+        emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+        writer.endNode();
+
+    }
+
+    private void emitMustNodes(final Set<MustDefinition> mustConstraints) {
+        for (final MustDefinition must : mustConstraints) {
+            emitMust(must);
+        }
+    }
+
+    private void emitKey(final List<QName> keyList) {
+        if (keyList != null && !keyList.isEmpty()) {
+            writer.startKeyNode(keyList);
+            writer.endNode();
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private void emitUnique(final String input) {
+        // FIXME: BUG-2444: writer.startUniqueNode(uniqueArgStr)); Nodeend
+
+    }
+
+    private void emitChoice(final ChoiceNode choice) {
+        writer.startChoiceNode(choice.getQName());
+        emitWhen(choice.getConstraints().getWhenCondition());
+        // FIXME: BUG-2444: *(ifFeatureNode )
+        // FIXME: BUG-2444: defaultNode //Optional
+        emitConfigNode(choice.isConfiguration());
+        emitMandatoryNode(choice.getConstraints().isMandatory());
+        emitDocumentedNode(choice);
+        for (final ChoiceCaseNode caze : choice.getCases()) {
+            // TODO: emit short case?
+            emitCaseNode(caze);
+        }
+        emitUnknownStatementNodes(choice.getUnknownSchemaNodes());
+        writer.endNode();
+    }
+
+    private void emitCaseNode(final ChoiceCaseNode caze) {
+        if (!emitInstantiated && caze.isAugmenting()) {
+            return;
+        }
+        writer.startCaseNode(caze.getQName());
+        emitWhen(caze.getConstraints().getWhenCondition());
+        // FIXME: BUG-2444: *(ifFeatureNode )
+        emitDocumentedNode(caze);
+        emitDataNodeContainer(caze);
+        emitUnknownStatementNodes(caze.getUnknownSchemaNodes());
+        writer.endNode();
+
+    }
+
+    private void emitAnyxml(final AnyXmlSchemaNode child) {
+        writer.startAnyxmlNode(child.getQName());
+
+        emitWhen(child.getConstraints().getWhenCondition());
+        // FIXME: BUG-2444: *(ifFeatureNode )
+        emitMustNodes(child.getConstraints().getMustConstraints());
+        emitConfigNode(child.isConfiguration());
+        emitMandatoryNode(child.getConstraints().isMandatory());
+        emitDocumentedNode(child);
+        emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+        writer.endNode();
+
+    }
+
+    private void emitUsesNode(final UsesNode usesNode) {
+        if (emitUses && !usesNode.isAddedByUses() && !usesNode.isAugmenting()) {
+            writer.startUsesNode(usesNode.getGroupingPath().getLastComponent());
+            /*
+             * FIXME: BUG-2444:
+             *  whenNode /
+             *  *(ifFeatureNode )
+             * statusNode // Optional F
+             * : descriptionNode // Optional
+             * referenceNode // Optional
+             */
+            for (final Entry<SchemaPath, SchemaNode> refine : usesNode.getRefines().entrySet()) {
+                emitRefine(refine);
+            }
+            for (final AugmentationSchema aug : usesNode.getAugmentations()) {
+                emitUsesAugmentNode(aug);
+            }
+            writer.endNode();
+        }
+    }
+
+    private void emitRefine(final Entry<SchemaPath, SchemaNode> refine) {
+        final SchemaPath path = refine.getKey();
+        final SchemaNode value = refine.getValue();
+        writer.startRefineNode(path);
+
+        if (value instanceof LeafSchemaNode) {
+            emitRefineLeafNodes((LeafSchemaNode) value);
+        } else if (value instanceof LeafListSchemaNode) {
+            emitRefineLeafListNodes((LeafListSchemaNode) value);
+        } else if (value instanceof ListSchemaNode) {
+            emitRefineListNodes((ListSchemaNode) value);
+        } else if (value instanceof ChoiceNode) {
+            emitRefineChoiceNodes((ChoiceNode) value);
+        } else if (value instanceof ChoiceCaseNode) {
+            emitRefineCaseNodes((ChoiceCaseNode) value);
+        } else if (value instanceof ContainerSchemaNode) {
+            emitRefineContainerNodes((ContainerSchemaNode) value);
+        } else if (value instanceof AnyXmlSchemaNode) {
+            emitRefineAnyxmlNodes((AnyXmlSchemaNode) value);
+        }
+        writer.endNode();
+
+    }
+
+    private <T extends SchemaNode> T getOriginalChecked(final T value) {
+        final Optional<SchemaNode> original = SchemaNodeUtils.getOriginalIfPossible(value);
+        Preconditions.checkArgument(original.isPresent(), "Original unmodified version of node is not present.");
+        @SuppressWarnings("unchecked")
+        final T ret = (T) original.get();
+        return ret;
+    }
+
+    private void emitDocumentedNodeRefine(final DocumentedNode original, final DocumentedNode value) {
+        if (Objects.deepEquals(original.getDescription(), value.getDescription())) {
+            emitDescriptionNode(value.getDescription());
+        }
+        if (Objects.deepEquals(original.getReference(), value.getReference())) {
+            emitReferenceNode(value.getReference());
+        }
+    }
+
+    private void emitRefineContainerNodes(final ContainerSchemaNode value) {
+        final ContainerSchemaNode original = getOriginalChecked(value);
+
+        // emitMustNodes(child.getConstraints().getMustConstraints());
+        if (Objects.deepEquals(original.isPresenceContainer(), value.isPresenceContainer())) {
+            emitPresenceNode(value.isPresenceContainer());
+        }
+        if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+            emitConfigNode(value.isConfiguration());
+        }
+        emitDocumentedNodeRefine(original, value);
+
+    }
+
+    private void emitRefineLeafNodes(final LeafSchemaNode value) {
+        final LeafSchemaNode original = getOriginalChecked(value);
+
+        // emitMustNodes(child.getConstraints().getMustConstraints());
+        if (Objects.deepEquals(original.getDefault(), value.getDefault())) {
+            emitDefaultNode(value.getDefault());
+        }
+        if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+            emitConfigNode(value.isConfiguration());
+        }
+        emitDocumentedNodeRefine(original, value);
+        if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
+            emitMandatoryNode(value.getConstraints().isMandatory());
+        }
+
+    }
+
+    private void emitRefineLeafListNodes(final LeafListSchemaNode value) {
+        final LeafListSchemaNode original = getOriginalChecked(value);
+
+        // emitMustNodes(child.getConstraints().getMustConstraints());
+        if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+            emitConfigNode(value.isConfiguration());
+        }
+        if (Objects.deepEquals(original.getConstraints().getMinElements(), value.getConstraints().getMinElements())) {
+            emitMinElementsNode(value.getConstraints().getMinElements());
+        }
+        if (Objects.deepEquals(original.getConstraints().getMaxElements(), value.getConstraints().getMaxElements())) {
+            emitMaxElementsNode(value.getConstraints().getMaxElements());
+        }
+        emitDocumentedNodeRefine(original, value);
+
+    }
+
+    private void emitRefineListNodes(final ListSchemaNode value) {
+        final ListSchemaNode original = getOriginalChecked(value);
+
+        // emitMustNodes(child.getConstraints().getMustConstraints());
+        if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+            emitConfigNode(value.isConfiguration());
+        }
+        if (Objects.deepEquals(original.getConstraints().getMinElements(), value.getConstraints().getMinElements())) {
+            emitMinElementsNode(value.getConstraints().getMinElements());
+        }
+        if (Objects.deepEquals(original.getConstraints().getMaxElements(), value.getConstraints().getMaxElements())) {
+            emitMaxElementsNode(value.getConstraints().getMaxElements());
+        }
+        emitDocumentedNodeRefine(original, value);
+
+    }
+
+    private void emitRefineChoiceNodes(final ChoiceNode value) {
+        final ChoiceNode original = getOriginalChecked(value);
+
+        // FIXME: BUG-2444: defaultNode //FIXME: BUG-2444: Optional
+        if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+            emitConfigNode(value.isConfiguration());
+        }
+        if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
+            emitMandatoryNode(value.getConstraints().isMandatory());
+        }
+        emitDocumentedNodeRefine(original, value);
+
+    }
+
+    private void emitRefineCaseNodes(final ChoiceCaseNode value) {
+        final ChoiceCaseNode original = getOriginalChecked(value);
+        emitDocumentedNodeRefine(original, value);
+
+    }
+
+    private void emitRefineAnyxmlNodes(final AnyXmlSchemaNode value) {
+        final AnyXmlSchemaNode original = getOriginalChecked(value);
+
+        // FIXME: BUG-2444:  emitMustNodes(child.getConstraints().getMustConstraints());
+        if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+            emitConfigNode(value.isConfiguration());
+        }
+        if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
+            emitMandatoryNode(value.getConstraints().isMandatory());
+        }
+        emitDocumentedNodeRefine(original, value);
+
+    }
+
+    private void emitUsesAugmentNode(final AugmentationSchema aug) {
+        /**
+         * differs only in location in schema, otherwise currently (as of
+         * RFC6020) it is same, so we could freely reuse path.
+         */
+        emitAugment(aug);
+    }
+
+    private void emitAugment(final AugmentationSchema augmentation) {
+        writer.startAugmentNode(augmentation.getTargetPath());
+        // FIXME: BUG-2444: whenNode //Optional
+        // FIXME: BUG-2444: *(ifFeatureNode )
+
+        emitStatusNode(augmentation.getStatus());
+        emitDescriptionNode(augmentation.getDescription());
+        emitReferenceNode(augmentation.getReference());
+        for(final UsesNode uses: augmentation.getUses()) {
+            emitUsesNode(uses);
+        }
+
+        for (final DataSchemaNode childNode : augmentation.getChildNodes()) {
+            if (childNode instanceof ChoiceCaseNode) {
+                emitCaseNode((ChoiceCaseNode) childNode);
+            } else {
+                emitDataSchemaNode(childNode);
+            }
+        }
+        emitUnknownStatementNodes(augmentation.getUnknownSchemaNodes());
+        writer.endNode();
+    }
+
+    private void emitUnknownStatementNodes(final List<UnknownSchemaNode> unknownNodes) {
+        for (final UnknownSchemaNode unknonwnNode : unknownNodes) {
+            emitUnknownStatementNode(unknonwnNode);
+        }
+    }
+
+    private void emitUnknownStatementNode(final UnknownSchemaNode node) {
+        final StatementDefinition def = getStatementChecked(node.getNodeType());
+        if (def.getArgumentName() == null) {
+            writer.startUnknownNode(def);
+        } else {
+            writer.startUnknownNode(def, node.getNodeParameter());
+        }
+        emitUnknownStatementNodes(node.getUnknownSchemaNodes());
+        writer.endNode();
+    }
+
+    private StatementDefinition getStatementChecked(final QName nodeType) {
+        final StatementDefinition ret = extensions.get(nodeType);
+        Preconditions.checkArgument(ret != null, "Unknown extension %s used during export.",nodeType);
+        return ret;
+    }
+
+    private void emitWhen(final RevisionAwareXPath revisionAwareXPath) {
+        if(revisionAwareXPath != null) {
+            writer.startWhenNode(revisionAwareXPath);
+            writer.endNode();
+        }
+                // FIXME: BUG-2444: descriptionNode //FIXME: BUG-2444: Optional
+        // FIXME: BUG-2444: referenceNode //FIXME: BUG-2444: Optional
+        // FIXME: BUG-2444: writer.endNode();)
+
+    }
+
+    private void emitRpc(final RpcDefinition rpc) {
+        writer.startRpcNode(rpc.getQName());
+        // FIXME: BUG-2444: *(ifFeatureNode )
+        emitStatusNode(rpc.getStatus());
+        emitDescriptionNode(rpc.getDescription());
+        emitReferenceNode(rpc.getReference());
+
+        for(final TypeDefinition<?> typedef : rpc.getTypeDefinitions()) {
+            emitTypedefNode(typedef);
+        }
+        for(final GroupingDefinition grouping : rpc.getGroupings()) {
+            emitGrouping(grouping);
+        }
+        emitInput(rpc.getInput());
+        emitOutput(rpc.getOutput());
+        emitUnknownStatementNodes(rpc.getUnknownSchemaNodes());
+        writer.endNode();
+
+    }
+
+    private void emitInput(@Nullable final ContainerSchemaNode input) {
+        if (input != null) {
+            writer.startInputNode();
+            emitDataNodeContainer(input);
+            emitUnknownStatementNodes(input.getUnknownSchemaNodes());
+            writer.endNode();
+        }
+
+    }
+
+    private void emitOutput(@Nullable final ContainerSchemaNode input) {
+        if (input != null) {
+            writer.startOutputNode();
+            emitDataNodeContainer(input);
+            emitUnknownStatementNodes(input.getUnknownSchemaNodes());
+            writer.endNode();
+        }
+
+    }
+
+    private void emitNotificationNode(final NotificationDefinition notification) {
+        writer.startNotificationNode(notification.getQName());
+        // FIXME: BUG-2444: *(ifFeatureNode )
+        emitDocumentedNode(notification);
+        emitDataNodeContainer(notification);
+        emitUnknownStatementNodes(notification.getUnknownSchemaNodes());
+        writer.endNode();
+
+    }
+
+
+    //FIXME: Probably should be moved to utils bundle.
+    private static <T> boolean  isPrefix(final Iterable<T> prefix, final Iterable<T> other) {
+        final Iterator<T> prefixIt = prefix.iterator();
+        final Iterator<T> otherIt = other.iterator();
+        while(prefixIt.hasNext()) {
+            if(!otherIt.hasNext()) {
+                return false;
+            }
+            if(!Objects.deepEquals(prefixIt.next(), otherIt.next())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void emitDeviation(final Deviation deviation) {
+        /*
+         * FIXME: BUG-2444:  Deviation is not modeled properly and we are loosing lot of
+         * information in order to export it properly
+         *
+         * writer.startDeviationNode(deviation.getTargetPath());
+         *
+         * :descriptionNode //:Optional
+         *
+         *
+         * emitReferenceNode(deviation.getReference());
+         * :(deviateNotSupportedNode :1*(deviateAddNode :deviateReplaceNode
+         * :deviateDeleteNode)) :writer.endNode();
+         */
+    }
+}
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/SchemaToStatementWriterAdaptor.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/SchemaToStatementWriterAdaptor.java
new file mode 100644 (file)
index 0000000..8dbe7f4
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+ * 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.model.export;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.UnsignedInteger;
+import java.net.URI;
+import java.util.Date;
+import java.util.List;
+import javax.annotation.concurrent.NotThreadSafe;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+
+@Beta
+@NotThreadSafe
+final class SchemaToStatementWriterAdaptor implements Rfc6020ModuleWriter {
+
+    private final StatementTextWriter writer;
+
+    private SchemaToStatementWriterAdaptor(final StatementTextWriter writer) {
+        this.writer = Preconditions.checkNotNull(writer);
+    }
+
+    public static final Rfc6020ModuleWriter from(final StatementTextWriter writer) {
+        return new SchemaToStatementWriterAdaptor(writer);
+    }
+
+    @Override
+    public void endNode() {
+        writer.endStatement();
+    }
+
+    @Override
+    public void startModuleNode(final String identifier) {
+        writer.startStatement(Rfc6020Mapping.Module);
+        writer.writeArgument(identifier);
+    }
+
+    @Override
+    public void startOrganizationNode(final String input) {
+        writer.startStatement(Rfc6020Mapping.Organization);
+        writer.writeArgument(input);
+    }
+
+    @Override
+    public void startContactNode(final String input) {
+        writer.startStatement(Rfc6020Mapping.Contact);
+        writer.writeArgument(input);
+    }
+
+    @Override
+    public void startDescriptionNode(final String input) {
+        writer.startStatement(Rfc6020Mapping.Description);
+        writer.writeArgument(input);
+    }
+
+    @Override
+    public void startReferenceNode(final String input) {
+        writer.startStatement(Rfc6020Mapping.Reference);
+        writer.writeArgument(input);
+    }
+
+    @Override
+    public void startUnitsNode(final String input) {
+        writer.startStatement(Rfc6020Mapping.Units);
+        writer.writeArgument(input);
+    }
+
+    @Override
+    public void startYangVersionNode(final String input) {
+        writer.startStatement(Rfc6020Mapping.YangVersion);
+        writer.writeArgument(input);
+    }
+
+    @Override
+    public void startNamespaceNode(final URI uri) {
+        writer.startStatement(Rfc6020Mapping.Namespace);
+        writer.writeArgument(uri.toString());
+    }
+
+    @Override
+    public void startKeyNode(final List<QName> keyList) {
+        writer.startStatement(Rfc6020Mapping.Key);
+        final StringBuilder keyStr = new StringBuilder();
+        for (final QName item : keyList) {
+            keyStr.append(item.getLocalName());
+        }
+        writer.writeArgument(keyStr.toString());
+    }
+
+    @Override
+    public void startPrefixNode(final String input) {
+        writer.startStatement(Rfc6020Mapping.Prefix);
+        writer.writeArgument(input);
+    }
+
+    @Override
+    public void startFeatureNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.Feature);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startExtensionNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.Extension);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startArgumentNode(final String input) {
+        writer.startStatement(Rfc6020Mapping.Argument);
+        writer.writeArgument(input);
+    }
+
+    @Override
+    public void startStatusNode(final Status status) {
+        writer.startStatement(Rfc6020Mapping.Status);
+        writer.writeArgument(status.toString().toLowerCase());
+    }
+
+    @Override
+    public void startTypeNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.Type);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startLeafNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.Leaf);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startContainerNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.Container);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startGroupingNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.Grouping);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startRpcNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.Rpc);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startInputNode() {
+        writer.startStatement(Rfc6020Mapping.Input);
+    }
+
+    @Override
+    public void startOutputNode() {
+        writer.startStatement(Rfc6020Mapping.Output);
+    }
+
+    @Override
+    public void startLeafListNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.LeafList);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startListNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.List);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startChoiceNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.Choice);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startCaseNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.Case);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startNotificationNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.Notification);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startIdentityNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.Identity);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startBaseNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.Base);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startTypedefNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.Typedef);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startRevisionNode(final Date date) {
+        writer.startStatement(Rfc6020Mapping.Revision);
+        writer.writeArgument(SimpleDateFormatUtil.getRevisionFormat().format(date));
+    }
+
+    @Override
+    public void startDefaultNode(final String string) {
+        writer.startStatement(Rfc6020Mapping.Default);
+        writer.writeArgument(string);
+    }
+
+    @Override
+    public void startMustNode(final RevisionAwareXPath xpath) {
+        writer.startStatement(Rfc6020Mapping.Must);
+        writer.writeArgument(xpath);
+    }
+
+    @Override
+    public void startErrorMessageNode(final String input) {
+        writer.startStatement(Rfc6020Mapping.ErrorMessage);
+        writer.writeArgument(input);
+    }
+
+    @Override
+    public void startErrorAppTagNode(final String input) {
+        writer.startStatement(Rfc6020Mapping.ErrorAppTag);
+        writer.writeArgument(input);
+    }
+
+    @Override
+    public void startPatternNode(final String regularExpression) {
+        writer.startStatement(Rfc6020Mapping.Pattern);
+        writer.writeArgument(regularExpression);
+    }
+
+    @Override
+    public void startValueNode(final Integer integer) {
+        writer.startStatement(Rfc6020Mapping.Value);
+        writer.writeArgument(integer.toString());
+    }
+
+    @Override
+    public void startEnumNode(final String name) {
+        writer.startStatement(Rfc6020Mapping.Enum);
+        writer.writeArgument(name);
+    }
+
+    @Override
+    public void startRequireInstanceNode(final boolean require) {
+        writer.startStatement(Rfc6020Mapping.RequireInstance);
+        writer.writeArgument(Boolean.toString(require));
+    }
+
+    @Override
+    public void startPathNode(final RevisionAwareXPath revisionAwareXPath) {
+        writer.startStatement(Rfc6020Mapping.Path);
+        writer.writeArgument(revisionAwareXPath);
+    }
+
+    @Override
+    public void startBitNode(final String name) {
+        writer.startStatement(Rfc6020Mapping.Bit);
+        writer.writeArgument(name);
+    }
+
+    @Override
+    public void startPositionNode(final UnsignedInteger position) {
+        writer.startStatement(Rfc6020Mapping.Position);
+        writer.writeArgument(position.toString());
+    }
+
+    @Override
+    public void startImportNode(final String moduleName) {
+        writer.startStatement(Rfc6020Mapping.Import);
+        writer.writeArgument(moduleName);
+    }
+
+    @Override
+    public void startRevisionDateNode(final Date date) {
+        writer.startStatement(Rfc6020Mapping.RevisionDate);
+        writer.writeArgument(SimpleDateFormatUtil.getRevisionFormat().format(date));
+    }
+
+    @Override
+    public void startUsesNode(final QName groupingName) {
+        writer.startStatement(Rfc6020Mapping.Uses);
+        writer.writeArgument(groupingName);
+    }
+
+    @Override
+    public void startAugmentNode(final SchemaPath targetPath) {
+        writer.startStatement(Rfc6020Mapping.Augment);
+        writer.writeArgument(targetPath);
+    }
+
+    @Override
+    public void startConfigNode(final boolean config) {
+        writer.startStatement(Rfc6020Mapping.Config);
+        writer.writeArgument(Boolean.toString(config));
+    }
+
+    @Override
+    public void startLengthNode(final String lengthString) {
+        writer.startStatement(Rfc6020Mapping.Length);
+        writer.writeArgument(lengthString);
+    }
+
+    @Override
+    public void startMaxElementsNode(final Integer max) {
+        writer.startStatement(Rfc6020Mapping.MaxElements);
+        writer.writeArgument(max.toString());
+    }
+
+    @Override
+    public void startMinElementsNode(final Integer min) {
+        writer.startStatement(Rfc6020Mapping.MinElements);
+        writer.writeArgument(min.toString());
+    }
+
+    @Override
+    public void startPresenceNode(final boolean presence) {
+        writer.startStatement(Rfc6020Mapping.Presence);
+        writer.writeArgument(Boolean.toString(presence));
+    }
+
+    @Override
+    public void startOrderedByNode(final String ordering) {
+        writer.startStatement(Rfc6020Mapping.OrderedBy);
+        writer.writeArgument(ordering);
+    }
+
+    @Override
+    public void startRangeNode(final String rangeString) {
+        writer.startStatement(Rfc6020Mapping.Range);
+        writer.writeArgument(rangeString);
+    }
+
+    @Override
+    public void startFractionDigitsNode(final Integer fractionDigits) {
+        writer.startStatement(Rfc6020Mapping.FractionDigits);
+        writer.writeArgument(fractionDigits.toString());
+    }
+
+    @Override
+    public void startRefineNode(final SchemaPath path) {
+        writer.startStatement(Rfc6020Mapping.Refine);
+        writer.writeArgument(path);
+    }
+
+    @Override
+    public void startMandatoryNode(final boolean mandatory) {
+        writer.startStatement(Rfc6020Mapping.Mandatory);
+        writer.writeArgument(Boolean.toString(mandatory));
+    }
+
+    @Override
+    public void startAnyxmlNode(final QName qName) {
+        writer.startStatement(Rfc6020Mapping.Anyxml);
+        writer.writeArgument(qName);
+    }
+
+    @Override
+    public void startUnknownNode(final StatementDefinition def) {
+        writer.startStatement(def);
+    }
+
+    @Override
+    public void startUnknownNode(final StatementDefinition def, final String nodeParameter) {
+        writer.startStatement(def);
+        writer.writeArgument(nodeParameter);
+    }
+
+    @Override
+    public void startYinElementNode(final boolean yinElement) {
+        writer.startStatement(Rfc6020Mapping.YinElement);
+        writer.writeArgument(Boolean.toString(yinElement));
+    }
+
+    @Override
+    public void startWhenNode(final RevisionAwareXPath revisionAwareXPath) {
+        writer.startStatement(Rfc6020Mapping.When);
+        writer.writeArgument(revisionAwareXPath);
+    }
+}
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/SingleModuleYinStatementWriter.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/SingleModuleYinStatementWriter.java
new file mode 100644 (file)
index 0000000..bbc059d
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import java.net.URI;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.NotThreadSafe;
+import javax.xml.XMLConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.YangConstants;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+
+@Beta
+@NotThreadSafe
+class SingleModuleYinStatementWriter implements StatementTextWriter {
+
+    private final XMLStreamWriter writer;
+    private final URI currentModuleNs;
+    private final BiMap<String, URI> prefixToNamespace;
+    private StatementDefinition currentStatement;
+
+    private SingleModuleYinStatementWriter(final XMLStreamWriter writer, final URI moduleNamespace,
+            final Map<String, URI> prefixToNs) {
+        super();
+        this.writer = writer;
+        this.currentModuleNs = moduleNamespace;
+        this.prefixToNamespace = HashBiMap.create(prefixToNs);
+        initializeYinNamespaceInXml();
+
+    }
+
+    private void initializeYinNamespaceInXml() {
+       try {
+            final String defaultNs = writer.getNamespaceContext().getNamespaceURI(XMLConstants.NULL_NS_URI);
+            if (defaultNs == null) {
+                writer.setDefaultNamespace(YangConstants.RFC6020_YIN_NAMESPACE.toString());
+            } else if (!YangConstants.RFC6020_YIN_NAMESPACE.toString().equals(defaultNs)) {
+                // FIXME: Implement support for exporting YIN as part of other XML document.
+                throw new UnsupportedOperationException("Not implemented support for nesting YIN in different XML element.");
+            }
+        } catch (final XMLStreamException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    static final StatementTextWriter create(final XMLStreamWriter writer, final URI moduleNs,
+            final Map<String, URI> prefixToNs) {
+        return new SingleModuleYinStatementWriter(writer, moduleNs, prefixToNs);
+    }
+
+    @Override
+    public void startStatement(final StatementDefinition statement) {
+        currentStatement = Preconditions.checkNotNull(statement);
+        try {
+            writeStartXmlElement(statement.getStatementName());
+            if (Rfc6020Mapping.Module.equals(statement) || Rfc6020Mapping.Submodule.equals(statement)) {
+                declareXmlNamespaces(prefixToNamespace);
+            }
+        } catch (final XMLStreamException e) {
+            // FIXME: Introduce proper expression
+            throw new IllegalStateException(e);
+        }
+    }
+
+    @Override
+    public void endStatement() {
+        currentStatement = null;
+        try {
+            writeXmlEndElement();
+        } catch (final XMLStreamException e) {
+            // FIXME: Introduce proper expression
+            throw new IllegalStateException(e);
+        }
+    }
+
+    @Override
+    public void writeArgument(final String strRep) {
+        checkArgumentApplicable();
+        writeArgument0(strRep);
+    }
+
+    @Override
+    public void writeArgument(final QName value) {
+        checkArgumentApplicable();
+        final String valueStr = toPrefixedString(value);
+        writeArgument0(valueStr);
+    }
+
+    @Override
+    public void writeArgument(final SchemaPath targetPath) {
+        checkArgumentApplicable();
+        final StringBuilder valueStr = new StringBuilder();
+        if(targetPath.isAbsolute()) {
+            valueStr.append("/");
+        }
+        final Iterator<QName> argIt = targetPath.getPathFromRoot().iterator();
+        while(argIt.hasNext()) {
+            valueStr.append(toPrefixedString(argIt.next()));
+            if(argIt.hasNext()) {
+                valueStr.append("/");
+            }
+        }
+        writeArgument0(valueStr.toString());
+    }
+
+    @Override
+    public void writeArgument(final RevisionAwareXPath xpath) {
+        checkArgumentApplicable();
+        // FIXME: This implementation assumes prefixes are unchanged
+        // and were not changed in schema context.
+        writeArgument0(xpath.toString());
+    }
+
+
+    private void writeArgument0(final String strRep) {
+        try {
+            if (isArgumentYinElement(currentStatement)) {
+                writeStartXmlElement(currentStatement.getArgumentName());
+                writeXmlText(strRep);
+                writeXmlEndElement();
+            } else {
+                writeXmlArgument(currentStatement.getArgumentName(), strRep);
+            }
+        } catch (final XMLStreamException e) {
+            // FIXME: throw proper exception
+            throw new IllegalStateException(e);
+        }
+    }
+
+    private boolean isArgumentYinElement(StatementDefinition currentStatement2) {
+        // FIXME: Implement this
+        return false;
+    }
+
+    private void checkArgumentApplicable() {
+        Preconditions.checkState(currentStatement != null, "No statement is opened.");
+        Preconditions.checkState(currentStatement.getArgumentName() != null, "Statement %s does not take argument.",
+                currentStatement.getArgumentName());
+    }
+
+
+
+    private String toPrefixedString(@Nullable final String prefix, final String localName) {
+        if (prefix == null || prefix.isEmpty()) {
+            return localName;
+        }
+        return prefix + ":" + localName;
+    }
+
+    private String toPrefixedString(final QName value) {
+        final URI valueNs = value.getNamespace();
+        final String valueLocal = value.getLocalName();
+        if (currentModuleNs.equals(valueNs)) {
+            return valueLocal;
+        }
+        final String prefix = ensureAndGetXmlNamespacePrefix(valueNs);
+        return toPrefixedString(prefix, valueLocal);
+    }
+
+    private @Nullable String ensureAndGetXmlNamespacePrefix(final URI namespace) {
+        if(YangConstants.RFC6020_YANG_NAMESPACE.equals(namespace)) {
+         // YANG namespace does not have prefix if used in arguments.
+            return null;
+
+        }
+        String prefix = writer.getNamespaceContext().getPrefix(namespace.toString());
+        if (prefix == null) {
+            // FIXME: declare prefix
+            prefix =prefixToNamespace.inverse().get(namespace);
+        }
+        if(prefix == null) {
+            throw new IllegalArgumentException("Namespace " + namespace + " is not bound to imported prefixes.");
+        }
+        return prefix;
+    }
+
+    private void writeXmlText(final String strRep) throws XMLStreamException {
+        writer.writeCharacters(strRep);
+    }
+
+    private void declareXmlNamespaces(final Map<String, URI> prefixToNamespace) {
+        try {
+            writer.writeDefaultNamespace(YangConstants.RFC6020_YIN_NAMESPACE.toString());
+            for (final Entry<String, URI> nsDeclaration : prefixToNamespace.entrySet()) {
+                writer.writeNamespace(nsDeclaration.getKey(), nsDeclaration.getValue().toString());
+            }
+        } catch (final XMLStreamException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    private void writeXmlEndElement() throws XMLStreamException {
+        writer.writeEndElement();
+    }
+
+    private void writeXmlArgument(final QName qName, final String value) throws XMLStreamException {
+        writer.writeAttribute(qName.getNamespace().toString(), qName.getLocalName(), value);
+    }
+
+    private void writeStartXmlElement(final QName name) throws XMLStreamException {
+        writer.writeStartElement(name.getNamespace().toString(), name.getLocalName());
+    }
+
+}
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/StatementTextWriter.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/StatementTextWriter.java
new file mode 100644 (file)
index 0000000..867c297
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */package org.opendaylight.yangtools.yang.model.export;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+
+interface StatementTextWriter {
+
+
+    void startStatement(StatementDefinition statement);
+
+    void writeArgument(RevisionAwareXPath xpath);
+
+    void writeArgument(QName name);
+
+    void writeArgument(String argStr);
+
+    void writeArgument(SchemaPath targetPath);
+
+    void endStatement();
+
+}
diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/YinExportUtils.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/YinExportUtils.java
new file mode 100644 (file)
index 0000000..e518050
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.Date;
+import java.util.Map;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class YinExportUtils {
+
+
+    private YinExportUtils() {
+        throw new UnsupportedOperationException("Utility class");
+    }
+
+
+    /**
+     *
+     * Returns well-formed file name of YIN file as defined in RFC6020.
+     *
+     * @param name Module or submodule name
+     * @param revision Revision of module or submodule
+     * @return well-formed file name of YIN file as defined in RFC6020.
+     */
+    public static String wellFormedYinName(final String name, final Date revision) {
+        return wellFormedYinName(name, SimpleDateFormatUtil.getRevisionFormat().format(revision));
+    }
+
+    /**
+     *
+     * Returns well-formed file name of YIN file as defined in RFC6020.
+     *
+     * @param name
+     *            name Module or submodule name
+     * @param revision
+     *            Revision of module or submodule
+     * @return well-formed file name of YIN file as defined in RFC6020.
+     */
+    public static String wellFormedYinName(final String name, final String revision) {
+        return String.format("%s@%s.yin", Preconditions.checkNotNull(name),Preconditions.checkNotNull(revision));
+    }
+
+    /**
+     * Writes YIN representation of supplied module to specified output stream.
+     *
+     * @param ctx
+     *            Schema Context which contains module and extension definitions
+     *            to be used during export of model.
+     * @param module
+     *            Module to be exported.
+     * @param str
+     *            Output stream to which YIN representation of model will be
+     *            written.
+     * @throws XMLStreamException
+     */
+    public static void writeModuleToOutputStream(final SchemaContext ctx, final Module module, final OutputStream str) throws XMLStreamException {
+        final XMLOutputFactory factory = XMLOutputFactory.newFactory();
+        final XMLStreamWriter xmlStreamWriter = factory.createXMLStreamWriter(str);
+        writeModuleToOutputStream(ctx,module, xmlStreamWriter);
+    }
+
+    private static void writeModuleToOutputStream(final SchemaContext ctx, final Module module, final XMLStreamWriter xmlStreamWriter) {
+        final URI moduleNs = module.getNamespace();
+        final Map<String, URI> prefixToNs = prefixToNamespace(ctx,module);
+        final StatementTextWriter yinWriter = SingleModuleYinStatementWriter.create(xmlStreamWriter, moduleNs, prefixToNs);
+        SchemaContextEmitter.writeToStatementWriter(module, ctx,yinWriter);
+    }
+
+    private static Map<String, URI> prefixToNamespace(final SchemaContext ctx, final Module module) {
+        final BiMap<String, URI> prefixMap = HashBiMap.create(module.getImports().size() + 1);
+        prefixMap.put(module.getPrefix(), module.getNamespace());
+        for(final ModuleImport imp : module.getImports()) {
+            final String prefix = imp.getPrefix();
+            final URI namespace = getModuleNamespace(ctx,imp.getModuleName());
+            prefixMap.put(prefix, namespace);
+        }
+        return prefixMap;
+    }
+
+    private static URI getModuleNamespace(final SchemaContext ctx, final String moduleName) {
+        for(final Module module : ctx.getModules()) {
+            if(moduleName.equals(module.getName())) {
+                return module.getNamespace();
+            }
+        }
+        throw new IllegalArgumentException("Module " + moduleName + "does not exists in provided schema context");
+    }
+
+}
diff --git a/yang/yang-model-export/src/test/java/org/opendaylight/yangtools/yang/model/export/test/SimpleModuleTest.java b/yang/yang-model-export/src/test/java/org/opendaylight/yangtools/yang/model/export/test/SimpleModuleTest.java
new file mode 100644 (file)
index 0000000..1ce27d2
--- /dev/null
@@ -0,0 +1,98 @@
+package org.opendaylight.yangtools.yang.model.export.test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.net.URISyntaxException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.export.YinExportUtils;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaListenerRegistration;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceListener;
+import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache;
+import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
+import org.opendaylight.yangtools.yang.parser.util.TextToASTTransformer;
+
+public class SimpleModuleTest {
+
+    private static final File TEST_MODELS_FOLDER;
+
+    static {
+        try {
+            TEST_MODELS_FOLDER = new File(SimpleModuleTest.class.getResource("/yang/").toURI());
+        } catch (final URISyntaxException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    private SharedSchemaRepository schemaRegistry;
+    private FilesystemSchemaSourceCache<YangTextSchemaSource> fileSourceProvider;
+    private SchemaContextFactory schemaContextFactory;
+    private Set<SourceIdentifier> allTestSources;
+
+    @Before
+    public void init() {
+        schemaRegistry = new SharedSchemaRepository("test");
+        fileSourceProvider = new FilesystemSchemaSourceCache<YangTextSchemaSource>(schemaRegistry,
+                YangTextSchemaSource.class, TEST_MODELS_FOLDER);
+        final TextToASTTransformer astTransformer = TextToASTTransformer.create(schemaRegistry, schemaRegistry);
+        schemaRegistry.registerSchemaSourceListener(astTransformer);
+
+        schemaContextFactory = schemaRegistry.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT);
+        allTestSources = new HashSet<>();
+        final SchemaListenerRegistration reg = schemaRegistry.registerSchemaSourceListener(new SchemaSourceListener() {
+
+            @Override
+            public void schemaSourceUnregistered(final PotentialSchemaSource<?> source) {
+                // NOOP
+            }
+
+            @Override
+            public void schemaSourceRegistered(final Iterable<PotentialSchemaSource<?>> sources) {
+                for (final PotentialSchemaSource<?> source : sources) {
+                    allTestSources.add(source.getSourceIdentifier());
+                }
+            }
+
+            @Override
+            public void schemaSourceEncountered(final SchemaSourceRepresentation source) {
+                // NOOP
+            }
+        });
+        reg.close();
+    }
+
+    @Test
+    public void testGenerateAll() throws Exception {
+        testSetOfModules(allTestSources);
+    }
+
+    private void testSetOfModules(final Collection<SourceIdentifier> source) throws Exception {
+        final SchemaContext schemaContext = schemaContextFactory.createSchemaContext(source).checkedGet();
+        final File outDir = new File("target/collection");
+        outDir.mkdirs();
+        for (final Module module : schemaContext.getModules()) {
+            exportModule(schemaContext, module, outDir);
+        }
+    }
+
+    private File exportModule(final SchemaContext schemaContext, final Module module, final File outDir)
+            throws Exception {
+        final File outFile = new File(outDir, YinExportUtils.wellFormedYinName(module.getName(), module.getRevision()));
+        try (OutputStream output = new FileOutputStream(outFile)) {
+            YinExportUtils.writeModuleToOutputStream(schemaContext, module, output);
+        }
+        return outFile;
+    }
+}
diff --git a/yang/yang-model-export/src/test/resources/yang/ietf-inet-types@2010-09-24.yang b/yang/yang-model-export/src/test/resources/yang/ietf-inet-types@2010-09-24.yang
new file mode 100644 (file)
index 0000000..edd285d
--- /dev/null
@@ -0,0 +1,427 @@
+module ietf-inet-types {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+  prefix "inet";
+
+  organization
+   "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+  contact
+   "WG Web:   <http://tools.ietf.org/wg/netmod/>
+    WG List:  <mailto:netmod@ietf.org>
+
+    WG Chair: David Partain
+              <mailto:david.partain@ericsson.com>
+
+    WG Chair: David Kessens
+              <mailto:david.kessens@nsn.com>
+
+    Editor:   Juergen Schoenwaelder
+              <mailto:j.schoenwaelder@jacobs-university.de>";
+
+  description
+   "This module contains a collection of generally useful derived
+    YANG data types for Internet addresses and related things.
+
+    Copyright (c) 2010 IETF Trust and the persons identified as
+    authors of the code.  All rights reserved.
+
+
+
+    Redistribution and use in source and binary forms, with or without
+    modification, is permitted pursuant to, and subject to the license
+    terms contained in, the Simplified BSD License set forth in Section
+    4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+    (http://trustee.ietf.org/license-info).
+
+    This version of this YANG module is part of RFC 6021; see
+    the RFC itself for full legal notices.";
+
+  revision 2010-09-24 {
+    description
+     "Initial revision.";
+    reference
+     "RFC 6021: Common YANG Data Types";
+  }
+
+  /*** collection of protocol field related types ***/
+
+  typedef ip-version {
+    type enumeration {
+      enum unknown {
+        value "0";
+        description
+         "An unknown or unspecified version of the Internet protocol.";
+      }
+      enum ipv4 {
+        value "1";
+        description
+         "The IPv4 protocol as defined in RFC 791.";
+      }
+      enum ipv6 {
+        value "2";
+        description
+         "The IPv6 protocol as defined in RFC 2460.";
+      }
+    }
+    description
+     "This value represents the version of the IP protocol.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetVersion textual convention of the SMIv2.";
+    reference
+     "RFC  791: Internet Protocol
+      RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  typedef dscp {
+    type uint8 {
+      range "0..63";
+    }
+    description
+     "The dscp type represents a Differentiated Services Code-Point
+      that may be used for marking packets in a traffic stream.
+
+      In the value set and its semantics, this type is equivalent
+      to the Dscp textual convention of the SMIv2.";
+    reference
+     "RFC 3289: Management Information Base for the Differentiated
+                Services Architecture
+      RFC 2474: Definition of the Differentiated Services Field
+                (DS Field) in the IPv4 and IPv6 Headers
+      RFC 2780: IANA Allocation Guidelines For Values In
+                the Internet Protocol and Related Headers";
+  }
+
+  typedef ipv6-flow-label {
+    type uint32 {
+      range "0..1048575";
+    }
+    description
+     "The flow-label type represents flow identifier or Flow Label
+      in an IPv6 packet header that may be used to discriminate
+      traffic flows.
+
+      In the value set and its semantics, this type is equivalent
+      to the IPv6FlowLabel textual convention of the SMIv2.";
+    reference
+     "RFC 3595: Textual Conventions for IPv6 Flow Label
+      RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+  }
+
+  typedef port-number {
+    type uint16 {
+      range "0..65535";
+    }
+    description
+     "The port-number type represents a 16-bit port number of an
+      Internet transport layer protocol such as UDP, TCP, DCCP, or
+      SCTP.  Port numbers are assigned by IANA.  A current list of
+      all assignments is available from <http://www.iana.org/>.
+
+      Note that the port number value zero is reserved by IANA.  In
+      situations where the value zero does not make sense, it can
+      be excluded by subtyping the port-number type.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetPortNumber textual convention of the SMIv2.";
+    reference
+     "RFC  768: User Datagram Protocol
+      RFC  793: Transmission Control Protocol
+      RFC 4960: Stream Control Transmission Protocol
+      RFC 4340: Datagram Congestion Control Protocol (DCCP)
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  /*** collection of autonomous system related types ***/
+
+  typedef as-number {
+    type uint32;
+    description
+     "The as-number type represents autonomous system numbers
+      which identify an Autonomous System (AS).  An AS is a set
+      of routers under a single technical administration, using
+      an interior gateway protocol and common metrics to route
+      packets within the AS, and using an exterior gateway
+      protocol to route packets to other ASs'.  IANA maintains
+      the AS number space and has delegated large parts to the
+      regional registries.
+
+      Autonomous system numbers were originally limited to 16
+      bits.  BGP extensions have enlarged the autonomous system
+      number space to 32 bits.  This type therefore uses an uint32
+      base type without a range restriction in order to support
+      a larger autonomous system number space.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetAutonomousSystemNumber textual convention of
+      the SMIv2.";
+    reference
+     "RFC 1930: Guidelines for creation, selection, and registration
+                of an Autonomous System (AS)
+      RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+      RFC 4893: BGP Support for Four-octet AS Number Space
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  /*** collection of IP address and hostname related types ***/
+
+  typedef ip-address {
+    type union {
+      type inet:ipv4-address;
+      type inet:ipv6-address;
+    }
+    description
+     "The ip-address type represents an IP address and is IP
+      version neutral.  The format of the textual representations
+      implies the IP version.";
+  }
+
+  typedef ipv4-address {
+    type string {
+      pattern
+        '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+      +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+      + '(%[\p{N}\p{L}]+)?';
+    }
+    description
+      "The ipv4-address type represents an IPv4 address in
+       dotted-quad notation.  The IPv4 address may include a zone
+       index, separated by a % sign.
+
+       The zone index is used to disambiguate identical address
+       values.  For link-local addresses, the zone index will
+       typically be the interface index number or the name of an
+       interface.  If the zone index is not present, the default
+       zone of the device will be used.
+
+       The canonical format for the zone index is the numerical
+       format";
+  }
+
+  typedef ipv6-address {
+    type string {
+      pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+            + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+            + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+            + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+            + '(%[\p{N}\p{L}]+)?';
+      pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+            + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+            + '(%.+)?';
+    }
+    description
+     "The ipv6-address type represents an IPv6 address in full,
+      mixed, shortened, and shortened-mixed notation.  The IPv6
+      address may include a zone index, separated by a % sign.
+
+
+
+
+
+      The zone index is used to disambiguate identical address
+      values.  For link-local addresses, the zone index will
+      typically be the interface index number or the name of an
+      interface.  If the zone index is not present, the default
+      zone of the device will be used.
+
+      The canonical format of IPv6 addresses uses the compressed
+      format described in RFC 4291, Section 2.2, item 2 with the
+      following additional rules: the :: substitution must be
+      applied to the longest sequence of all-zero 16-bit chunks
+      in an IPv6 address.  If there is a tie, the first sequence
+      of all-zero 16-bit chunks is replaced by ::.  Single
+      all-zero 16-bit chunks are not compressed.  The canonical
+      format uses lowercase characters and leading zeros are
+      not allowed.  The canonical format for the zone index is
+      the numerical format as described in RFC 4007, Section
+      11.2.";
+    reference
+     "RFC 4291: IP Version 6 Addressing Architecture
+      RFC 4007: IPv6 Scoped Address Architecture
+      RFC 5952: A Recommendation for IPv6 Address Text Representation";
+  }
+
+  typedef ip-prefix {
+    type union {
+      type inet:ipv4-prefix;
+      type inet:ipv6-prefix;
+    }
+    description
+     "The ip-prefix type represents an IP prefix and is IP
+      version neutral.  The format of the textual representations
+      implies the IP version.";
+  }
+
+  typedef ipv4-prefix {
+    type string {
+      pattern
+         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+       + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+    }
+    description
+     "The ipv4-prefix type represents an IPv4 address prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal to 32.
+
+
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.
+
+      The canonical format of an IPv4 prefix has all bits of
+      the IPv4 address set to zero that are not part of the
+      IPv4 prefix.";
+  }
+
+  typedef ipv6-prefix {
+    type string {
+      pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+            + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+            + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+            + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+            + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+      pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+            + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+            + '(/.+)';
+    }
+    description
+     "The ipv6-prefix type represents an IPv6 address prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal 128.
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.
+
+      The IPv6 address should have all bits that do not belong
+      to the prefix set to zero.
+
+      The canonical format of an IPv6 prefix has all bits of
+      the IPv6 address set to zero that are not part of the
+      IPv6 prefix.  Furthermore, IPv6 address is represented
+      in the compressed format described in RFC 4291, Section
+      2.2, item 2 with the following additional rules: the ::
+      substitution must be applied to the longest sequence of
+      all-zero 16-bit chunks in an IPv6 address.  If there is
+      a tie, the first sequence of all-zero 16-bit chunks is
+      replaced by ::.  Single all-zero 16-bit chunks are not
+      compressed.  The canonical format uses lowercase
+      characters and leading zeros are not allowed.";
+    reference
+     "RFC 4291: IP Version 6 Addressing Architecture";
+  }
+
+
+  /*** collection of domain name and URI types ***/
+
+  typedef domain-name {
+    type string {
+      pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+           +  '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+           +  '|\.';
+      length "1..253";
+    }
+    description
+     "The domain-name type represents a DNS domain name.  The
+      name SHOULD be fully qualified whenever possible.
+
+      Internet domain names are only loosely specified.  Section
+      3.5 of RFC 1034 recommends a syntax (modified in Section
+      2.1 of RFC 1123).  The pattern above is intended to allow
+      for current practice in domain name use, and some possible
+      future expansion.  It is designed to hold various types of
+      domain names, including names used for A or AAAA records
+      (host names) and other records, such as SRV records.  Note
+      that Internet host names have a stricter syntax (described
+      in RFC 952) than the DNS recommendations in RFCs 1034 and
+      1123, and that systems that want to store host names in
+      schema nodes using the domain-name type are recommended to
+      adhere to this stricter standard to ensure interoperability.
+
+      The encoding of DNS names in the DNS protocol is limited
+      to 255 characters.  Since the encoding consists of labels
+      prefixed by a length bytes and there is a trailing NULL
+      byte, only 253 characters can appear in the textual dotted
+      notation.
+
+      The description clause of schema nodes using the domain-name
+      type MUST describe when and how these names are resolved to
+      IP addresses.  Note that the resolution of a domain-name value
+      may require to query multiple DNS records (e.g., A for IPv4
+      and AAAA for IPv6).  The order of the resolution process and
+      which DNS record takes precedence can either be defined
+      explicitely or it may depend on the configuration of the
+      resolver.
+
+      Domain-name values use the US-ASCII encoding.  Their canonical
+      format uses lowercase US-ASCII characters.  Internationalized
+      domain names MUST be encoded in punycode as described in RFC
+      3492";
+    reference
+     "RFC  952: DoD Internet Host Table Specification
+      RFC 1034: Domain Names - Concepts and Facilities
+      RFC 1123: Requirements for Internet Hosts -- Application
+                and Support
+      RFC 2782: A DNS RR for specifying the location of services
+                (DNS SRV)
+      RFC 3492: Punycode: A Bootstring encoding of Unicode for
+                Internationalized Domain Names in Applications
+                (IDNA)
+      RFC 5891: Internationalizing Domain Names in Applications
+                (IDNA): Protocol";
+  }
+
+  typedef host {
+    type union {
+      type inet:ip-address;
+      type inet:domain-name;
+    }
+    description
+     "The host type represents either an IP address or a DNS
+      domain name.";
+  }
+
+  typedef uri {
+    type string;
+    description
+     "The uri type represents a Uniform Resource Identifier
+      (URI) as defined by STD 66.
+
+      Objects using the uri type MUST be in US-ASCII encoding,
+      and MUST be normalized as described by RFC 3986 Sections
+      6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary
+      percent-encoding is removed, and all case-insensitive
+      characters are set to lowercase except for hexadecimal
+      digits, which are normalized to uppercase as described in
+      Section 6.2.2.1.
+
+      The purpose of this normalization is to help provide
+      unique URIs.  Note that this normalization is not
+      sufficient to provide uniqueness.  Two URIs that are
+      textually distinct after this normalization may still be
+      equivalent.
+
+      Objects using the uri type may restrict the schemes that
+      they permit.  For example, 'data:' and 'urn:' schemes
+      might not be appropriate.
+
+      A zero-length URI is not a valid URI.  This can be used to
+      express 'URI absent' where required.
+
+      In the value set and its semantics, this type is equivalent
+      to the Uri SMIv2 textual convention defined in RFC 5017.";
+    reference
+     "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+      RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+                Group: Uniform Resource Identifiers (URIs), URLs,
+                and Uniform Resource Names (URNs): Clarifications
+                and Recommendations
+      RFC 5017: MIB Textual Conventions for Uniform Resource
+                Identifiers (URIs)";
+  }
+
+}
index aae8fa165a2d563f0d749f1827bc032ab141a39a..f484e09d3a54d878eebbef8a4a74c4dff36d26ce 100644 (file)
             <groupId>${project.groupId}</groupId>
             <artifactId>yang-model-api</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.yangtools</groupId>
-            <artifactId>yang-binding</artifactId>
-        </dependency>
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
index e0d8e6cbb96731f3f80e1c673a16caf3d9ae0326..cecc17f8b033355a16d0b587786f91e78bc1350a 100644 (file)
@@ -8,7 +8,7 @@
 package org.opendaylight.yangtools.yang.model.repo.util;
 
 import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
@@ -264,7 +264,7 @@ public final class FilesystemSchemaSourceCache<T extends SchemaSourceRepresentat
             return new YangTextSchemaSource(sourceIdentifier) {
 
                 @Override
-                protected Objects.ToStringHelper addToStringAttributes(final Objects.ToStringHelper toStringHelper) {
+                protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
                     return toStringHelper;
                 }
 
diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/AbstractSchemaContext.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/AbstractSchemaContext.java
new file mode 100644 (file)
index 0000000..e04d72a
--- /dev/null
@@ -0,0 +1,266 @@
+package org.opendaylight.yangtools.yang.model.util;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Supplier;
+import com.google.common.collect.SetMultimap;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+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.TreeSet;
+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.DataSchemaNode;
+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.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.UsesNode;
+
+
+public abstract class AbstractSchemaContext implements SchemaContext {
+
+    protected static final Supplier<TreeSet<Module>> MODULE_SET_SUPPLIER = new Supplier<TreeSet<Module>>() {
+        @Override
+        public TreeSet<Module> get() {
+            return new TreeSet<>(REVISION_COMPARATOR);
+        }
+    };
+
+    protected static final Comparator<Module> REVISION_COMPARATOR = new Comparator<Module>() {
+        @Override
+        public int compare(final Module o1, final Module o2) {
+            if (o2.getRevision() == null) {
+                return -1;
+            }
+
+            return o2.getRevision().compareTo(o1.getRevision());
+        }
+    };
+
+    /**
+     * @return yang sources where key is ModuleIdentifier
+     */
+    protected abstract Map<ModuleIdentifier, String> getIdentifiersToSources();
+
+    /**
+     * @return Map of modules where key is namespace
+     */
+    protected abstract SetMultimap<URI, Module> getNamespaceToModules();
+
+    /**
+     * @return Map of modules where key is name of module
+     */
+    protected abstract SetMultimap<String, Module> getNameToModules();
+
+    @Override
+    public Set<DataSchemaNode> getDataDefinitions() {
+        final Set<DataSchemaNode> dataDefs = new HashSet<>();
+        for (Module m : getModules()) {
+            dataDefs.addAll(m.getChildNodes());
+        }
+        return dataDefs;
+    }
+
+    @Override
+    public Set<NotificationDefinition> getNotifications() {
+        final Set<NotificationDefinition> notifications = new HashSet<>();
+        for (Module m : getModules()) {
+            notifications.addAll(m.getNotifications());
+        }
+        return notifications;
+    }
+
+    @Override
+    public Set<RpcDefinition> getOperations() {
+        final Set<RpcDefinition> rpcs = new HashSet<>();
+        for (Module m : getModules()) {
+            rpcs.addAll(m.getRpcs());
+        }
+        return rpcs;
+    }
+
+    @Override
+    public Set<ExtensionDefinition> getExtensions() {
+        final Set<ExtensionDefinition> extensions = new HashSet<>();
+        for (Module m : getModules()) {
+            extensions.addAll(m.getExtensionSchemaNodes());
+        }
+        return extensions;
+    }
+
+    @Override
+    public Module findModuleByName(final String name, final Date revision) {
+        for (final Module module : getNameToModules().get(name)) {
+            if (revision == null || revision.equals(module.getRevision())) {
+                return module;
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public Set<Module> findModuleByNamespace(final URI namespace) {
+        final Set<Module> ret = getNamespaceToModules().get(namespace);
+        return ret == null ? Collections.<Module>emptySet() : ret;
+    }
+
+    @Override
+    public Module findModuleByNamespaceAndRevision(final URI namespace, final Date revision) {
+        if (namespace == null) {
+            return null;
+        }
+        for (Module module : findModuleByNamespace(namespace)) {
+            if (revision == null || revision.equals(module.getRevision())) {
+                return module;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean isAugmenting() {
+        return false;
+    }
+
+    @Override
+    public boolean isAddedByUses() {
+        return false;
+    }
+
+    @Override
+    public boolean isConfiguration() {
+        return false;
+    }
+
+    @Override
+    public ConstraintDefinition getConstraints() {
+        return null;
+    }
+
+    @Override
+    public QName getQName() {
+        return SchemaContext.NAME;
+    }
+
+    @Override
+    public SchemaPath getPath() {
+        return SchemaPath.ROOT;
+    }
+
+    @Override
+    public String getDescription() {
+        return null;
+    }
+
+    @Override
+    public String getReference() {
+        return null;
+    }
+
+    @Override
+    public Status getStatus() {
+        return Status.CURRENT;
+    }
+
+    @Override
+    public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+        final List<UnknownSchemaNode> result = new ArrayList<>();
+        for (Module module : getModules()) {
+            result.addAll(module.getUnknownSchemaNodes());
+        }
+        return Collections.unmodifiableList(result);
+    }
+
+    @Override
+    public Set<TypeDefinition<?>> getTypeDefinitions() {
+        final Set<TypeDefinition<?>> result = new LinkedHashSet<>();
+        for (Module module : getModules()) {
+            result.addAll(module.getTypeDefinitions());
+        }
+        return Collections.unmodifiableSet(result);
+    }
+
+    @Override
+    public Set<DataSchemaNode> getChildNodes() {
+        final Set<DataSchemaNode> result = new LinkedHashSet<>();
+        for (Module module : getModules()) {
+            result.addAll(module.getChildNodes());
+        }
+        return Collections.unmodifiableSet(result);
+    }
+
+    @Override
+    public Set<GroupingDefinition> getGroupings() {
+        final Set<GroupingDefinition> result = new LinkedHashSet<>();
+        for (Module module : getModules()) {
+            result.addAll(module.getGroupings());
+        }
+        return Collections.unmodifiableSet(result);
+    }
+
+    @Override
+    public DataSchemaNode getDataChildByName(final QName name) {
+        for (Module module : getModules()) {
+            final DataSchemaNode result = module.getDataChildByName(name);
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public DataSchemaNode getDataChildByName(final String name) {
+        for (Module module : getModules()) {
+            final DataSchemaNode result = module.getDataChildByName(name);
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Set<UsesNode> getUses() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public boolean isPresenceContainer() {
+        return false;
+    }
+
+    @Override
+    public Set<AugmentationSchema> getAvailableAugmentations() {
+        return Collections.emptySet();
+    }
+
+    //FIXME: should work for submodules too
+    @Override
+    public Set<ModuleIdentifier> getAllModuleIdentifiers() {
+        return getIdentifiersToSources().keySet();
+    }
+
+    @Override
+    public Optional<String> getModuleSource(final ModuleIdentifier moduleIdentifier) {
+        String maybeSource = getIdentifiersToSources().get(moduleIdentifier);
+        return Optional.fromNullable(maybeSource);
+    }
+
+}
diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/FilteringSchemaContextProxy.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/FilteringSchemaContextProxy.java
new file mode 100644 (file)
index 0000000..3421cad
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.html
+ */
+
+package org.opendaylight.yangtools.yang.model.util;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Strings;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet.Builder;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.TreeMultimap;
+import java.net.URI;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+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;
+
+@Immutable
+public final class FilteringSchemaContextProxy extends AbstractSchemaContext {
+
+    //collection to be filled with filtered modules
+    private final Set<Module> filteredModules;
+
+    //collections to be filled in with filtered data
+    private final Map<ModuleIdentifier, String> identifiersToSources;
+    private final SetMultimap<URI, Module> namespaceToModules;
+    private final SetMultimap<String, Module> nameToModules;
+
+    /**
+     * Filters SchemaContext for yang modules
+     *
+     * @param delegate original SchemaContext
+     * @param rootModules modules (yang schemas) to be available and all their dependencies (modules importing rootModule and whole chain of their imports)
+     * @param additionalModuleIds (additional) modules (yang schemas) to be available and whole chain of their imports
+     *
+     */
+    public FilteringSchemaContextProxy(final SchemaContext delegate, final Collection<ModuleId> rootModules, final Set<ModuleId> additionalModuleIds) {
+
+        Preconditions.checkArgument(rootModules!=null,"Base modules cannot be null.");
+        Preconditions.checkArgument(additionalModuleIds!=null,"Additional modules cannot be null.");
+
+        final Builder<Module> filteredModulesBuilder = new Builder<>();
+
+        final SetMultimap<URI, Module> nsMap = Multimaps.newSetMultimap(new TreeMap<URI, Collection<Module>>(), MODULE_SET_SUPPLIER);
+        final SetMultimap<String, Module> nameMap = Multimaps.newSetMultimap(new TreeMap<String, Collection<Module>>(), MODULE_SET_SUPPLIER);
+
+        ImmutableMap.Builder<ModuleIdentifier, String> identifiersToSourcesBuilder = ImmutableMap.builder();
+
+        //preparing map to get all modules with one name but difference in revision
+        final TreeMultimap<String, Module> nameToModulesAll = getStringModuleTreeMultimap();
+
+        nameToModulesAll.putAll(getStringModuleMap(delegate));
+
+        //in case there is a particular dependancy to view filteredModules/yang models
+        //dependancy is checked for module name and imports
+        processForRootModules(delegate, rootModules, filteredModulesBuilder);
+
+        //adding additional modules
+        processForAdditionalModules(delegate, additionalModuleIds, filteredModulesBuilder);
+
+        filteredModulesBuilder.addAll(getImportedModules(
+                Maps.uniqueIndex(delegate.getModules(), ModuleId.MODULE_TO_MODULE_ID), filteredModulesBuilder.build(), nameToModulesAll));
+
+        /**
+         * Instead of doing this on each invocation of getModules(), pre-compute
+         * it once and keep it around -- better than the set we got in.
+         */
+        this.filteredModules = filteredModulesBuilder.build();
+
+        for (final Module module :filteredModules) {
+            nameMap.put(module.getName(), module);
+            nsMap.put(module.getNamespace(), module);
+            identifiersToSourcesBuilder.put(module, module.getSource());
+        }
+
+        namespaceToModules = ImmutableSetMultimap.copyOf(nsMap);
+        nameToModules = ImmutableSetMultimap.copyOf(nameMap);
+        identifiersToSources = identifiersToSourcesBuilder.build();
+    }
+
+    private static TreeMultimap<String, Module> getStringModuleTreeMultimap() {
+        return TreeMultimap.create(new Comparator<String>() {
+                @Override
+                public int compare(String o1, String o2) {
+                    return o1.compareTo(o2);
+                }
+            }, REVISION_COMPARATOR);
+    }
+
+    private void processForAdditionalModules(SchemaContext delegate, final Set<ModuleId> additionalModuleIds, Builder<Module> filteredModulesBuilder) {
+        filteredModulesBuilder.addAll(Collections2.filter(delegate.getModules(), new Predicate<Module>() {
+            @Override
+            public boolean apply(@Nullable Module module) {
+                return selectAdditionalModules(module, additionalModuleIds);
+            }
+        }));
+    }
+
+    private void processForRootModules(SchemaContext delegate, final Collection<ModuleId> rootModules, Builder<Module> filteredModulesBuilder) {
+        filteredModulesBuilder.addAll(Collections2.filter(delegate.getModules(), new Predicate<Module>() {
+            @Override
+            public boolean apply(@Nullable Module module) {
+                return checkModuleDependency(module, rootModules);
+            }
+        }));
+    }
+
+    private Multimap<String, Module> getStringModuleMap(SchemaContext delegate) {
+        return Multimaps.index(delegate.getModules(), new Function<Module, String>() {
+            @Override
+            public String apply(Module input) {
+                return input.getName();
+            }
+        });
+    }
+
+    //dealing with imported module other than root and directly importing root
+    private static Collection<Module> getImportedModules(Map<ModuleId, Module> allModules, Set<Module> baseModules, TreeMultimap<String, Module> nameToModulesAll) {
+
+        List<Module> relatedModules = Lists.newLinkedList();
+
+        for (Module module : baseModules) {
+            for (ModuleImport moduleImport : module.getImports()) {
+
+                Date revisionDate = moduleImport.getRevision() == null ?
+                        nameToModulesAll.get(moduleImport.getModuleName()).first().getRevision() : moduleImport.getRevision();
+
+                ModuleId key = new ModuleId(moduleImport.getModuleName(),revisionDate);
+                Module importedModule = allModules.get(key);
+
+                Preconditions.checkArgument(importedModule != null,  "Invalid schema, cannot find imported module: %s from module: %s, %s, modules:%s", key, module.getQNameModule(), module.getName() );
+                relatedModules.add(importedModule);
+
+                //calling imports recursive
+                relatedModules.addAll(getImportedModules(allModules, Collections.singleton(importedModule), nameToModulesAll));
+
+            }
+        }
+
+        return relatedModules;
+    }
+
+    @Override
+    protected Map<ModuleIdentifier, String> getIdentifiersToSources() {
+        return identifiersToSources;
+    }
+
+    public Set<Module> getModules() {
+        return filteredModules;
+    }
+
+    @Override
+    protected SetMultimap<URI, Module> getNamespaceToModules() {
+        return namespaceToModules;
+    }
+
+    @Override
+    protected SetMultimap<String, Module> getNameToModules() {
+        return nameToModules;
+    }
+
+    private boolean selectAdditionalModules(Module module, Set<ModuleId> additionalModules){
+
+        if(additionalModules.contains(new ModuleId(module.getName(), module.getRevision()))){
+
+            return true;
+        }
+
+        return false;
+    };
+
+    //check for any dependency regarding given string
+    private boolean checkModuleDependency(Module module, Collection<ModuleId> rootModules) {
+
+        for (ModuleId rootModule : rootModules) {
+
+            if(rootModule.equals(new ModuleId(module.getName(), module.getRevision()))) {
+                return true;
+            }
+
+            //handling/checking imports regarding root modules
+            for (ModuleImport moduleImport : module.getImports()) {
+
+                if(moduleImport.getModuleName().equals(rootModule.getName())) {
+
+                    if(moduleImport.getRevision() != null && !moduleImport.getRevision().equals(rootModule.getRev())) {
+                        return false;
+                    }
+
+                    return true;
+                }
+            }
+
+            //submodules handling
+            for (Module moduleSub : module.getSubmodules()) {
+                return checkModuleDependency(moduleSub, rootModules);
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("SchemaContextProxyImpl{filteredModules=%s}", filteredModules);
+    }
+
+    public static final class ModuleId {
+        private final String name;
+        private final Date rev;
+
+        public ModuleId(String name, Date rev) {
+            Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "No module dependency name given. Nothing to do.");
+            this.name = name;
+            this.rev = Preconditions.checkNotNull(rev, "No revision date given. Nothing to do.");
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public Date getRev() {
+            return rev;
+        }
+
+        public static final Function<Module, ModuleId> MODULE_TO_MODULE_ID = new Function<Module, ModuleId>() {
+            @Override
+            public ModuleId apply(Module input) {
+                return new ModuleId(input.getName(), input.getRevision());
+            }
+        };
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            ModuleId moduleId = (ModuleId) o;
+
+            if (name != null ? !name.equals(moduleId.name) : moduleId.name != null) return false;
+            if (rev != null ? !rev.equals(moduleId.rev) : moduleId.rev != null) return false;
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = name != null ? name.hashCode() : 0;
+            result = 31 * result + (rev != null ? rev.hashCode() : 0);
+            return result;
+        }
+
+        @Override
+        public String toString() {
+
+            return String.format("ModuleId{name='%s', rev=%s}",name,rev);
+        }
+    }
+}
index 1cb9ed77464104d43807d43bf76b43ad9842508f..7b98d2a2fd7c36eaa55dd4be653444fbb2072c4a 100644 (file)
@@ -18,10 +18,9 @@ import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-
 import com.google.common.base.Charsets;
 import com.google.common.base.Function;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Optional;
 import com.google.common.collect.Collections2;
 import com.google.common.io.Files;
@@ -152,7 +151,7 @@ public class FilesystemSchemaSourceCacheTest {
         }
 
         @Override
-        protected Objects.ToStringHelper addToStringAttributes(final Objects.ToStringHelper toStringHelper) {
+        protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
             return toStringHelper;
         }
 
diff --git a/yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/SchemaContextProxyTest.java b/yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/SchemaContextProxyTest.java
new file mode 100644 (file)
index 0000000..e9a34d8
--- /dev/null
@@ -0,0 +1,540 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.html
+ */
+
+package org.opendaylight.yangtools.yang.model.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import com.google.common.collect.Sets;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.ParseException;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.util.FilteringSchemaContextProxy.ModuleId;
+
+public class SchemaContextProxyTest {
+
+    private static URI namespace;
+    private static Date revision;
+    private static Date revision2;
+
+    private static final String CONFIG_NAME = "config";
+    private static final String ROOT_NAME = "root";
+    private static final String MODULE2_NAME = "module2";
+    private static final String MODULE3_NAME = "module3";
+    private static final String MODULE4_NAME = "module4";
+    private static final String MODULE41_NAME = "module41";
+    private static final String MODULE5_NAME = "module5";
+    private static final String TEST_SOURCE = "test source";
+
+    @BeforeClass
+    public static void setUp() throws ParseException, URISyntaxException {
+
+        namespace = new URI("urn:opendaylight:params:xml:ns:yang:controller:config");
+
+        revision = SimpleDateFormatUtil.getRevisionFormat().parse("2015-01-01");
+        revision2 = SimpleDateFormatUtil.getRevisionFormat().parse("2015-01-15");
+    }
+
+    private SchemaContext mockSchema(Module... module) {
+
+        SchemaContext mock = mock(SchemaContext.class);
+        doReturn(Sets.newHashSet(module)).when(mock).getModules();
+        return mock;
+    }
+
+    /**
+     * <pre>
+     * CFG(R)
+     *  | \
+     *  |  \
+     * M2 <- M3
+     * </pre>
+     */
+    @Test
+    public void testBasic() {
+        Module moduleConfig = mockModule(CONFIG_NAME);
+        Module module2 = mockModule(MODULE2_NAME);
+        Module module3 = mockModule(MODULE3_NAME);
+
+        mockModuleImport(module2, moduleConfig);
+        mockModuleImport(module3, module2, moduleConfig);
+
+        SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3);
+
+        FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+        assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
+    }
+
+    /**
+     * <pre>
+     * No root or additional modules
+     *  | \
+     *  |  \
+     * M2 <- M3
+     * </pre>
+     */
+    @Test
+    public void testNull() {
+        Module moduleConfig = mockModule(CONFIG_NAME);
+        Module module2 = mockModule(MODULE2_NAME);
+        Module module3 = mockModule(MODULE3_NAME);
+
+        mockModuleImport(module2, moduleConfig);
+        mockModuleImport(module3, module2, moduleConfig);
+
+        SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3);
+
+        FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, null);
+        assertProxyContext(filteringSchemaContextProxy, null);
+    }
+
+    /**
+     * <pre>
+     *  Config
+     *  | \ (NR)
+     *  |  \
+     * M2 <- M3
+     * </pre>
+     */
+    @Test
+    public void testConfigDifferentRevisions() {
+        Module moduleConfigNullRevision = mockModule(CONFIG_NAME, null);
+        Module moduleConfig = mockModule(CONFIG_NAME, revision);
+        Module moduleConfig2 = mockModule(CONFIG_NAME, revision2);
+        Module module2 = mockModule(MODULE2_NAME);
+        Module module3 = mockModule(MODULE3_NAME);
+
+        mockModuleImport(module2, moduleConfig);
+        mockModuleImport(module3, module2, moduleConfigNullRevision);
+
+        SchemaContext schemaContext = mockSchema(moduleConfig, moduleConfig2, module2, module3);
+
+        FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+        assertProxyContext(filteringSchemaContextProxy, moduleConfig, moduleConfig2, module2, module3);
+    }
+
+    /**
+     * <pre>
+     *     CFG(R)
+     *    |      \
+     *   |         \
+     * M2<-(NullRev)M3
+     * </pre>
+     */
+    @Test
+    public void testBasicNullRevision() throws Exception {
+        Module moduleConfig = mockModule(CONFIG_NAME,SimpleDateFormatUtil.getRevisionFormat().parse("2013-04-05"));
+        Module module2 = mockModule(MODULE2_NAME, SimpleDateFormatUtil.getRevisionFormat().parse("2014-06-17"));
+        Module module20 = mockModule(MODULE2_NAME, null);
+        Module module3 = mockModule(MODULE3_NAME, SimpleDateFormatUtil.getRevisionFormat().parse("2014-06-12"));
+        Module module30 = mockModule(MODULE3_NAME, null);
+
+        mockModuleImport(module20, moduleConfig);
+        mockModuleImport(module2, moduleConfig);
+        mockModuleImport(module3, module20, moduleConfig);
+        mockModuleImport(module30, module20, moduleConfig);
+
+        SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3);
+
+        FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+
+        assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
+    }
+
+    /**
+     * <pre>
+     * CFG(R)   ROOT(R)
+     *  |         \
+     *  |          \
+     * M2          M3
+     * </pre>
+     */
+    @Test
+    public void testBasicMoreRootModules() {
+        Module moduleConfig = mockModule(CONFIG_NAME);
+        Module moduleRoot = mockModule(ROOT_NAME);
+        Module module2 = mockModule(MODULE2_NAME);
+        Module module3 = mockModule(MODULE3_NAME);
+
+        mockModuleImport(module2, moduleConfig);
+        mockModuleImport(module3, moduleRoot);
+
+        SchemaContext schemaContext = mockSchema(moduleConfig, moduleRoot, module2, module3);
+
+        FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleRoot, moduleConfig);
+        assertProxyContext(filteringSchemaContextProxy, moduleRoot, module3, moduleConfig, module2);
+    }
+
+    /**
+     * <pre>
+     * CFG(R)
+     *  |
+     *  |
+     * M2 <- M3
+     * </pre>
+     */
+    @Test
+    public void testChainNotDepend() {
+        Module moduleConfig = mockModule(CONFIG_NAME);
+        Module module2 = mockModule(MODULE2_NAME);
+        Module module3 = mockModule(MODULE3_NAME);
+
+        mockModuleImport(module2, moduleConfig);
+        mockModuleImport(module3, module2);
+
+        SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3);
+
+        FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+        assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2);
+    }
+
+    /**
+     * <pre>
+     * CFG(R)
+     *  |
+     *  |
+     * M2 -> M3 -> M4 -> M5
+     * </pre>
+     */
+    @Test
+    public void testChainDependMulti() {
+        Module moduleConfig = mockModule(CONFIG_NAME);
+        Module module2 = mockModule(MODULE2_NAME);
+        Module module3 = mockModule(MODULE3_NAME);
+        Module module4 = mockModule(MODULE4_NAME);
+        Module module5 = mockModule(MODULE5_NAME);
+
+        mockModuleImport(module2, moduleConfig, module3);
+        mockModuleImport(module3, module4);
+        mockModuleImport(module4, module5);
+
+        SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4, module5);
+
+        FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+        assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4, module5);
+    }
+
+    /**
+     * <pre>
+     * CFG(R)
+     *  |
+     *  |
+     * M2 -> M3 <- M4
+     * </pre>
+     */
+    @Test
+    public void testChainNotDependMulti() {
+        Module moduleConfig = mockModule(CONFIG_NAME);
+        Module module2 = mockModule(MODULE2_NAME);
+        Module module3 = mockModule(MODULE3_NAME);
+        Module module4 = mockModule(MODULE4_NAME);
+
+        mockModuleImport(module2, moduleConfig, module3);
+        mockModuleImport(module4, module3);
+
+        SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4);
+
+        FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+        assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
+    }
+
+    /**
+     * <pre>
+     *  CFG(R)
+     *  | \ \ \
+     *  |  \ \ \
+     * M2 M3 M4 M5
+     * </pre>
+     */
+    @Test
+    public void testChainNotMulti() {
+        Module moduleConfig = mockModule(CONFIG_NAME);
+        Module module2 = mockModule(MODULE2_NAME);
+        Module module3 = mockModule(MODULE3_NAME);
+        Module module4 = mockModule(MODULE4_NAME);
+        Module module5 = mockModule(MODULE5_NAME);
+
+        mockModuleImport(module2, moduleConfig);
+        mockModuleImport(module3, moduleConfig);
+        mockModuleImport(module4, moduleConfig);
+        mockModuleImport(module5, moduleConfig);
+
+        SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4, module5);
+
+        FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+        assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4, module5);
+    }
+
+    /**
+     * <pre>
+     * CFG(R)
+     *  | \
+     *  |  \
+     * M2 <- M3 M4=M3(Different revision)
+     * </pre>
+     */
+    @Test
+    public void testBasicRevisionChange() throws Exception {
+        Module moduleConfig = mockModule(CONFIG_NAME);
+        Module module2 = mockModule(MODULE2_NAME);
+        Module module3 = mockModule(MODULE3_NAME);
+
+        Date dat = SimpleDateFormatUtil.getRevisionFormat().parse("2015-10-10");
+        Module module4 = mockModule(MODULE3_NAME, dat);
+
+        mockModuleImport(module2, moduleConfig);
+        mockModuleImport(module3, module2, moduleConfig);
+
+        SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4);
+
+        FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+        assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
+    }
+
+    /**
+     * <pre>
+     * CFG(R)
+     * |
+     * M2 -(no revision)-> M3(R2) ... M3(R1)
+     * </pre>
+     */
+    @Test
+    public void testImportNoRevision() throws Exception {
+        Module moduleConfig = mockModule(CONFIG_NAME, revision);
+        Module module2 = mockModule(MODULE2_NAME, revision);
+
+        Module module3  = mockModule(MODULE3_NAME, null);
+        Module module30 = mockModule(MODULE3_NAME, revision);
+        Module module31 = mockModule(MODULE3_NAME, revision2);
+        mockModuleImport(module2, moduleConfig, module3);
+
+        SchemaContext schemaContext = mockSchema(moduleConfig, module2, module30, module31);
+
+        FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+
+        assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module31);
+    }
+
+    /**
+     * <pre>
+     * CFG(R)
+     * |   \
+     * |    \
+     * |    M2 -> M3
+     * |
+     * M41(S) => M4
+     * </pre>
+     */
+    @Test
+    public void testBasicSubmodule() throws Exception {
+        Module moduleConfig = mockModule(CONFIG_NAME);
+        Module module2 = mockModule(MODULE2_NAME);
+        Module module3 = mockModule(MODULE3_NAME);
+        Module module4 = mockModule(MODULE4_NAME);
+        Module module41 = mockModule(MODULE41_NAME);
+
+        mockSubmodules(module4, module41);
+        mockModuleImport(module2, moduleConfig, module3);
+        mockModuleImport(module41, moduleConfig);
+
+        SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4);
+
+        FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+        assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4);
+    }
+
+    /**
+     * <pre>
+     *
+     * M2 -> M3 -> M4 -> M5
+     *
+     * </pre>
+     */
+    @Test
+    public void testChainAdditionalModules() {
+        Module module2 = mockModule(MODULE2_NAME);
+        Module module3 = mockModule(MODULE3_NAME);
+        Module module4 = mockModule(MODULE4_NAME);
+        Module module5 = mockModule(MODULE5_NAME);
+
+        mockModuleImport(module2, module3);
+        mockModuleImport(module3, module4);
+        mockModuleImport(module4, module5);
+
+        SchemaContext schemaContext = mockSchema(module2, module3, module4, module5);
+
+        FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Sets.newHashSet(module2), null);
+        assertProxyContext(filteringSchemaContextProxy, module2, module3, module4, module5);
+    }
+
+    /**
+     * <pre>
+     *
+     * CFG(R)
+     *  |
+     *  |       M5
+     * M2
+     *
+     * M3 -> M4
+     *
+     * </pre>
+     */
+    @Test
+    public void testChainAdditionalModulesConfig() {
+        Module moduleConfig = mockModule(CONFIG_NAME);
+        Module module2 = mockModule(MODULE2_NAME);
+
+        Module module3 = mockModule(MODULE3_NAME);
+        Module module4 = mockModule(MODULE4_NAME);
+        Module module5 = mockModule(MODULE5_NAME);
+
+        mockModuleImport(module2, moduleConfig);
+        mockModuleImport(module3, module4);
+
+        SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4, module5);
+
+        FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Sets.newHashSet(module3), moduleConfig);
+        assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4);
+    }
+
+    private void assertProxyContext(FilteringSchemaContextProxy filteringSchemaContextProxy, Module... expected) {
+
+        Set<Module> modSet = Sets.newHashSet();
+
+        if(expected!=null) {
+
+            modSet = Sets.newHashSet(expected);
+        }
+
+        Set<Module> modSetFiltering = filteringSchemaContextProxy.getModules();
+
+        assertEquals(modSet, modSetFiltering);
+
+        //asserting collections
+        if(expected!=null) {
+            for (final Module module : expected) {
+                assertEquals(module, filteringSchemaContextProxy.findModuleByName(module.getName(), module.getRevision()));
+
+                Set<Module> mod = filteringSchemaContextProxy.findModuleByNamespace(module.getNamespace());
+                assertTrue(mod.contains(module));
+
+                assertEquals(module, filteringSchemaContextProxy.findModuleByNamespaceAndRevision(module.getNamespace(), module.getRevision()));
+
+                assertEquals(module.getSource(), filteringSchemaContextProxy.getModuleSource(module).get());
+            }
+        }
+    }
+
+    private FilteringSchemaContextProxy createProxySchemaCtx(SchemaContext schemaContext, Set<Module> additionalModules, Module... modules) {
+
+        Set<Module> modulesSet = new HashSet();
+
+        if(modules!=null) {
+
+            modulesSet = Sets.newHashSet(modules);
+
+        }
+
+        return new FilteringSchemaContextProxy(schemaContext, createModuleIds(modulesSet) , createModuleIds(additionalModules));
+    }
+
+    private Set<ModuleId> createModuleIds(Set<Module> modules) {
+
+        Set<ModuleId> moduleIds = Sets.newHashSet();
+
+        if(modules!=null && modules.size()>0) {
+
+            for (Module module : modules) {
+
+                moduleIds.add(new ModuleId(module.getName(), module.getRevision()));
+            }
+        }
+
+        return moduleIds;
+    }
+
+    private void mockSubmodules(Module mainModule, Module... submodules){
+
+        Set<Module> submodulesSet = new HashSet<>();
+        submodulesSet.addAll(Arrays.asList(submodules));
+
+        doReturn(submodulesSet).when(mainModule).getSubmodules();
+    }
+
+    private void mockModuleImport(Module importer, Module... imports) {
+        Set<ModuleImport> mockedImports = Sets.newHashSet();
+        for (final Module module : imports) {
+            mockedImports.add(new ModuleImport() {
+                @Override
+                public String getModuleName() {
+                    return module.getName();
+                }
+
+                @Override
+                public Date getRevision() {
+                    return module.getRevision();
+                }
+
+                @Override
+                public String getPrefix() {
+                    return module.getName();
+                }
+
+                @Override
+                public String toString() {
+
+                    return String.format("Module: %s, revision:%s", module.getName(), module.getRevision());
+                }
+            });
+        }
+        doReturn(mockedImports).when(importer).getImports();
+    }
+
+    //mock module with revision
+    private Module mockModule(String name, final Date rev){
+
+        final Module mod = mockModule(name);
+
+        doReturn(QNameModule.create(mod.getNamespace(), rev)).when(mod).getQNameModule();
+        doReturn(rev).when(mod).getRevision();
+        doReturn(mod.getQNameModule().toString()).when(mod).toString();
+
+        return mod;
+    }
+
+    //mock module with default revision
+    private Module mockModule(String mName) {
+
+        Module mockedModule = mock(Module.class);
+        doReturn(mName).when(mockedModule).getName();
+        doReturn(revision).when(mockedModule).getRevision();
+        final URI newNamespace = URI.create(namespace.toString() + ":" + mName);
+        doReturn(newNamespace).when(mockedModule).getNamespace();
+        doReturn(QNameModule.create(newNamespace, revision)).when(mockedModule).getQNameModule();
+        doReturn(TEST_SOURCE).when(mockedModule).getSource();
+        doReturn(Sets.newHashSet()).when(mockedModule).getSubmodules();
+        doReturn(mockedModule.getQNameModule().toString()).when(mockedModule).toString();
+        mockModuleImport(mockedModule);
+
+        return mockedModule;
+    }
+}
index 0ca3d88b276ce03c509f8a2705cd469603592de1..55cf82726d8d104a4d9c32facff1bcf6d77bc6ab 100644 (file)
@@ -202,7 +202,7 @@ public final class CopyUtils {
         }
 
         if (old.getType() == null) {
-            copy.setTypedef(copy(old.getTypedef(), copy, updateQName));
+            copy.setTypedef(old.getTypedef());
         } else {
             copy.setType(old.getType());
         }
@@ -235,7 +235,7 @@ public final class CopyUtils {
         }
 
         if (old.getType() == null) {
-            copy.setTypedef(copy(old.getTypedef(), copy, updateQName));
+            copy.setTypedef(old.getTypedef());
         } else {
             copy.setType(old.getType());
         }
index 5a4bb3df25aa69fd2324b7def8dd1a59c69339ee..652011a2250d681bc0e81b22650dd143a93a021d 100644 (file)
@@ -7,80 +7,40 @@
  */
 package org.opendaylight.yangtools.yang.parser.impl;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSetMultimap;
 import com.google.common.collect.Multimaps;
 import com.google.common.collect.SetMultimap;
 import java.net.URI;
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-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;
-import java.util.TreeSet;
 import javax.annotation.concurrent.Immutable;
-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.DataSchemaNode;
-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.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.UsesNode;
+import org.opendaylight.yangtools.yang.model.util.AbstractSchemaContext;
 import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
 
 @Immutable
-final class SchemaContextImpl implements SchemaContext {
-    private static final Comparator<Module> REVISION_COMPARATOR = new Comparator<Module>() {
-        @Override
-        public int compare(final Module o1, final Module o2) {
-            if (o2.getRevision() == null) {
-                return -1;
-            }
+final class SchemaContextImpl extends AbstractSchemaContext {
 
-            return o2.getRevision().compareTo(o1.getRevision());
-        }
-    };
-
-    private static final Supplier<TreeSet<Module>> MODULE_SET_SUPPLIER = new Supplier<TreeSet<Module>>() {
-        @Override
-        public TreeSet<Module> get() {
-            return new TreeSet<>(REVISION_COMPARATOR);
-        }
-    };
-
-    private final Map<ModuleIdentifier, String> identifiersToSources;
-    private final SetMultimap<URI, Module> namespaceToModules;
-    private final SetMultimap<String, Module> nameToModules;
-    private final Set<Module> modules;
+    private  final Map<ModuleIdentifier, String> identifiersToSources;
+    private  final SetMultimap<URI, Module> namespaceToModules;
+    private  final SetMultimap<String, Module> nameToModules;
+    private  final Set<Module> modules;
 
     SchemaContextImpl(final Set<Module> modules, final Map<ModuleIdentifier, String> identifiersToSources) {
         this.identifiersToSources = ImmutableMap.copyOf(identifiersToSources);
 
-        /*
+         /*
          * Instead of doing this on each invocation of getModules(), pre-compute
          * it once and keep it around -- better than the set we got in.
          */
         this.modules = ImmutableSet.copyOf(ModuleDependencySort.sort(modules.toArray(new Module[modules.size()])));
 
-        /*
+         /*
          * The most common lookup is from Namespace->Module.
          *
          * RESTCONF performs lookups based on module name only, where it wants
@@ -92,6 +52,7 @@ final class SchemaContextImpl implements SchemaContext {
                 new TreeMap<URI, Collection<Module>>(), MODULE_SET_SUPPLIER);
         final SetMultimap<String, Module> nameMap = Multimaps.newSetMultimap(
                 new TreeMap<String, Collection<Module>>(), MODULE_SET_SUPPLIER);
+
         for (Module m : modules) {
             nameMap.put(m.getName(), m);
             nsMap.put(m.getNamespace(), m);
@@ -102,210 +63,32 @@ final class SchemaContextImpl implements SchemaContext {
     }
 
     @Override
-    public Set<DataSchemaNode> getDataDefinitions() {
-        final Set<DataSchemaNode> dataDefs = new HashSet<>();
-        for (Module m : modules) {
-            dataDefs.addAll(m.getChildNodes());
-        }
-        return dataDefs;
-    }
-
-    @Override
-    public Set<Module> getModules() {
-        return modules;
-    }
-
-    @Override
-    public Set<NotificationDefinition> getNotifications() {
-        final Set<NotificationDefinition> notifications = new HashSet<>();
-        for (Module m : modules) {
-            notifications.addAll(m.getNotifications());
-        }
-        return notifications;
-    }
-
-    @Override
-    public Set<RpcDefinition> getOperations() {
-        final Set<RpcDefinition> rpcs = new HashSet<>();
-        for (Module m : modules) {
-            rpcs.addAll(m.getRpcs());
-        }
-        return rpcs;
-    }
-
-    @Override
-    public Set<ExtensionDefinition> getExtensions() {
-        final Set<ExtensionDefinition> extensions = new HashSet<>();
-        for (Module m : modules) {
-            extensions.addAll(m.getExtensionSchemaNodes());
-        }
-        return extensions;
-    }
-
-    @Override
-    public Module findModuleByName(final String name, final Date revision) {
-        for (final Module module : nameToModules.get(name)) {
-            if (revision == null || revision.equals(module.getRevision())) {
-                return module;
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public Set<Module> findModuleByNamespace(final URI namespace) {
-        final Set<Module> ret = namespaceToModules.get(namespace);
-        return ret == null ? Collections.<Module>emptySet() : ret;
-    }
-
-    @Override
-    public Module findModuleByNamespaceAndRevision(final URI namespace, final Date revision) {
-        if (namespace == null) {
-            return null;
-        }
-        for (Module module : findModuleByNamespace(namespace)) {
-            if (revision == null || revision.equals(module.getRevision())) {
-                return module;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public boolean isAugmenting() {
-        return false;
-    }
-
-    @Override
-    public boolean isAddedByUses() {
-        return false;
-    }
-
-    @Override
-    public boolean isConfiguration() {
-        return false;
-    }
-
-    @Override
-    public ConstraintDefinition getConstraints() {
-        return null;
-    }
-
-    @Override
-    public QName getQName() {
-        return SchemaContext.NAME;
-    }
-
-    @Override
-    public SchemaPath getPath() {
-        return SchemaPath.ROOT;
-    }
-
-    @Override
-    public String getDescription() {
-        return null;
-    }
-
-    @Override
-    public String getReference() {
-        return null;
-    }
-
-    @Override
-    public Status getStatus() {
-        return Status.CURRENT;
-    }
+    protected Map<ModuleIdentifier, String> getIdentifiersToSources(){
 
-    @Override
-    public List<UnknownSchemaNode> getUnknownSchemaNodes() {
-        final List<UnknownSchemaNode> result = new ArrayList<>();
-        for (Module module : modules) {
-            result.addAll(module.getUnknownSchemaNodes());
-        }
-        return Collections.unmodifiableList(result);
+        return identifiersToSources;
     }
 
     @Override
-    public Set<TypeDefinition<?>> getTypeDefinitions() {
-        final Set<TypeDefinition<?>> result = new LinkedHashSet<>();
-        for (Module module : modules) {
-            result.addAll(module.getTypeDefinitions());
-        }
-        return Collections.unmodifiableSet(result);
-    }
+    public Set<Module> getModules(){
 
-    @Override
-    public Set<DataSchemaNode> getChildNodes() {
-        final Set<DataSchemaNode> result = new LinkedHashSet<>();
-        for (Module module : modules) {
-            result.addAll(module.getChildNodes());
-        }
-        return Collections.unmodifiableSet(result);
-    }
-
-    @Override
-    public Set<GroupingDefinition> getGroupings() {
-        final Set<GroupingDefinition> result = new LinkedHashSet<>();
-        for (Module module : modules) {
-            result.addAll(module.getGroupings());
-        }
-        return Collections.unmodifiableSet(result);
-    }
-
-    @Override
-    public DataSchemaNode getDataChildByName(final QName name) {
-        for (Module module : modules) {
-            final DataSchemaNode result = module.getDataChildByName(name);
-            if (result != null) {
-                return result;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public DataSchemaNode getDataChildByName(final String name) {
-        for (Module module : modules) {
-            final DataSchemaNode result = module.getDataChildByName(name);
-            if (result != null) {
-                return result;
-            }
-        }
-        return null;
+        return modules;
     }
 
     @Override
-    public Set<UsesNode> getUses() {
-        return Collections.emptySet();
-    }
+    protected SetMultimap<URI, Module> getNamespaceToModules() {
 
-    @Override
-    public boolean isPresenceContainer() {
-        return false;
+        return namespaceToModules;
     }
 
     @Override
-    public Set<AugmentationSchema> getAvailableAugmentations() {
-        return Collections.emptySet();
-    }
+    protected SetMultimap<String, Module> getNameToModules() {
 
-    //FIXME: should work for submodules too
-    @Override
-    public Set<ModuleIdentifier> getAllModuleIdentifiers() {
-        return identifiersToSources.keySet();
-    }
-
-    @Override
-    public Optional<String> getModuleSource(final ModuleIdentifier moduleIdentifier) {
-        String maybeSource = identifiersToSources.get(moduleIdentifier);
-        return Optional.fromNullable(maybeSource);
+        return nameToModules;
     }
 
     @Override
     public String toString() {
-        return "SchemaContextImpl{" +
-                "modules=" + modules +
-                '}';
+
+        return String.format("SchemaContextImpl{modules=%s}", modules);
     }
 }
index 39dfbc9222bd7b3a27cc753de40fcc75c32dbeec..77a0a354dfa341e69805bdf0769eaa46358cb3f0 100644 (file)
@@ -816,6 +816,10 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             } else if (childNode instanceof Key_stmtContext) {
                 final Set<String> key = createListKey((Key_stmtContext) childNode);
                 builder.setKeys(key);
+            } else if (childNode instanceof YangParser.Identifier_stmtContext) {
+                if (childNode.getChild(0).toString().equals("union")) {
+                    throw new YangParseException(moduleName, line, "Union statement is not allowed inside a list statement");
+                }
             }
         }
     }
index 0f7de6e7d27905211165963c06baa92c5942454b..a96ac87991df986fc10a1d792697594d8baa4fa1 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.parser.repo;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ArrayListMultimap;
@@ -210,7 +210,7 @@ final class DependencyResolver {
 
         @Override
         public String toString() {
-            return Objects.toStringHelper(this)
+            return MoreObjects.toStringHelper(this)
                     .add("parent", parent)
                     .toString();
         }
index 02497a880921dc19edf213ea25e36d09d58fcead..97d0c64c51128af9f2798b4af83b5bae5bcbcc9b 100644 (file)
@@ -8,9 +8,8 @@
 package org.opendaylight.yangtools.yang.parser.repo;
 
 import static com.google.common.base.Preconditions.checkArgument;
-
 import com.google.common.annotations.Beta;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ArrayListMultimap;
@@ -18,14 +17,12 @@ import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Multimap;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 import java.util.Collection;
 import java.util.concurrent.ConcurrentLinkedDeque;
 import java.util.concurrent.atomic.AtomicReference;
-
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
 import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractDeclaredStatement.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractDeclaredStatement.java
new file mode 100644 (file)
index 0000000..01ca560
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import java.util.Collection;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
+
+/**
+ * Utility abstract base class for implementing declared statements.
+ *
+ *
+ * @param <A> Argument type.
+ */
+public abstract class AbstractDeclaredStatement<A> implements DeclaredStatement<A> {
+
+
+    private final A argument;
+    private final String rawArgument;
+    private final ImmutableList<? extends DeclaredStatement<?>> substatements;
+    private final StatementDefinition definition;
+    private final StatementSource source;
+
+    protected AbstractDeclaredStatement(StmtContext<A,?,?> context) {
+        rawArgument = context.rawStatementArgument();
+        argument = context.getStatementArgument();
+        source = context.getStatementSource();
+        definition = context.getPublicDefinition();
+        /*
+         *  Collections.transform could not be used here, since it is lazily
+         *  transformed and retains pointer to original collection, which may
+         *  contains references to mutable context.
+         *
+         *  FluentIterable.tranform().toList() - actually performs transformation
+         *  and creates immutable list from transformed results.
+         */
+        substatements = FluentIterable.from(context.declaredSubstatements()).transform(StmtContextUtils.buildDeclared()).toList();
+    }
+
+    protected final <S extends DeclaredStatement<?>> S firstDeclared(Class<S> type) {
+        return type.cast(Iterables.find(substatements, Predicates.instanceOf(type)));
+    }
+
+    @Override
+    public String rawArgument() {
+        return rawArgument;
+    }
+
+    @Override
+    public A argument() {
+        return argument;
+    }
+
+    @Override
+    public StatementDefinition statementDefinition() {
+        return definition;
+    }
+
+    @Override
+    public Collection<? extends DeclaredStatement<?>> declaredSubstatements() {
+        return substatements;
+    }
+
+    @Override
+    public StatementSource getStatementSource() {
+        return source;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected final <S extends DeclaredStatement<?>> Collection<? extends S> allDeclared(Class<S> type) {
+        return Collection.class.cast(Collections2.filter(substatements,Predicates.instanceOf(type)));
+    }
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractStatementSupport.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractStatementSupport.java
new file mode 100644 (file)
index 0000000..b891518
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+
+/**
+ *
+ * Class providing necessary support for processing YANG statement.
+ *
+ * This class is intended to be subclassed by developers, which want to
+ * introduce support of statement to parser.
+ *
+ * @param <A>
+ *            Argument type
+ * @param <D>
+ *            Declared Statement representation
+ * @param <E>
+ *            Effective Statement representation
+ */
+public abstract class AbstractStatementSupport<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
+        implements StatementDefinition, StatementFactory<A, D, E>, StatementSupport<A, D, E> {
+
+    private final StatementDefinition type;
+
+    protected AbstractStatementSupport(StatementDefinition publicDefinition) {
+        Preconditions.checkArgument(publicDefinition != this);
+        this.type = Preconditions.checkNotNull(publicDefinition);
+    }
+
+    @Override
+    public final QName getStatementName() {
+        return type.getStatementName();
+    }
+
+    @Override
+    public final QName getArgumentName() {
+        return type.getArgumentName();
+    }
+
+    @Override
+    public final Class<? extends DeclaredStatement<?>> getDeclaredRepresentationClass() {
+        return type.getDeclaredRepresentationClass();
+    }
+
+    @Override
+    public final Class<? extends DeclaredStatement<?>> getEffectiveRepresentationClass() {
+        return type.getEffectiveRepresentationClass();
+    }
+
+    @Override
+    public final StatementDefinition getPublicView() {
+        return type;
+    }
+
+    @Override
+    public abstract A parseArgumentValue(StmtContext<?, ?, ?> ctx, String value) throws SourceException;
+
+    @Override
+    public void onStatementAdded(StmtContext.Mutable<A, D, E> stmt) {
+        // NOOP for most implementations
+    };
+
+    /**
+     *
+     * {@inheritDoc}
+     *
+     * Subclasses of this class may override this method to perform actions on
+     * this event or register modification action using
+     * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
+     *
+     */
+    @Override
+    public void onLinkageDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException, SourceException {
+        // NOOP for most implementations
+    }
+
+    /**
+     *
+     * {@inheritDoc}
+     *
+     * Subclasses of this class may override this method to perform actions on
+     * this event or register modification action using
+     * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
+     *
+     */
+    @Override
+    public void onStatementDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException,
+            SourceException {
+        // NOOP for most implementations
+    }
+
+    /**
+     *
+     * {@inheritDoc}
+     *
+     * Subclasses of this class may override this method to perform actions on
+     * this event or register modification action using
+     * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
+     *
+     */
+    @Override
+    public void onFullDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException, SourceException {
+        // NOOP for most implementations
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ImportedNamespaceContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ImportedNamespaceContext.java
new file mode 100644 (file)
index 0000000..6197562
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+
+/**
+ *
+ * Special namespace which allows import of namespaces from other sources.
+ *
+ * <p>
+ * This namespace and its subclasses are used by model processor to
+ * link / import namespaces to context node from supplied {@link StmtContext}.
+ * <p>
+ * This abstraction allows for imports and includes be implement as derived
+ * namespaces of this, but is not tied only for import and include statements.
+ *
+ * @param <K> Imported context identifier
+ */
+public interface ImportedNamespaceContext<K> extends IdentifierNamespace<K, StmtContext<?, ?, ?>> {
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/InferenceException.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/InferenceException.java
new file mode 100644 (file)
index 0000000..8e5cce1
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
+
+/**
+ *
+ * Thrown when there was inference error
+ *
+ */
+public class InferenceException extends SourceException {
+
+
+    private static final long serialVersionUID = 1L;
+
+    public InferenceException(@Nonnull String message, @Nonnull StatementSourceReference source, Throwable cause) {
+        super(message, source, cause);
+    }
+
+    public InferenceException(@Nonnull String message, @Nonnull StatementSourceReference source) {
+        super(message, source);
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelActionBuilder.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelActionBuilder.java
new file mode 100644 (file)
index 0000000..68e4a51
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Supplier;
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
+
+
+/**
+ * Builder for effective model inference action.
+ *
+ * Model inference action is core principle of transforming
+ * declared model into effective model.
+ *
+ * Since YANG allows forward references, some inference actions
+ * needs to be taken at later point, where reference is actually
+ * resolved. Referenced objects are not retrieved directly
+ * but are represented as {@link Prerequisite} (prerequisite) for
+ * inference action to be taken.
+ *
+ * Some existing YANG statements are more complex and also object,
+ * for which effective model may be inferred is also represented
+ * as {@link Prerequisite} which once, when reference is available
+ * will contain target context, which may be used for inference
+ * action.
+ *
+ * <h2>Implementing inference action</h2>
+ *
+ * Effective inference action could always be splitted into two
+ * separate tasks:
+ * <ol>
+ * <li>Declaration of inference action and its prerequisites</li>
+ * <li>Execution of inference action</li>
+ * </ol>
+ * In order to declare inference action following steps needs
+ * to be taken:
+ *
+ * <ol>
+ * <li>Use {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)} to obtain
+ * {@link ModelActionBuilder}.
+ * <li>Use builder to specify concrete prerequisites of inference action
+ * (other statements, values from identifier namespaces)
+ * <li>Use builder to specify concrete set of nodes (or forward references to nodes)
+ * which will inference action mutate.
+ * <li>Use {@link #apply(InferenceAction)} with {@link InferenceAction} implementation
+ * to register inference action.
+ * </ol>
+ *
+ * Action will be executed when:
+ * <ul>
+ * <li> {@link InferenceAction#apply()} - all prerequisites (and declared forward references) are met,
+ * action could dereference them and start applying changes.
+ * </li>
+ * <li>{@link InferenceAction#prerequisiteFailed(Collection)} - semantic parser finished all other satisfied
+ * inference actions and some of declared prerequisites was still not met.
+ * </li>
+ * </ul>
+ *
+ * TODO: Insert real word example
+ *
+ * <h2>Design notes</h2>
+ * {@link java.util.concurrent.Future} seems as viable and more standard
+ * alternative to {@link Prerequisite}, but futures also carries
+ * promise that resolution of it is carried in other
+ * thread, which will actually put additional constraints on
+ * semantic parser.
+ *
+ * Also listening on multiple futures is costly, so we opted
+ * out of future and designed API, which later may introduce
+ * futures.
+ *
+ */
+public interface ModelActionBuilder {
+
+    public interface Prerequisite<T> extends Supplier<T> {
+
+        /**
+         *
+         * Returns associated prerequisite once it is resolved.
+         *
+         * @return associated prerequisite once it is resolved.
+         *
+         */
+        @Override
+        public T get();
+
+        boolean isDone();
+
+    }
+
+    /**
+     * User-defined inference action.
+     *
+     */
+    public interface InferenceAction {
+
+        /**
+         * Invoked once all prerequisites were met and forward references
+         * were resolved and inference action should be applied.
+         *
+         * Implementors may do necessary changes to mutable objects
+         * which were declared.
+         *
+         * @throws InferenceException If inference action can not be processed.
+         *      Note that this exception be used for user to debug YANG sources,
+         *      so should provide helpful context to fix issue in sources.
+         */
+        void apply() throws InferenceException;
+
+        /**
+         * Invoked once one of prerequisites was not met,
+         * even after all other satifiable inference actions were processed.
+         *
+         * Implementors MUST throw {@link InferenceException} if semantic processing
+         * of model should be stopped and failed.
+         *
+         * List of failed prerequisites should be used to select right message / error
+         * type to debug problem in YANG sources.
+         *
+         * @throws InferenceException If inference action can not be processed.
+         *      Note that this exception be used for user to debug YANG sources,
+         *      so should provide helpful context to fix issue in sources.
+         */
+        void prerequisiteFailed(Collection<? extends Prerequisite<?>> failed) throws InferenceException;
+    }
+
+    @Nonnull <D extends DeclaredStatement<?>> Prerequisite<D> requiresDeclared(StmtContext<?,? extends D,?> context);
+
+    @Nonnull <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>> Prerequisite<D> requiresDeclared(StmtContext<?,?,?> context,Class<N> namespace, K key);
+
+    @Nonnull <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>> Prerequisite<StmtContext<?, D, ?>>requiresDeclaredCtx(StmtContext<?,?,?> context,Class<N> namespace, K key);
+
+    @Nonnull <E extends EffectiveStatement<?,?>> Prerequisite<E> requiresEffective(StmtContext<?,?,? extends E> stmt);
+
+    @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>> Prerequisite<E> requiresEffective(StmtContext<?,?,?> context,Class<N> namespace, K key);
+
+    @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>> Prerequisite<StmtContext<?,?,E>> requiresEffectiveCtx(StmtContext<?,?,?> context,Class<N> namespace, K key);
+
+    @Nonnull <N extends IdentifierNamespace<? ,?>> Prerequisite<Mutable<?,?,?>> mutatesNs(Mutable<?,?, ?> ctx, Class<N> namespace);
+
+    @Nonnull <T extends Mutable<?,?,?>> Prerequisite<T> mutatesEffectiveCtx(T stmt);
+
+    @Nonnull  <K,E extends EffectiveStatement<?,?>,N extends StatementNamespace<K, ?, ? extends E>> Prerequisite<Mutable<?,?,E>> mutatesEffectiveCtx(StmtContext<?,?,?> context,Class<N> namespace, K key);
+
+    void apply(InferenceAction action) throws InferenceException;
+
+    @Nonnull <A,D extends DeclaredStatement<A>,E extends EffectiveStatement<A, D>> Prerequisite<StmtContext<A, D, E>> requiresCtx(StmtContext<A, D, E> context, ModelProcessingPhase phase);
+
+    @Nonnull <K, N extends StatementNamespace<K, ?, ? >> Prerequisite<StmtContext<?,?,?>> requiresCtx(StmtContext<?, ?, ?> context, Class<N> namespace, K key, ModelProcessingPhase phase);
+
+    @Nonnull <C extends StmtContext.Mutable<?,?,?>, CT extends C> Prerequisite<C> mutatesCtx(CT root, ModelProcessingPhase phase);
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelProcessingPhase.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelProcessingPhase.java
new file mode 100644 (file)
index 0000000..1bb6d82
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import javax.annotation.Nullable;
+
+public enum ModelProcessingPhase {
+
+    /**
+     *
+     * Cross-source relationship resolution phase.
+     * <p>
+     * In this phase of processing only statements which affects
+     * cross-source relationship (e.g. imports / includes)
+     * are processed.
+     * <p>
+     * At end of this phase all source related contexts should
+     * be bind to their imports and includes to allow
+     * visibility of custom defined statements in following
+     * phases.
+     */
+    SourceLinkage(null),
+    StatementDefinition(SourceLinkage),
+    FullDeclaration(StatementDefinition),
+    EffectiveModel(FullDeclaration);
+
+
+    private final ModelProcessingPhase previousPhase;
+
+    private ModelProcessingPhase(@Nullable ModelProcessingPhase previous) {
+        this.previousPhase = previous;
+    }
+
+    public ModelProcessingPhase getPreviousPhase() {
+        return previousPhase;
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java
new file mode 100644 (file)
index 0000000..0f795cc
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+
+/**
+ * Definition / implementation of specific Identifier Namespace behaviour.
+ *
+ * Namespace behaviour is build on top of tree of {@link NamespaceStorageNode}
+ * which represents local context of one of types defined in {@link StorageNodeType}.
+ *
+ * For common behaviour models please use static factories {@link #global(Class)},
+ * {@link #sourceLocal(Class)} and {@link #treeScoped(Class)}.
+ *
+ * @param <K> Key type
+ * @param <V> Value type
+ * @param <N> Namespace Type
+ */
+public abstract class NamespaceBehaviour<K,V, N extends IdentifierNamespace<K, V>> implements Identifiable<Class<N>>{
+
+    public enum StorageNodeType {
+        Global,
+        SourceLocalSpecial,
+        StatementLocal
+    }
+
+    public interface Registry {
+
+        abstract <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> getNamespaceBehaviour(Class<N> type);
+
+    }
+
+    public interface NamespaceStorageNode {
+
+        StorageNodeType getStorageNodeType();
+
+        @Nullable NamespaceStorageNode getParentNamespaceStorage();
+
+        @Nullable  <K, V, N extends IdentifierNamespace<K, V>> V getFromLocalStorage(Class<N> type, K key);
+
+        @Nullable  <K, V, N extends IdentifierNamespace<K, V>> void addToLocalStorage(Class<N> type, K key, V value);
+
+    }
+
+    private final Class<N> identifier;
+
+
+    protected NamespaceBehaviour(Class<N> identifier) {
+        this.identifier = Preconditions.checkNotNull(identifier);
+    }
+
+    /**
+     *
+     * Creates global namespace behaviour for supplied namespace type.
+     *
+     * Global behaviour stores and loads all values from root {@link NamespaceStorageNode}
+     * with type of {@link StorageNodeType#Global}.
+     *
+     * @param identifier Namespace identifier.
+     * @return global namespace behaviour for supplied namespace type.
+     */
+    public static @Nonnull <K,V, N extends IdentifierNamespace<K, V>>  NamespaceBehaviour<K,V,N> global(Class<N> identifier) {
+        return new StorageSpecific<>(identifier, StorageNodeType.Global);
+    }
+
+    /**
+     *
+     * Creates source-local namespace behaviour for supplied namespace type.
+     *
+     * Source-local namespace behaviour stores and loads all values from closest
+     * {@link NamespaceStorageNode} ancestor with type of
+     * {@link StorageNodeType#SourceLocalSpecial}.
+     *
+     * @param identifier Namespace identifier.
+     * @return source-local namespace behaviour for supplied namespace type.
+     */
+    public static <K,V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K,V,N> sourceLocal(Class<N> identifier) {
+        return new StorageSpecific<>(identifier, StorageNodeType.SourceLocalSpecial);
+    }
+
+    /**
+    *
+    * Creates tree-scoped namespace behaviour for supplied namespace type.
+    *
+    * Tree-scoped namespace behaviour search for value in all storage nodes
+    * up to the root and stores values in supplied node.
+    *
+    * @param identifier Namespace identifier.
+    * @return tree-scoped namespace behaviour for supplied namespace type.
+    */
+    public static <K,V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K,V,N> treeScoped(Class<N> identifier) {
+        return new TreeScoped<>(identifier);
+    }
+
+    public abstract V getFrom(NamespaceStorageNode storage, K key);
+    public abstract void addTo(NamespaceStorageNode storage,K key,V value);
+
+
+    @Override
+    public Class<N> getIdentifier() {
+        return identifier;
+    }
+
+    protected final V getFromLocalStorage(NamespaceStorageNode storage, K key) {
+        return storage.getFromLocalStorage(getIdentifier(), key);
+    }
+
+    protected final void addToStorage(NamespaceStorageNode storage,K key,V value) {
+        storage.addToLocalStorage(getIdentifier(),key,value);
+    }
+
+    static class StorageSpecific<K,V, N extends IdentifierNamespace<K, V>> extends NamespaceBehaviour<K, V, N> {
+
+        StorageNodeType storageType;
+
+        public StorageSpecific(Class<N> identifier, StorageNodeType type) {
+            super(identifier);
+            storageType = Preconditions.checkNotNull(type);
+        }
+
+        @Override
+        public V getFrom(final NamespaceStorageNode storage, final K key) {
+            NamespaceStorageNode current = storage;
+            while(current.getParentNamespaceStorage() != null) {
+                current = current.getParentNamespaceStorage();
+            }
+            return getFromLocalStorage(current,key);
+        }
+
+        @Override
+        public void addTo(NamespaceBehaviour.NamespaceStorageNode storage, K key, V value) {
+            NamespaceStorageNode current = storage;
+            while(current.getStorageNodeType() != storageType) {
+                current = current.getParentNamespaceStorage();
+            }
+            addToStorage(current, key, value);
+        }
+
+    }
+
+    static class TreeScoped<K,V, N extends IdentifierNamespace<K, V>> extends NamespaceBehaviour<K, V, N> {
+
+        public TreeScoped(Class<N> identifier) {
+            super(identifier);
+        }
+
+        @Override
+        public V getFrom(final NamespaceStorageNode storage, final K key) {
+            NamespaceStorageNode current = storage;
+            while(current != null) {
+                final V val = getFromLocalStorage(current, key);
+                if(val != null) {
+                    return val;
+                }
+                current = current.getParentNamespaceStorage();
+            }
+            return null;
+        }
+
+        @Override
+        public void addTo(NamespaceStorageNode storage,K key, V value) {
+            addToStorage(storage, key, value);
+        }
+
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceNotAvailableException.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceNotAvailableException.java
new file mode 100644 (file)
index 0000000..40f8a4e
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Preconditions;
+
+/**
+ *
+ * Thrown when identifier namespace is not available (supported)
+ * in specific model processing phase.
+ *
+ */
+public class NamespaceNotAvailableException extends RuntimeException {
+
+    private static final long serialVersionUID = 1L;
+
+    public NamespaceNotAvailableException(String message) {
+        super(Preconditions.checkNotNull(message));
+    }
+
+    public NamespaceNotAvailableException(String message, Throwable cause) {
+        super(Preconditions.checkNotNull(message), cause);
+    }
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ReactorException.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ReactorException.java
new file mode 100644 (file)
index 0000000..1ea15e2
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Preconditions;
+
+
+public class ReactorException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+    private final ModelProcessingPhase phase;
+
+    public ReactorException(ModelProcessingPhase phase, String message, Throwable cause) {
+        super(message, cause);
+        this.phase = Preconditions.checkNotNull(phase);
+    }
+
+    public ReactorException(ModelProcessingPhase phase, String message) {
+        super(message);
+        this.phase = Preconditions.checkNotNull(phase);
+    }
+
+    public final ModelProcessingPhase getPhase() {
+        return phase;
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/SomeModifiersUnresolvedException.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/SomeModifiersUnresolvedException.java
new file mode 100644 (file)
index 0000000..169a75a
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+public class SomeModifiersUnresolvedException extends ReactorException {
+
+    private static final long serialVersionUID = 1L;
+
+    public SomeModifiersUnresolvedException(ModelProcessingPhase phase) {
+        super(phase,"Some of " + phase + " modifiers for statements were not resolved.");
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementFactory.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementFactory.java
new file mode 100644 (file)
index 0000000..1ee9f37
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+
+public interface StatementFactory<A,D extends DeclaredStatement<A>,E extends EffectiveStatement<A, D>> {
+
+    D createDeclared(StmtContext<A,D,?> ctx);
+
+    E createEffective(StmtContext<A,D,E> ctx);
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementNamespace.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementNamespace.java
new file mode 100644 (file)
index 0000000..02840c6
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+
+public interface StatementNamespace<K, D extends DeclaredStatement<?>,E extends EffectiveStatement<?,D>>  extends IdentifierNamespace<K, E>  {
+
+    @Override
+    @Nullable E get(K key);
+
+    public interface TreeScoped<K, D extends DeclaredStatement<?>,E extends EffectiveStatement<?,D>> extends StatementNamespace<K,D,E> {
+
+        TreeScoped<K,D,E> getParentContext();
+
+    }
+
+    public interface TreeBased<K,D extends DeclaredStatement<?>,E extends EffectiveStatement<?,D>> {
+
+    }
+
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java
new file mode 100644 (file)
index 0000000..321c3e9
--- /dev/null
@@ -0,0 +1,116 @@
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+
+/**
+ *
+ * Support for processing concrete YANG statement.
+ *
+ * This interface is intended to be implemented by developers, which want to
+ * introduce support of statement to parser. Consider subclassing
+ * {@link AbstractStatementSupport} for easier implementation of this interface.
+ *
+ * @param <A>
+ *            Argument type
+ * @param <D>
+ *            Declared Statement representation
+ * @param <E>
+ *            Effective Statement representation
+ */
+public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> extends StatementDefinition, StatementFactory<A, D, E> {
+
+    /**
+     * Returns public statement definition, which will be present in builded statements.
+     *
+     * Public statement definition may be used to provide different implementation
+     * of statement definition, which will not retain any build specific data
+     * or context.
+     *
+     * @return public statement definition, which will be present in builded statements.
+     */
+     StatementDefinition getPublicView();
+
+    /**
+     *
+     * Parses textual representation of argument in object representation.
+     *
+     * @param ctx Context, which may be used to access source-specific namespaces
+     * required for parsing.
+     * @param value String representation of value, as was present in text source.
+     * @return Parsed value
+     */
+     A parseArgumentValue(StmtContext<?, ?, ?> ctx, String value) throws SourceException;
+
+    /**
+     *
+     * Invoked when statement is added to build context.
+     *
+     * @param stmt
+     *            Context of added statement. No substatement are available.
+     */
+     void onStatementAdded(StmtContext.Mutable<A, D, E> stmt);
+
+    /**
+     *
+     * Invoked when statement is closed during
+     * {@link ModelProcessingPhase#StatementDefinition} phase.
+     *
+     * Invoked when statement is closed during
+     * {@link ModelProcessingPhase#StatementDefinition} phase, only substatements from
+     * this and previous phase are available.
+     *
+     * Implementation may use method to perform actions on this event or
+     * register modification action using
+     * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
+     *
+     * @param stmt
+     *            Context of added statement.
+     */
+     void onLinkageDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException,
+            SourceException;
+
+    /**
+     *
+     * Invoked when statement is closed during
+     * {@link ModelProcessingPhase#StatementDefinition} phase.
+     *
+     * Invoked when statement is closed during
+     * {@link ModelProcessingPhase#StatementDefinition} phase, only substatements from
+     * this phase are available.
+     *
+     * Implementation may use method to perform actions on this event or
+     * register modification action using
+     * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
+     *
+     * @param stmt
+     *            Context of added statement. Argument and statement parent is
+     *            accessible.
+     */
+     void onStatementDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException,
+            SourceException;
+
+    /**
+     *
+     * Invoked when statement is closed during
+     * {@link ModelProcessingPhase#FullDeclaration} phase.
+     *
+     * Invoked when statement is closed during
+     * {@link ModelProcessingPhase#FullDeclaration} phase, only substatements
+     * from this phase are available.
+     *
+     * Implementation may use method to perform actions on this event or
+     * register modification action using
+     * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
+     *
+     *
+     * @param stmt
+     *            Context of added statement. Argument and statement parent is
+     *            accessible.
+     */
+     void onFullDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException,
+            SourceException;
+
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupportBundle.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupportBundle.java
new file mode 100644 (file)
index 0000000..504a70d
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import java.util.HashMap;
+import java.util.Map;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+
+public final class StatementSupportBundle implements Immutable,NamespaceBehaviour.Registry {
+
+    private static final StatementSupportBundle EMPTY = new StatementSupportBundle(null, ImmutableMap.<QName, StatementSupport<?, ?, ?>>of(), ImmutableMap.<Class<?>, NamespaceBehaviour<?, ?, ?>>of());
+
+    private final StatementSupportBundle parent;
+    private final ImmutableMap<QName, StatementSupport<?,?,?>> definitions;
+    private final ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaceDefinitions;
+
+    private StatementSupportBundle(StatementSupportBundle parent,
+            ImmutableMap<QName, StatementSupport<?, ?, ?>> statements,
+            ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces) {
+        this.parent = parent;
+        this.definitions = statements;
+        this.namespaceDefinitions = namespaces;
+    }
+
+    public static final Builder builder() {
+        return new Builder(EMPTY);
+    }
+
+    public static final Builder derivedFrom(StatementSupportBundle parent) {
+        return new Builder(parent);
+    }
+
+    @Override
+    public <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> getNamespaceBehaviour(Class<N> namespace)
+            throws NamespaceNotAvailableException {
+        NamespaceBehaviour<?, ?, ?> potential = namespaceDefinitions.get(namespace);
+        if (potential != null) {
+            Preconditions.checkState(namespace.equals(potential.getIdentifier()));
+
+            /*
+             * Safe cast, previous checkState checks equivalence of key from
+             * which type argument are derived
+             */
+            @SuppressWarnings("unchecked")
+            NamespaceBehaviour<K, V, N> casted = (NamespaceBehaviour<K, V, N>) potential;
+            return casted;
+        }
+        if (parent != null) {
+            return parent.getNamespaceBehaviour(namespace);
+        }
+        return null;
+    }
+
+    public <K, V, N extends IdentifierNamespace<K, V>> boolean hasNamespaceBehaviour(Class<N> namespace) {
+        if (namespaceDefinitions.containsKey(namespace)) {
+            return true;
+        }
+        if (parent != null) {
+            return parent.hasNamespaceBehaviour(namespace);
+        }
+        return false;
+    }
+
+    public StatementSupport<?, ?,?> getStatementDefinition(QName stmtName) {
+        StatementSupport<?,?, ?> potential = definitions.get(stmtName);
+        if (potential != null) {
+            return potential;
+        }
+        if (parent != null) {
+            return parent.getStatementDefinition(stmtName);
+        }
+        return null;
+    }
+
+    public static class Builder implements org.opendaylight.yangtools.concepts.Builder<StatementSupportBundle> {
+
+        private final StatementSupportBundle parent;
+        private final Map<QName, StatementSupport<?,?,?>> statements = new HashMap<>();
+        private final Map<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces = new HashMap<>();
+
+        Builder(StatementSupportBundle parent) {
+            this.parent = parent;
+        }
+
+        public Builder addSupport(StatementSupport<?, ?,?> definition) {
+            QName identifier = definition.getStatementName();
+            Preconditions.checkState(!statements.containsKey(identifier), "Statement %s already defined.",identifier);
+            Preconditions.checkState(parent.getStatementDefinition(identifier) == null, "Statement %s already defined.",identifier);
+            statements.put(identifier, definition);
+            return this;
+        }
+
+       public <K, V, N extends IdentifierNamespace<K, V>> Builder addSupport(NamespaceBehaviour<K, V, N> namespaceSupport) {
+            Class<N> identifier = namespaceSupport.getIdentifier();
+            Preconditions.checkState(!namespaces.containsKey(identifier));
+            Preconditions.checkState(!parent.hasNamespaceBehaviour(identifier));
+            namespaces.put(identifier, namespaceSupport);
+            return this;
+        }
+
+       @Override
+        public StatementSupportBundle build() {
+            return new StatementSupportBundle(parent, ImmutableMap.copyOf(statements), ImmutableMap.copyOf(namespaces));
+        }
+
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java
new file mode 100644 (file)
index 0000000..124d6bf
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
+import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
+
+
+public interface StmtContext<A,D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> {
+
+    @Nonnull StatementSource getStatementSource();
+
+    @Nonnull StatementSourceReference getStatementSourceReference();
+
+    @Nonnull StatementDefinition getPublicDefinition();
+
+    @Nullable StmtContext<?,?,?> getParentContext();
+
+    @Nullable String rawStatementArgument();
+
+    @Nullable A getStatementArgument();
+
+    @Nonnull <K,VT, V extends VT,N extends IdentifierNamespace<K, V>> VT getFromNamespace(Class<N> type, K key) throws NamespaceNotAvailableException;
+
+    @Nonnull StmtContext<?,?,?> getRoot();
+
+    @Nonnull Collection<? extends StmtContext<?,?,?>> declaredSubstatements();
+
+    D buildDeclared();
+
+    E buildEffective();
+
+    interface Mutable<A,D extends DeclaredStatement<A>,E extends EffectiveStatement<A, D>> extends StmtContext<A,D,E> {
+
+        @Override
+        StmtContext.Mutable<?,?,?> getParentContext();
+
+        <K,V,VT extends V,N extends IdentifierNamespace<K, V>> void addToNs(Class<N> type, K key, VT value) throws NamespaceNotAvailableException;
+
+        @Override
+        StmtContext.Mutable<?,?,?> getRoot();
+
+        ModelActionBuilder newInferenceAction(ModelProcessingPhase phase);
+
+        <K,KT extends K, N extends StatementNamespace<K, ?, ?>> void addContext(Class<N> namepsace, KT key,
+                StmtContext<?, ?, ?> stmt);
+
+    }
+
+
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java
new file mode 100644 (file)
index 0000000..9e3cd70
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Function;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+
+public final class StmtContextUtils {
+
+    private static final Function<StmtContext<?, ?,?>, DeclaredStatement<?>> BUILD_DECLARED = new Function<StmtContext<?,?,?>, DeclaredStatement<?>>() {
+
+        @Override
+        public DeclaredStatement<?> apply(StmtContext<?,?,?> input) {
+            return input.buildDeclared();
+        }
+
+    };
+
+    private static final Function<StmtContext<?, ?,?>, EffectiveStatement<?,?>> BUILD_EFFECTIVE = new Function<StmtContext<?,?,?>, EffectiveStatement<?,?>>() {
+
+        @Override
+        public EffectiveStatement<?,?> apply(StmtContext<?,?,?> input) {
+            return input.buildEffective();
+        }
+
+    };
+
+    private StmtContextUtils() {
+        throw new UnsupportedOperationException("Utility class");
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static final <D extends DeclaredStatement<?>> Function<StmtContext<?, ? extends D, ?>, D> buildDeclared() {
+        return Function.class.cast(BUILD_DECLARED);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static final <E extends EffectiveStatement<?,?>> Function<StmtContext<?, ?,? extends E>, E> buildEffective() {
+        return Function.class.cast(BUILD_EFFECTIVE);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static final <AT,DT extends DeclaredStatement<AT>> AT firstAttributeOf(Iterable<? extends StmtContext<?,?,?>> contexts, Class<DT> declaredType) {
+        for(StmtContext<?, ?, ?> ctx : contexts) {
+            if(producesDeclared(ctx,declaredType)) {
+                return (AT) ctx.getStatementArgument();
+            }
+        }
+        return null;
+    }
+
+    public static final boolean producesDeclared(StmtContext<?, ?, ?> ctx, Class<? extends DeclaredStatement<?>> type) {
+        return type.isAssignableFrom(ctx.getPublicDefinition().getDeclaredRepresentationClass());
+    }
+
+
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/DeclarationInTextSource.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/DeclarationInTextSource.java
new file mode 100644 (file)
index 0000000..8f37fdf
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.source;
+
+import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
+
+/**
+ *
+ * Reference of statement source present in textual source format
+ *
+ * Utility implementation of {@link StatementSourceReference} for textual sources,
+ * this is prefered {@link StatementSourceReference} for implementations
+ * of YANG / YIN statement stream sources.
+ *
+ *
+ *  To create source reference use one of this static factiories:
+ *  <ul>
+ *  <li>{@link #atPosition(String, int, int)} - provides most specific reference of statement location,
+ *  this is most prefered since it provides most context to debug YANG model.
+ *  </li>
+ *  <li>{@link #atLine(String, int)}- provides source and line of statement location.
+ *  </li>
+ *  <li>{@link #inSource(String)} - least specific reference, should be used only if any of previous
+ *  references are unable to create / derive from source.
+ *  </li>
+ *  </ul>
+ *
+ */
+public abstract class DeclarationInTextSource implements StatementSourceReference {
+
+    private final String source;
+
+    DeclarationInTextSource(String source) {
+        this.source = source;
+    }
+
+    public String getSourceName() {
+        return source;
+    }
+
+    @Override
+    public StatementSource getStatementSource() {
+        return StatementSource.DECLARATION;
+    }
+
+    @Override
+    public abstract String toString();
+
+    public static final DeclarationInTextSource inSource(String sourceName) {
+        return new InSource(sourceName);
+    }
+
+    public static final DeclarationInTextSource atLine(String sourceName, int line) {
+        return new AtLine(sourceName,line);
+    }
+
+    public static final DeclarationInTextSource atPosition(String sourceName, int line, int position) {
+        return new AtPosition(sourceName,line,position);
+    }
+
+    private static class InSource extends DeclarationInTextSource {
+
+        public InSource(String source) {
+            super(source);
+        }
+
+        @Override
+        public String toString() {
+            return getSourceName();
+        }
+
+    }
+
+    private static class AtLine extends DeclarationInTextSource {
+
+        private final int line;
+
+        public AtLine(String source,int line) {
+            super(source);
+            this.line = line;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%s:%d", getSourceName(),line);
+        }
+
+    }
+
+    private static class AtPosition extends DeclarationInTextSource {
+
+        private int line;
+        private int character;
+
+        public AtPosition(String source, int line, int character) {
+            super(source);
+            this.line = line;
+            this.character = character;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%s:%d:%d", getSourceName(),line,character);
+        }
+
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/PrefixToModule.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/PrefixToModule.java
new file mode 100644 (file)
index 0000000..6b409e0
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.source;
+
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+
+/**
+ *
+ * Source-specific mapping of prefixes to namespaces
+ *
+ */
+public interface PrefixToModule extends IdentifierNamespace<String, QNameModule> {
+
+    public static final String DEFAULT_PREFIX = "";
+
+
+    /**
+     *
+     * Returns QNameModule (namespace + revision) associated with supplied
+     * prefix.
+     *
+     * @param prefix
+     *            Prefix
+     * @return QNameModule associated with supplied prefix, or null if prefix is
+     *         not defined.
+     *
+     */
+    @Override
+    @Nullable QNameModule get(String prefix);
+
+    /**
+     *
+     * Returns QNameModule (namespace + revision) associated with XML namespace
+     * (URI).
+     *
+     * @param namespace
+     *            XML Namespace
+     * @return QNameModule associated with supplied namespace, or null if prefix
+     *         is not defined.
+     *
+     */
+    @Nullable QNameModule getByNamespace(String namespace);
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinition.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinition.java
new file mode 100644 (file)
index 0000000..58e7da9
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.source;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+
+/**
+ *
+ * Map of fully qualified statement name to statement definition.
+ *
+ */
+public interface QNameToStatementDefinition extends IdentifierNamespace<QName, StatementDefinition> {
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/SourceException.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/SourceException.java
new file mode 100644 (file)
index 0000000..de5228e
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.source;
+
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+
+/**
+ *
+ * Thrown to indicate error in YANG model source.
+ *
+ */
+public class SourceException extends Exception {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
+    private final StatementSourceReference sourceRef;
+
+    public SourceException(@Nonnull String message,@Nonnull StatementSourceReference source) {
+        super(Preconditions.checkNotNull(message));
+        sourceRef = Preconditions.checkNotNull(source);
+    }
+
+    public SourceException(@Nonnull String message,@Nonnull StatementSourceReference source, Throwable cause) {
+        super(Preconditions.checkNotNull(message),cause);
+        sourceRef = Preconditions.checkNotNull(source);
+    }
+
+    public @Nonnull StatementSourceReference getSourceReference() {
+        return sourceRef;
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/StatementSourceReference.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/StatementSourceReference.java
new file mode 100644 (file)
index 0000000..b5efed6
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.source;
+
+import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
+
+/**
+ *
+ * Reference of statement source
+ *
+ * Statement source reference serves to provide information, why
+ * statement was defined and introduced in model.
+ *
+ * Reasons for introduction of statement could be various, but
+ * most obvious one is explicit declaration in model source text
+ * such as {@link DeclarationInTextSource}.
+ *
+ */
+public interface StatementSourceReference {
+
+    /**
+     *
+     * Returns source type
+     *
+     * @return {@link StatementSource#DECLARATION} if statement was explicitly
+     * declared in YANG model source, {@link StatementSource#CONTEXT} if statement
+     * was inferred.
+     */
+    StatementSource getStatementSource();
+
+    /**
+     * Returns human readable representation of statement source.
+     *
+     * Implementations of this interface should override {@link #toString()},
+     * since it may be used in error reporting to provide context
+     * information for model designer to debug errors in its mode.
+     *
+     * @return human readable representation of statement source.
+     */
+    @Override
+    String toString();
+
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/StatementStreamSource.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/StatementStreamSource.java
new file mode 100644 (file)
index 0000000..fa3cc60
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.source;
+
+/**
+ *
+ * Statement stream source, which is used for inference of effective model.
+ *
+ * <p>
+ * Statement stream source is required to emit its statements using supplied
+ * {@link StatementWriter}.
+ * </p>
+ * <p>
+ * Since YANG allows language extensions defined in sources (which defines how
+ * source is serialized), instances of extensions present anywhere and forward
+ * references, each source needs to be processed in three steps, where each step
+ * uses different set of supported statements.
+ * <p>
+ * Steps (in order of invocation) are:
+ *
+ * <ol>
+ * <li>{@link #writeLinkage(StatementWriter, QNameToStatementDefinition)} -
+ * Source MUST emit only statements related in linkage, which are present in
+ * supplied statement definition map. This step is used to build cross-source
+ * linkage and visibility relationship, and to determine XMl namespaces and
+ * prefixes.</li>
+ * <li>
+ * {@link #writeLinkageAndStatementDefinitions(StatementWriter, QNameToStatementDefinition, PrefixToModule)}
+ * - Source MUST emit only statements related to linkage and language extensions
+ * definitions, which are present in supplied statement definition map. This
+ * step is used to build statement definitions in order to fully processed
+ * source.</li>
+ * <li>
+ * {@link #writeFull(StatementWriter, QNameToStatementDefinition, PrefixToModule)}
+ * - Source MUST emit all statements present in source. This step is used to
+ * build full declared statement model of source.</li>
+ * </ol>
+ *
+ */
+public interface StatementStreamSource {
+
+    /**
+     *
+     * Emits only linkage-related statements to supplied {@code writer}.
+     *
+     * @param writer
+     *            {@link StatementWriter} which should be used to emit
+     *            statements.
+     * @param stmtDef
+     *            Map of available statement definitions. Only these statements
+     *            may be written to statement writer, source MUST ignore and MUST NOT
+     *            emit any other statements.
+     *
+     * @throws SourceException
+     *             If source was is not valid, or provided statement writer
+     *             failed to write statements.
+     */
+    void writeLinkage(StatementWriter writer, QNameToStatementDefinition stmtDef) throws SourceException;
+
+    /**
+     *
+     * Emits only linkage and language extension statements to supplied
+     * {@code writer}.
+     *
+     * @param writer
+     *            {@link StatementWriter} which should be used to emit
+     *            statements.
+     * @param stmtDef
+     *            Map of available statement definitions. Only these statements
+     *            may be written to statement writer, source MUST ignore and MUST NOT
+     *            emit any other statements.
+     * @param prefixes
+     *            Map of source-specific prefixes to namespaces
+     *
+     * @throws SourceException
+     *             If source was is not valid, or provided statement writer
+     *             failed to write statements.
+     */
+    void writeLinkageAndStatementDefinitions(StatementWriter writer, QNameToStatementDefinition stmtDef, PrefixToModule prefixes) throws SourceException;
+
+    /**
+     *
+     * Emits every statements present in this statement source to supplied
+     * {@code writer}.
+     *
+     * @param writer
+     *            {@link StatementWriter} which should be used to emit
+     *            statements.
+     * @param stmtDef
+     *            Map of available statement definitions.
+     * @param prefixes
+     *            Map of source-specific prefixes to namespaces
+     * @throws SourceException
+     *             If source was is not valid, or provided statement writer
+     *             failed to write statements.
+     */
+    void writeFull(StatementWriter writer,QNameToStatementDefinition stmtDef, PrefixToModule prefixes) throws SourceException;
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/StatementWriter.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/StatementWriter.java
new file mode 100644 (file)
index 0000000..543e06b
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.source;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+
+public interface StatementWriter {
+
+    /**
+     *
+     * Starts statement with supplied name and location in source.
+     *
+     *
+     * <p>
+     * Each started statement must also be closed by
+     * {@link #endStatement(StatementSourceReference)} in order for stream to be
+     * correct.
+     * </p>
+     * <p>
+     * If statement requires an argument, user must call
+     * {@link #argumentValue(String, StatementSourceReference)} to emit
+     * argument, otherwise any subsequent call to this {@link StatementWriter}
+     * will throw {@link SourceException}.
+     * </p>
+     * <p>
+     * If statement has substatements, in order to start substatement, call to
+     * {@link #startStatement(QName, StatementSourceReference)} needs to be done
+     * for substatement.
+     *
+     * @param name
+     *            Fully qualified name of statement.
+     * @param ref
+     *            Identifier of location in source, which will be used for
+     *            reporting in case of statement processing error.
+     * @throws SourceException
+     *             if statement is not valid according to current context.
+     */
+    void startStatement(@Nonnull QName name, @Nonnull StatementSourceReference ref) throws SourceException;
+
+    /**
+     *
+     * Emits an argument to current opened statement.
+     *
+     * <p>
+     * If statement has an argument, this must be called right after
+     * {@link #startStatement(QName, StatementSourceReference)} otherwise any
+     * subsequent call to this {@link StatementWriter} will throw
+     * {@link SourceException}.
+     *
+     *
+     *
+     * @param value
+     *            String representation of value as appeared in source
+     * @param ref
+     *            Identifier of location in source, which will be used for
+     *            reporting in case of statement processing error.
+     * @throws SourceException
+     *             if argument is not valid for current statement.
+     */
+    void argumentValue(@Nonnull String value,@Nonnull StatementSourceReference ref) throws SourceException;
+
+    /**
+     * Ends current opened statement.
+     *
+     * @param ref
+     *            Identifier of location in source, which will be used for
+     *            reporting in case of statement processing error.
+     * @throws SourceException
+     *             if closed statement is not valid in current context, or there
+     *             is no such statement
+     */
+    void endStatement(@Nonnull StatementSourceReference ref) throws SourceException;
+
+}
index 211e6a21743a666065e5e0ebc27aebb5cbb8de87..f425a5ba033c5ab475fccc0c26032cccc5023d0b 100644 (file)
@@ -8,8 +8,7 @@ package org.opendaylight.yangtools.yang.parser.util;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Charsets;
-import com.google.common.io.CharStreams;
-import com.google.common.io.InputSupplier;
+import com.google.common.io.ByteSource;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
 
@@ -48,13 +47,12 @@ public final class TextToASTTransformer extends SchemaSourceTransformer<YangText
                 LOG.debug("Model {} validated successfully", input);
 
                 // Backwards compatibility
-                final String text = CharStreams.toString(
-                        CharStreams.newReaderSupplier(new InputSupplier<InputStream>() {
-                            @Override
-                            public InputStream getInput() throws IOException {
-                                return input.openStream();
-                            }
-                        }, Charsets.UTF_8));
+                final String text = new ByteSource() {
+                    @Override
+                    public InputStream openStream() throws IOException {
+                        return input.openStream();
+                    }
+                }.asCharSource(Charsets.UTF_8).read();
 
                 return Futures.immediateCheckedFuture(ASTSchemaSource.create(input.getIdentifier().getName(), ctx, text));
             }
index a4360a5a67a93345f8e121781ae64ac4bee919c6..3abb8508e7b337b933fbf1b9d121a789319c7131 100644 (file)
@@ -13,6 +13,8 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
@@ -545,4 +547,41 @@ public class GroupingTest {
         assertEquals(gy.getDataChildByName("leaf-grouping-Y"),SchemaNodeUtils.getRootOriginalIfPossible( gx.getDataChildByName("leaf-grouping-Y")));
     }
 
+    @Test
+    public void testAddedByUsesLeafTypeQName() throws IOException,
+            URISyntaxException {
+
+        Set<Module> loadModules = TestUtils.loadModules(getClass().getResource(
+                "/added-by-uses-leaf-test").toURI());
+
+        assertEquals(2, loadModules.size());
+
+        Module foo = null;
+        Module imp = null;
+        for (Module module : loadModules) {
+            if (module.getName().equals("foo")) {
+                foo = module;
+            }
+            if (module.getName().equals("import-module")) {
+                imp = module;
+            }
+        }
+
+        LeafSchemaNode leaf = (LeafSchemaNode) ((ContainerSchemaNode) foo
+                .getDataChildByName("my-container"))
+                .getDataChildByName("my-leaf");
+
+        TypeDefinition impType = null;
+        Set<TypeDefinition<?>> typeDefinitions = imp.getTypeDefinitions();
+        for (TypeDefinition<?> typeDefinition : typeDefinitions) {
+            if (typeDefinition.getQName().getLocalName().equals("imp-type")) {
+                impType = typeDefinition;
+                break;
+            }
+        }
+
+        assertEquals(leaf.getType().getQName(), impType.getQName());
+
+    }
+
 }
index 300ed776ffc10fff613dabc3ad7ae24341314ed5..588e7a21e40a7df2500f0ab97b2d8e9ebb3872ad 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.parser.impl;
 import static org.junit.Assert.assertEquals;
 import com.google.common.io.ByteSource;
 import com.google.common.io.ByteStreams;
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -87,7 +88,12 @@ final class TestUtils {
 
         final byte[] streamContent = ByteStreams.toByteArray(stream);
 
-        ByteSource source = ByteStreams.asByteSource(streamContent);
+        ByteSource source = new ByteSource() {
+            @Override
+            public InputStream openStream() throws IOException {
+                return new ByteArrayInputStream(streamContent);
+            }
+        };
 
         final Collection<ByteSource> sources = Collections.singletonList(source);
         SchemaContext ctx = parser.parseSources(sources, context);
index 6156093cf89684131339d108868a6c08c924dd7d..65d9d5d35c8b582959b9b32048572185b62e5afe 100644 (file)
@@ -39,6 +39,7 @@ import org.opendaylight.yangtools.yang.model.util.ExtendedType;
 import org.opendaylight.yangtools.yang.model.util.IdentityrefType;
 import org.opendaylight.yangtools.yang.model.util.InstanceIdentifierType;
 import org.opendaylight.yangtools.yang.model.util.UnionType;
+import org.opendaylight.yangtools.yang.parser.util.YangParseException;
 
 public class TypesResolutionTest {
     private Set<Module> testedModules;
@@ -346,4 +347,10 @@ public class TypesResolutionTest {
         parser.parseFiles(Arrays.asList(unionbits));
     }
 
+    @Test(expected = YangParseException.class)
+    public void testUnionInList() throws Exception {
+       File unioninlist = new File(getClass().getResource("/types/union-in-list/unioninlisttest.yang").toURI());
+       YangContextParser parser = new YangParserImpl();
+       parser.parseFiles(Arrays.asList(unioninlist));
+    }
 }
index 57b80ad2365a7eaeb2ca03d1d5581bb34c76d108..e349693f5deaa435dc5912f6e8ddab33138885bc 100644 (file)
@@ -8,7 +8,7 @@
 
 package org.opendaylight.yangtools.yang.parser.repo;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 import java.io.IOException;
 import java.io.InputStream;
@@ -24,7 +24,7 @@ final class ResourceYangSource extends YangTextSchemaSource {
     }
 
     @Override
-    protected Objects.ToStringHelper addToStringAttributes(final Objects.ToStringHelper toStringHelper) {
+    protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
         return toStringHelper.add("resource", resourceName);
     }
 
index 49ed2f8707bfd853ad94abd274079e953b84e57e..83c0a8f850c6ad2d37cf056a72635608b1e92fc3 100644 (file)
@@ -20,13 +20,13 @@ import static org.junit.Assert.fail;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import com.google.common.base.Charsets;
 import com.google.common.base.Function;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Optional;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.Lists;
 import com.google.common.io.Files;
-import com.google.common.io.InputSupplier;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
@@ -223,16 +223,16 @@ public class SharedSchemaRepositoryTest {
         sharedSchemaRepository.registerSchemaSourceListener(listener);
 
         final File test = new File(storageDir, "test.yang");
-        Files.copy(new StringSupplier("content-test"), test);
+        Files.write("content-test", test, Charsets.UTF_8);
 
         final File test2 = new File(storageDir, "test@2012-12-12.yang");
-        Files.copy(new StringSupplier("content-test-2012"), test2);
+        Files.write("content-test-2012", test2, Charsets.UTF_8);
 
         final File test3 = new File(storageDir, "test@2013-12-12.yang");
-        Files.copy(new StringSupplier("content-test-2013"), test3);
+        Files.write("content-test-2013", test3, Charsets.UTF_8);
 
         final File test4 = new File(storageDir, "module@2010-12-12.yang");
-        Files.copy(new StringSupplier("content-module-2010"), test4);
+        Files.write("content-module-2010", test4, Charsets.UTF_8);
 
 
         final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(sharedSchemaRepository, YangTextSchemaSource.class, storageDir);
@@ -270,7 +270,7 @@ public class SharedSchemaRepositoryTest {
             public CheckedFuture<YangTextSchemaSource, SchemaSourceException> getSource(final SourceIdentifier sourceIdentifier) {
                 return Futures.<YangTextSchemaSource, SchemaSourceException>immediateCheckedFuture(new YangTextSchemaSource(runningId) {
                     @Override
-                    protected Objects.ToStringHelper addToStringAttributes(final Objects.ToStringHelper toStringHelper) {
+                    protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
                         return toStringHelper;
                     }
 
@@ -329,17 +329,4 @@ public class SharedSchemaRepositoryTest {
         final CheckedFuture<ASTSchemaSource, SchemaSourceException> aSTSchemaSource = TextToASTTransformer.TRANSFORMATION.apply(yangSource);
         return SettableSchemaProvider.createImmediate(aSTSchemaSource.get(), ASTSchemaSource.class);
     }
-
-    private class StringSupplier implements InputSupplier<InputStream> {
-        private final String s;
-
-        public StringSupplier(final String s) {
-            this.s = s;
-        }
-
-        @Override
-        public InputStream getInput() throws IOException {
-            return IOUtils.toInputStream(s);
-        }
-    }
 }
diff --git a/yang/yang-parser-impl/src/test/resources/added-by-uses-leaf-test/foo.yang b/yang/yang-parser-impl/src/test/resources/added-by-uses-leaf-test/foo.yang
new file mode 100644 (file)
index 0000000..413d7c6
--- /dev/null
@@ -0,0 +1,20 @@
+module foo {
+    prefix foo;
+    namespace "namespace-foo";
+
+    import import-module { prefix imp; revision-date 1970-01-02; } 
+    
+    grouping grp {
+        leaf my-leaf {
+            type imp:imp-type;
+        }
+        
+    }
+    
+    container my-container {
+        uses grp;
+        uses imp:imp_grp;
+    }
+    
+}
+
diff --git a/yang/yang-parser-impl/src/test/resources/added-by-uses-leaf-test/import-module.yang b/yang/yang-parser-impl/src/test/resources/added-by-uses-leaf-test/import-module.yang
new file mode 100644 (file)
index 0000000..6cb9f69
--- /dev/null
@@ -0,0 +1,35 @@
+module import-module {
+    prefix imp;
+    namespace "import-module";
+
+    revision 1970-01-02 {
+        description "Initial revision.";
+    }
+
+    typedef imp-type {
+        type string {
+            length "0..100";
+        }
+    }
+
+    grouping imp_grp {
+        
+        typedef grp-type {
+            type string {
+                length "20..30";
+            }
+        }
+
+        leaf my-leaf2 {
+            type grp-type;
+        }
+        
+        leaf union-leaf {
+            type union {
+                type int16;
+                type string;
+            }
+        }
+    }
+}
+
diff --git a/yang/yang-parser-impl/src/test/resources/types/union-in-list/unioninlisttest.yang b/yang/yang-parser-impl/src/test/resources/types/union-in-list/unioninlisttest.yang
new file mode 100644 (file)
index 0000000..1db8726
--- /dev/null
@@ -0,0 +1,32 @@
+module unioninlisttest {
+
+    namespace "urn:uilt";
+    prefix "uilt";
+
+    revision 2015-01-13 {
+    }
+
+    list foo {
+        key "name";
+        unique "ip port";
+
+        leaf name {
+            type string;
+        }
+
+        union {
+            type int32;
+            type enumeration {
+                enum "test";
+            }
+        }
+
+        leaf ip {
+            type string;
+        }
+
+        leaf port {
+            type string;
+        }
+    }
+}
\ No newline at end of file