Merge "Bug 2983 - Throws ResultAlreadySet instead of IllegalStateException"
authorTony Tkacik <ttkacik@cisco.com>
Thu, 30 Apr 2015 13:21:34 +0000 (13:21 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 30 Apr 2015 13:21:34 +0000 (13:21 +0000)
265 files changed:
benchmarks/pom.xml
code-generator/binding-data-codec/pom.xml
code-generator/binding-generator-api/pom.xml
code-generator/binding-generator-impl/pom.xml
code-generator/binding-generator-spi/pom.xml
code-generator/binding-generator-util/pom.xml
code-generator/binding-java-api-generator/pom.xml
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend
code-generator/binding-model-api/pom.xml
code-generator/binding-parent/pom.xml
code-generator/binding-test-model/pom.xml
code-generator/binding-type-provider/pom.xml
code-generator/maven-sal-api-gen-plugin/pom.xml
code-generator/pom.xml
code-generator/samples/maven-code-gen-sample/pom.xml
code-generator/samples/modeling-sample/pom.xml
common/artifacts/pom.xml
common/checkstyle-logging/pom.xml
common/checkstyle-logging/src/test/java/org/opendaylight/yangtools/checkstyle/CheckstyleTest.java
common/concepts/pom.xml
common/features-test/pom.xml
common/features/pom.xml
common/mockito-configuration/pom.xml
common/object-cache-api/pom.xml
common/object-cache-guava/pom.xml
common/object-cache-noop/pom.xml
common/parent/pom.xml
common/pom.xml
common/util/pom.xml
integration-test/bug1196-test-model/pom.xml
integration-test/bug527-test-model/pom.xml
integration-test/bundle-test/pom.xml
integration-test/pom.xml
integration-test/regression-test-model/pom.xml
integration-test/test-models/pom.xml
integration-test/yang-runtime-tests/pom.xml
model/iana/iana-afn-safi/pom.xml
model/iana/iana-if-type-2014-05-08/pom.xml
model/iana/iana-if-type/pom.xml
model/iana/pom.xml
model/ietf/ietf-inet-types/pom.xml
model/ietf/ietf-inet-types/src/test/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev100924/HostBuilderTest.java
model/ietf/ietf-interfaces/pom.xml
model/ietf/ietf-restconf/pom.xml
model/ietf/ietf-ted/pom.xml
model/ietf/ietf-topology-isis/pom.xml
model/ietf/ietf-topology-l3-unicast-igp/pom.xml
model/ietf/ietf-topology-ospf/pom.xml
model/ietf/ietf-topology/pom.xml
model/ietf/ietf-yang-types-20130715/pom.xml
model/ietf/ietf-yang-types/pom.xml
model/ietf/pom.xml
model/l2-types/pom.xml
model/pom.xml
model/yang-ext/pom.xml
pom.xml
restconf/pom.xml
restconf/restconf-client-api/pom.xml
restconf/restconf-client-impl/pom.xml
restconf/restconf-common/pom.xml
restconf/restconf-jaxrs-api/pom.xml
restconf/restconf-test-service/pom.xml
restconf/restconf-util/pom.xml
third-party/antlr4-runtime-osgi/pom.xml
third-party/pom.xml
websocket/pom.xml
websocket/websocket-client/pom.xml
yang-validation-tool/pom.xml
yang/pom.xml
yang/yang-binding/pom.xml
yang/yang-common/pom.xml
yang/yang-data-api/pom.xml
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/YangInstanceIdentifier.java
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/BackendFailedException.java [new file with mode: 0644]
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/CursorAwareDataTreeModification.java [new file with mode: 0644]
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/CursorAwareDataTreeSnapshot.java [new file with mode: 0644]
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/DataTreeCandidates.java
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/DataTreeModification.java
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/DataTreeModificationCursor.java [new file with mode: 0644]
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/DataTreeSnapshotCursor.java [new file with mode: 0644]
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/SynchronizedDataTreeModification.java
yang/yang-data-codec-gson/pom.xml
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/RpcAsContainer.java
yang/yang-data-impl/pom.xml
yang/yang-data-impl/src/main/antlr/LeafRefPathLexer.g4 [new file with mode: 0644]
yang/yang-data-impl/src/main/antlr/LeafRefPathParser.g4 [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContext.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextBuilder.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextTreeBuilder.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextUtils.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefDataValidationFailedException.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPath.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathErrorListener.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParseException.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserImpl.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserListenerImpl.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathSyntaxErrorException.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefUtils.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefValidatation.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefYangSyntaxErrorException.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNamePredicate.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNamePredicateBuilder.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNamePredicateImpl.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNameWithPredicate.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNameWithPredicateBuilder.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNameWithPredicateImpl.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/ImmutableNodes.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/InstanceIdToCompositeNodes.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/InstanceIdToNodes.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/InstanceIdToSimpleNodes.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/SchemaUtils.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/AbstractImmutableNormalizedValueAttrNode.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/AugmentationNodeBaseParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/BaseDispatcherParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ContainerNodeBaseParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ListEntryNodeBaseParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/AugmentationNodeDomParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ContainerNodeDomParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/DomToNormalizedNodeParserFactory.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/MapEntryNodeDomParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractDataTreeTip.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTreeModification.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/SchemaAwareApplyOperation.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/DataTreeCandidateValidatorTest.java [new file with mode: 0644]
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/DataTreeCandidateValidatorTest2.java [new file with mode: 0644]
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/DataTreeCandidateValidatorTest3.java [new file with mode: 0644]
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/LeafRefContextTest.java [new file with mode: 0644]
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/LeafRefContextTreeBuilderTest.java [new file with mode: 0644]
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/InstanceIdToNodesTest.java [new file with mode: 0644]
yang/yang-data-impl/src/test/resources/filter-test.yang [new file with mode: 0644]
yang/yang-data-impl/src/test/resources/leafref-context-test/correct-modules/import-mod.yang [new file with mode: 0644]
yang/yang-data-impl/src/test/resources/leafref-context-test/correct-modules/leafref-test.yang [new file with mode: 0644]
yang/yang-data-impl/src/test/resources/leafref-context-test/correct-modules/leafref-test2.yang [new file with mode: 0644]
yang/yang-data-impl/src/test/resources/leafref-context-test/incorrect-modules/leafref-test.yang [new file with mode: 0644]
yang/yang-data-impl/src/test/resources/leafref-validation/leafref-validation.yang [new file with mode: 0644]
yang/yang-data-impl/src/test/resources/leafref-validation/leafref-validation2.yang [new file with mode: 0644]
yang/yang-data-impl/src/test/resources/leafref-validation/leafref-validation3.yang [new file with mode: 0644]
yang/yang-data-operations/pom.xml
yang/yang-data-util/pom.xml
yang/yang-maven-plugin-it/pom.xml
yang/yang-maven-plugin-spi/pom.xml
yang/yang-maven-plugin/pom.xml
yang/yang-model-api/pom.xml
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/stmt/DeviateStatement.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaNodeIdentifier.java
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/SchemaSourceFilter.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/repo/api/SourceIdentifier.java
yang/yang-model-export/pom.xml
yang/yang-model-parent/pom.xml
yang/yang-model-util/pom.xml
yang/yang-parser-api/pom.xml
yang/yang-parser-impl/pom.xml
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/BuilderUtils.java
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/builder/impl/GroupingUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/RpcDefinitionBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/TypeUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/BasicValidations.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.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/impl/YangStatementParserListenerImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/util/URLSchemaContextResolver.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/util/YangModelDependencyInfo.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/SharedSchemaContextFactory.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractStatementSupport.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupportBundle.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/PrefixToModuleMap.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinitionMap.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ModifierImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementDefinitionContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/CaseStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/DeviateStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ExtensionStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/IncludeStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ModuleStatementSupport.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/PrefixStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/SubmoduleStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UnknownStatementImpl.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UsesStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangStatementSourceImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDocumentedDataNodeContainer.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDocumentedNode.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveSchemaContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AnyXmlEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AugmentEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/CaseEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ChoiceEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ContainerEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/DeviateEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/DeviationEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveSchemaContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveStatementBase.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ExtensionEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/IdentityEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ImportEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/InputEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LeafEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LeafListEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ListEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ModuleEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/NotificationEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/OutputEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RpcEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/SubmoduleEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/TopologicalSort.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/builder/impl/BuilderUtilsTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveBuildTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveModuleTest.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/YangFileStatementSource.java [deleted file]
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentProcessTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentTest.java [moved from yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/augment/AugmentTest.java with 50% similarity]
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportBasicTestStatementSource.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/KeyTest.java [moved from yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/key/KeyTest.java with 64% similarity]
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/YangFileStmtTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/augment/TestAugmentSource.java [deleted file]
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/key/TestKeySource.java [deleted file]
yang/yang-parser-impl/src/test/resources/model-new/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/model-new/baz.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/model-new/foo.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/model-new/subfoo.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/imported.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-abs-no-imp.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-abs.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-empty.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-rel1.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-rel2.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-xpath.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-valid-aug-args.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/effective-module/imported.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/effective-module/root.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/effective-module/submod.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/foobar.yang [moved from yang/yang-parser-impl/src/test/resources/semantic-statement-parser/foo.yang with 87% similarity]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/key-arg-parsing/key-comp-duplicate.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/key-arg-parsing/key-simple-and-comp.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/simple-nodes-semantic.yang
yang/yang-parser-impl/src/test/resources/stmt-test/augments/aug-root.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/stmt-test/augments/augmented.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-imported.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-incorrect.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-incorrect2.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-root.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-submodule.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-test.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/stmt-test/effective-build/aug-root.yang [deleted file]
yang/yang-parser-impl/src/test/resources/stmt-test/effective-build/augmented.yang [deleted file]

index 1c5b45ef603938fb728381de38df4292b5941f42..242a71d2fc40a23cdc7e8f06b0ef9321197347f2 100644 (file)
@@ -13,7 +13,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>../common/parent</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
@@ -21,8 +21,8 @@
     <artifactId>benchmarks</artifactId>
 
     <properties>
-        <yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
-        <yang.maven.plugin.version>0.7.0-SNAPSHOT</yang.maven.plugin.version>
+        <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
+        <yang.maven.plugin.version>0.8.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>
index ad611d2d2dfc1240fae07f6c87be09669143058d..f6a179fd88c33bc8b7db142e54d36e123640bf3b 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>binding-generator</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
index 691f8e5a84a9826b1f152db62d4bdc5f57f3a046..b475ad3e3fbd64c6dd73e9059f152fbeb4180718 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>binding-generator</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
index c5ed3cfdb6e8028c117216799a60177ead59d70b..d446c82c1ff9c864467863d4b5034f8e137ddf43 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>binding-generator</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
index 185fd691430bce9927158397f159886d10870fd9..4ed76cc1f76e798d35697e4fd1cac4cb592de5b0 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>binding-generator</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
index 367aaff67bee2e38b019940bad8e87ce535863e2..80e09f2382ec27e0ab6c4bc3cdf8c0f5d1040151 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>binding-generator</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
index 51aa5c7629c587f4ef3310e688d9044adaf504eb..541d2f5859b6ae45e98267d2ab991aa3c5f3ef20 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>binding-generator</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
index cc3a78809a8215943b3f82a2469f8f54ed705313..6699d502006c1682cea241daa1d322b033a67d8c 100644 (file)
@@ -290,15 +290,10 @@ class ClassTemplate extends BaseTemplate {
 
             Â«FOR c : consts»
                 Â«IF c.name == TypeConstants.PATTERN_CONSTANT_NAME && c.value instanceof List<?>»
-            boolean valid = false;
             for (Pattern p : patterns) {
-                if (p.matcher(_value).matches()) {
-                    valid = true;
-                    break;
-                }
+                Â«Preconditions.importedName».checkArgument(p.matcher(_value).matches(), "Supplied value \"%s\" does not match any of the permitted patterns %s", _value, Â«TypeConstants.PATTERN_CONSTANT_NAME»);
             }
 
-            Â«Preconditions.importedName».checkArgument(valid, "Supplied value \"%s\" does not match any of the permitted patterns %s", _value, Â«TypeConstants.PATTERN_CONSTANT_NAME»);
                 Â«ENDIF»
             Â«ENDFOR»
         Â«ENDIF»
index 2403d6e958d22803fae866a505821de1b9658468..235167ef7d6353fe93d83a071c31d11419c919d7 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>binding-generator</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
index c38481e8d499af78d692e66f4c70d63ac1e3ed8c..cc1013ac8aefe52231c9e7a8d38be3e945de8ae6 100644 (file)
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
         <artifactId>bundle-parent</artifactId>
-        <version>1.5.0-SNAPSHOT</version>
+        <version>1.6.0-SNAPSHOT</version>
         <relativePath/>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.opendaylight.yangtools</groupId>
     <artifactId>binding-parent</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>0.8.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <properties>
-        <yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
+        <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
         <salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath>
     </properties>
 
index c93a84c7c133e1133a4443aad2c86743e69f9958..b759f86bdd0665cde31c98bd40e45d04043b3dd0 100644 (file)
@@ -13,7 +13,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>binding-generator</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
index f496868a3f49f4f22e7fa738e6a59f0cfab864cf..f19246475434ef75944dc9136ae55881826cf3ec 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>binding-generator</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
index d7d20c1489e13b118f711b34815436f2cff7ae96..c82c75a8f4dcbf3d68210d798b48770252fbc630 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>binding-generator</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>maven-sal-api-gen-plugin</artifactId>
index 324088dc7d3cffba53ada40b6ead92b7cf8f5f2e..2ce6df0c2a0c3c9e4980a6bd8450f60f8f45c404 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>../common/parent</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
index 52daaac3b81ab05af8626d7069b9909db9c0c804..765ebe254414fc1e4402af327c088d9482275ffc 100644 (file)
@@ -13,7 +13,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>binding-generator</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
     <artifactId>maven-code-gen-sample</artifactId>
 
index 4e1adde8af111b752b3b7f108a8d96dc8a8a5a31..ef68f03e62beffb93ade5a143f18339d259fdea5 100644 (file)
@@ -13,7 +13,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>binding-generator</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
     <artifactId>modeling-sample</artifactId>
 
index 6d862f667510322cf84809552947cbb1802b054a..3f532b469da4d9317c8d0f5a14545091dad06109 100644 (file)
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.opendaylight.yangtools</groupId>
     <artifactId>yangtools-artifacts</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>0.8.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <properties>
         <!-- Model versions -->
-        <ietf.topology.version>2013.10.21.7-SNAPSHOT</ietf.topology.version>
+        <ietf.topology.version>2013.10.21.8-SNAPSHOT</ietf.topology.version>
     </properties>
 
     <dependencyManagement>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>iana-if-type-2014-05-08</artifactId>
-                <version>2014.05.08.7-SNAPSHOT</version>
+                <version>2014.05.08.8-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-inet-types</artifactId>
-                <version>2010.09.24.7-SNAPSHOT</version>
+                <version>2010.09.24.8-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-yang-types</artifactId>
-                <version>2010.09.24.7-SNAPSHOT</version>
+                <version>2010.09.24.8-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-yang-types-20130715</artifactId>
-                <version>2013.07.15.7-SNAPSHOT</version>
+                <version>2013.07.15.8-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-interfaces</artifactId>
-                <version>2014.05.08.7-SNAPSHOT</version>
+                <version>2014.05.08.8-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-restconf</artifactId>
-                <version>2013.10.19.7-SNAPSHOT</version>
+                <version>2013.10.19.8-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>opendaylight-l2-types</artifactId>
-                <version>2013.08.27.7-SNAPSHOT</version>
+                <version>2013.08.27.8-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>yang-ext</artifactId>
-                <version>2013.09.07.7-SNAPSHOT</version>
+                <version>2013.09.07.8-SNAPSHOT</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
index a29a3fe38372ab5aae8bc21628b9487e8cb5fac0..238e78c7ea509ba0ea52587cdd163fd9a7f1e7c5 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
   <artifactId>checkstyle-logging</artifactId>
@@ -21,7 +21,7 @@
     <dependency>
       <groupId>com.puppycrawl.tools</groupId>
       <artifactId>checkstyle</artifactId>
-      <version>5.7</version>
+      <version>6.1.1</version>
     </dependency>
     <dependency>
         <groupId>org.slf4j</groupId>
index 24e048ad97a2027a4989bac705dbd5e471f5baab..bf59c594b4b558ccb953f048eb9d5cc733cc29b8 100644 (file)
@@ -11,14 +11,6 @@ package org.opendaylight.yangtools.checkstyle;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.xml.sax.InputSource;
-
 import com.google.common.collect.Lists;
 import com.puppycrawl.tools.checkstyle.Checker;
 import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
@@ -27,6 +19,12 @@ import com.puppycrawl.tools.checkstyle.PropertiesExpander;
 import com.puppycrawl.tools.checkstyle.api.AuditListener;
 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
 import com.puppycrawl.tools.checkstyle.api.Configuration;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.xml.sax.InputSource;
 
 public class CheckstyleTest {
 
@@ -36,11 +34,11 @@ public class CheckstyleTest {
     @Before
     public void setup() throws CheckstyleException {
         baos = new ByteArrayOutputStream();
-        AuditListener listener = new DefaultLogger(baos, false);
+        final AuditListener listener = new DefaultLogger(baos, false);
 
-        InputSource inputSource = new InputSource(CheckstyleTest.class.getClassLoader().getResourceAsStream(
+        final InputSource inputSource = new InputSource(CheckstyleTest.class.getClassLoader().getResourceAsStream(
                 "checkstyle-logging.xml"));
-        Configuration configuration = ConfigurationLoader.loadConfiguration(inputSource,
+        final Configuration configuration = ConfigurationLoader.loadConfiguration(inputSource,
                 new PropertiesExpander(System.getProperties()), false);
 
         checker = new Checker();
@@ -66,7 +64,7 @@ public class CheckstyleTest {
     @Test
     public void testCodingChecks() {
         verify(CheckCodingStyleTestClass.class, false, "9: Line has Windows line delimiter.", "14: Wrong order for", "24:1: Line contains a tab character.",
-                "22: Line has trailing spaces.", "22: ctor def child at indentation level 16 not at correct indentation, 8", "17:8: Unused import",
+                "22: Line has trailing spaces.", "22: 'ctor def' child have incorrect indentation level 16, expected level should be 8.", "17:8: Unused import",
                 "23: Line has trailing spaces.");
     }
 
index d2b0867d8cb680838202e21192532e87b393dd86..c702ae1e51a7d31e481dc5239f2c55dc84caaf60 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 50ff2715034365bf65876ad73328533e238b8ae6..0e5dbf09735d061c376dcad8f4d18e4e6511b32d 100644 (file)
@@ -13,7 +13,7 @@
    <parent>
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yangtools-parent</artifactId>
-      <version>0.7.0-SNAPSHOT</version>
+      <version>0.8.0-SNAPSHOT</version>
       <relativePath>../parent/pom.xml</relativePath>
    </parent>
    <artifactId>features-test</artifactId>
@@ -27,7 +27,7 @@
      <relocation>
        <groupId>org.opendaylight.odlparent</groupId>
        <artifactId>features-test</artifactId>
-       <version>1.5.0-SNAPSHOT</version>
+       <version>1.6.0-SNAPSHOT</version>
        <message>This artifact has been migrated to odlparent and will be removed in Lithium release</message>
      </relocation>
    </distributionManagement>
index d59c952d30cbdf611cdfcb4c808d7df5d4b12c87..d6d1647e40cd3a74bbe4c9816b907001e0a8c54f 100644 (file)
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
         <artifactId>features-parent</artifactId>
-        <version>1.5.0-SNAPSHOT</version>
+        <version>1.6.0-SNAPSHOT</version>
         <relativePath/>
     </parent>
 
     <groupId>org.opendaylight.yangtools</groupId>
     <artifactId>features-yangtools</artifactId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>0.8.0-SNAPSHOT</version>
     <packaging>jar</packaging>
 
     <dependencyManagement>
index 1637e1f9cbc3ccdde018767b948a28fc700a1094..7788fe49f1366896e4012976c6eac19c985f8602 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 568834cdd80d2c26c2c1b064097022eb20ab8e81..0fc11fc5580e0eed09f806c3f841969fed8bb373 100644 (file)
@@ -13,7 +13,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
     <packaging>bundle</packaging>
index ed837d1ace1d9c2cf838bc7493b0112c23bccec3..e198df3ecf4e745f05efff92dbb9bfb505defd32 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 2105738dd66ec9b2aea519792c10135f68075055..7e4268c37b09b98659059d6d85ba75c02eb62f8d 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
     <packaging>bundle</packaging>
index 6341f11cfb30960cbbed594077692c14c13642d3..da7b5eacbc2bb2ca9b991034e57cd4c49a9f3108 100644 (file)
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
         <artifactId>odlparent</artifactId>
-        <version>1.5.0-SNAPSHOT</version>
+        <version>1.6.0-SNAPSHOT</version>
         <relativePath></relativePath>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>yangtools-parent</artifactId>
     <groupId>org.opendaylight.yangtools</groupId>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>0.8.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <properties>
-        <yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
+        <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
 
         <!-- FIXME: these will be upstreamed -->
         <maven.depends.version>1.2</maven.depends.version>
                 <plugin>
                     <groupId>org.opendaylight.yangtools</groupId>
                     <artifactId>yang-maven-plugin</artifactId>
-                    <version>0.7.0-SNAPSHOT</version>
+                    <version>0.8.0-SNAPSHOT</version>
                     <executions>
                         <execution>
                             <goals>
                         <dependency>
                             <groupId>org.opendaylight.yangtools</groupId>
                             <artifactId>maven-sal-api-gen-plugin</artifactId>
-                            <version>0.7.0-SNAPSHOT</version>
+                            <version>0.8.0-SNAPSHOT</version>
                             <type>jar</type>
                         </dependency>
                     </dependencies>
index 8c0bf84b1bcfeb4183fc1474e8ef45feff2b9d0d..cff1d1feff58046bf946446ba7e863d0d101a2d8 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yangtools-parent</artifactId>
-      <version>0.7.0-SNAPSHOT</version>
+      <version>0.8.0-SNAPSHOT</version>
       <relativePath>parent</relativePath>
     </parent>
 
index 9c9ab40246a8c12b87347792a62a01d4492c1d5c..c32b829dce8ec2c1749cc4b375e8f6b246871970 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
     <packaging>bundle</packaging>
index c2d2746263d5a24d6cb6f48934ab7ec0674fb84a..447b1fb2fb8351b05a6bbe52ec5a64fea6ee5c41 100644 (file)
@@ -10,7 +10,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
                     <dependency>
                         <groupId>org.opendaylight.yangtools</groupId>
                         <artifactId>yang-binding</artifactId>
-                        <version>0.7.0-SNAPSHOT</version>
+                        <version>0.8.0-SNAPSHOT</version>
                     </dependency>
                     <dependency>
                         <groupId>org.opendaylight.yangtools</groupId>
                         <artifactId>yang-common</artifactId>
-                        <version>0.7.0-SNAPSHOT</version>
+                        <version>0.8.0-SNAPSHOT</version>
                     </dependency>
                 </dependencies>
             </plugin>
index 9a7177229b87fd0b55d8d976c0098abe655ecae8..f65011a00299f0a36626ece49cd9e282c6951472 100644 (file)
@@ -10,7 +10,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 42235ace5c538515a5a26f7758e4fc5cb337f41e..7f16ef284b918ea1fed93aa7c8085c5946ececbf 100644 (file)
@@ -10,7 +10,7 @@
     <parent>
         <artifactId>yangtools-parent</artifactId>
         <groupId>org.opendaylight.yangtools</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 0871e056e70544e2a207d4fd5daa8a73f3a7bb8d..8c1331dc552fa89acfc7d783c047e98412c9a316 100644 (file)
@@ -10,7 +10,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>../common/parent</relativePath>
     </parent>
 
index 4b0a4f1d7f6a99858c3d8024934ca1f73ce7d0a6..ad25fcc8bbf87833e3d776541b4dafc45bd7cbd2 100644 (file)
@@ -9,7 +9,7 @@
 
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <artifactId>yangtools-parent</artifactId>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
index 656ed68187738ca04c3e010d71eb518a97f53720..749217dbc4a69d032a4fc4ed13a9241bc731191d 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
@@ -60,7 +60,7 @@
                     <dependency>
                         <groupId>org.opendaylight.yangtools</groupId>
                         <artifactId>maven-sal-api-gen-plugin</artifactId>
-                        <version>0.7.0-SNAPSHOT</version>
+                        <version>0.8.0-SNAPSHOT</version>
                         <type>jar</type>
                     </dependency>
                 </dependencies>
index c145dc54ffa19de9a9f83f97f5e2c58a0a4aa5fe..89c0b68fbacae1b35cf068b8383487bf463bcd97 100644 (file)
@@ -11,7 +11,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 57bd56c9be34eae1848c01c97ecd40916b20ed27..de82000313359b0b9a45d764d11123ed969a07c5 100644 (file)
     <parent>
         <artifactId>model-iana</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>iana-afn-safi</artifactId>
-    <version>2013.07.04.7-SNAPSHOT</version>
+    <version>2013.07.04.8-SNAPSHOT</version>
 
     <build>
         <plugins>
index 979dfdf819dca75e3688a3ccf287a5ea87d6077f..3815db3fc5dc94d23eb673913e99850ec3c39168 100644 (file)
     <parent>
         <artifactId>model-iana</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>iana-if-type-2014-05-08</artifactId>
-    <version>2014.05.08.7-SNAPSHOT</version>
+    <version>2014.05.08.8-SNAPSHOT</version>
     <name>${project.artifactId}</name>
     <description>${project.artifactId}</description>
 
index b354c1c7cab3d46479b8f31afe5ccf05acaed39a..fb011b8145af34f2a7d2894345684749d3824e7a 100644 (file)
     <parent>
         <artifactId>model-iana</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>iana-if-type</artifactId>
-    <version>2013.07.04.7-SNAPSHOT</version>
+    <version>2013.07.04.8-SNAPSHOT</version>
 
     <build>
         <plugins>
index 13eb5db290d5645de0684c1b0d80652b30e98234..843c084db3211070576c3a4672ea2307132cc1e2 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <artifactId>model-parent</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
index 9759f5ce93a98b7351f8b2762aa1f04ac77578d7..cad85086202a35ccbdfc659a814879c0f45f4970 100644 (file)
     <parent>
         <artifactId>model-ietf</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>ietf-inet-types</artifactId>
-    <version>2010.09.24.7-SNAPSHOT</version>
+    <version>2010.09.24.8-SNAPSHOT</version>
     <name>${project.artifactId}</name>
     <description>${project.artifactId}</description>
 
index 1339fc06cf7e101ae6d1e1183a5c6aabeb9721db..d2259d006b21382a680aebf62da509e503065b1f 100644 (file)
@@ -16,24 +16,23 @@ public class HostBuilderTest {
 
     @Test
     public void testGetDefaultInstanceIpv4() throws Exception {
-        Host host = HostBuilder.getDefaultInstance("127.0.0.1");
+        final Host host = HostBuilder.getDefaultInstance("127.0.0.1");
         assertEquals(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))), host);
     }
 
     @Test
     public void testGetDefaultInstanceIpv6() throws Exception {
-        testIpv6("2001:db8:8s5a3:0:0:8a2e:370:7334");
-        testIpv6("2001:db8:85a3::8a2e:370:7334");
+        testIpv6("1234:5678:9abc:def1:2345:6789:abcd:ef12");
     }
 
     private void testIpv6(final String ivp6string) {
-        Host host = HostBuilder.getDefaultInstance(ivp6string);
+        final Host host = HostBuilder.getDefaultInstance(ivp6string);
         assertEquals(new Host(new IpAddress(new Ipv6Address(ivp6string))), host);
     }
 
     @Test
     public void testGetDefaultInstanceDomain() throws Exception {
-        Host host = HostBuilder.getDefaultInstance("localhost");
+        final Host host = HostBuilder.getDefaultInstance("localhost");
         assertEquals(new Host(new DomainName("localhost")), host);
     }
 }
\ No newline at end of file
index f1bc48457d309772e32222cd001edd3ddda64f47..ac561979dc3694e62d7a5ca3dcccf259b39a0b3f 100644 (file)
     <parent>
         <artifactId>model-ietf</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>ietf-interfaces</artifactId>
-    <version>2014.05.08.7-SNAPSHOT</version>
+    <version>2014.05.08.8-SNAPSHOT</version>
     <name>${project.artifactId}</name>
     <description>${project.artifactId}</description>
 
index e9ce3701373f407357650f202c1ad09ee3543653..f25ffe79468a13578d665c21f3a3e82262f7a46d 100644 (file)
     <parent>
         <artifactId>model-ietf</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>ietf-restconf</artifactId>
-    <version>2013.10.19.7-SNAPSHOT</version>
+    <version>2013.10.19.8-SNAPSHOT</version>
     <name>${project.artifactId}</name>
     <description>${project.artifactId}</description>
 
index d8f758d8783473e94a151943f9ea813678dd585a..f060fe23f506aefb9b2ec20a75cf1c95ed2b206d 100644 (file)
     <parent>
         <artifactId>model-ietf</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>ietf-ted</artifactId>
-    <version>2013.10.21.7-SNAPSHOT</version>
+    <version>2013.10.21.8-SNAPSHOT</version>
     <name>${project.artifactId}</name>
     <description>${project.artifactId}</description>
 
index 77c026bf4cc652531e53f3aa267e7580e3430878..9063160570836bffbba39e424bb67c15d66b862b 100644 (file)
     <parent>
         <artifactId>model-ietf</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>ietf-topology-isis</artifactId>
-    <version>2013.10.21.7-SNAPSHOT</version>
+    <version>2013.10.21.8-SNAPSHOT</version>
     <name>${project.artifactId}</name>
     <description>${project.artifactId}</description>
 
index 6d00b7814b7bced60b344438696f38be43e4b17a..071d5aadb2168d6cb4bad1744b576bea1eb7d432 100644 (file)
     <parent>
         <artifactId>model-ietf</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>ietf-topology-l3-unicast-igp</artifactId>
-    <version>2013.10.21.7-SNAPSHOT</version>
+    <version>2013.10.21.8-SNAPSHOT</version>
     <name>${project.artifactId}</name>
     <description>${project.artifactId}</description>
 
index 64f2eb5dfa067109074c8d6447278be96ce00728..7344aab89bbc2c977e16a7a2c32169240d26b88e 100644 (file)
     <parent>
         <artifactId>model-ietf</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>ietf-topology-ospf</artifactId>
-    <version>2013.10.21.7-SNAPSHOT</version>
+    <version>2013.10.21.8-SNAPSHOT</version>
     <name>${project.artifactId}</name>
     <description>${project.artifactId}</description>
 
index ea135bbb88bbb9977c42b1a6da4c6c027b457266..1954710a68a5e2eafc93bfdca49174e9985961e0 100644 (file)
     <parent>
         <artifactId>model-ietf</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>ietf-topology</artifactId>
-    <version>2013.10.21.7-SNAPSHOT</version>
+    <version>2013.10.21.8-SNAPSHOT</version>
     <name>${project.artifactId}</name>
     <description>${project.artifactId}</description>
 
index 25df3cebcaf72566136ac31e49f952116246de04..9d6c5eeba4220935f12b560c8989619b1f4ee7bd 100644 (file)
     <parent>
         <artifactId>model-ietf</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>ietf-yang-types-20130715</artifactId>
-    <version>2013.07.15.7-SNAPSHOT</version>
+    <version>2013.07.15.8-SNAPSHOT</version>
     <name>${project.artifactId}</name>
     <description>${project.artifactId}</description>
 
index 685d70daff2ed1adc8d0a02402b682a2c11e68c2..9c20f894354eabc56dc7dc76bc4816077ef0131a 100644 (file)
     <parent>
         <artifactId>model-ietf</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>ietf-yang-types</artifactId>
-    <version>2010.09.24.7-SNAPSHOT</version>
+    <version>2010.09.24.8-SNAPSHOT</version>
     <name>${project.artifactId}</name>
     <description>${project.artifactId}</description>
 
index 5677b0c11bd687a46b0a487bc18a24d6f6242e6a..0e958f85c2a7745ba53d20513f2044af7f7b514b 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <artifactId>model-parent</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
index c47cc0a90e3494baab6438743a3ae3e9bd3c1346..0b27bcd067fdd24707e30a7b9063554f4817010d 100644 (file)
     <parent>
         <artifactId>model-parent</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>opendaylight-l2-types</artifactId>
-    <version>2013.08.27.7-SNAPSHOT</version>
+    <version>2013.08.27.8-SNAPSHOT</version>
 
     <build>
         <plugins>
index 206d1b288601b9a6c7f974a14bec51facaf75d07..cc77098d0d383cd59d080e156e7791cc9f7c9c95 100644 (file)
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>../common/parent</relativePath>
     </parent>
     <groupId>org.opendaylight.yangtools.model</groupId>
-    <!--<version>0.7.0-SNAPSHOT</version>-->
+    <!--<version>0.8.0-SNAPSHOT</version>-->
     <modelVersion>4.0.0</modelVersion>
     <artifactId>model-parent</artifactId>
     <packaging>pom</packaging>
@@ -68,7 +68,7 @@
                     <dependency>
                         <groupId>org.opendaylight.yangtools</groupId>
                         <artifactId>maven-sal-api-gen-plugin</artifactId>
-                        <version>0.7.0-SNAPSHOT</version>
+                        <version>0.8.0-SNAPSHOT</version>
                         <type>jar</type>
                     </dependency>
                 </dependencies>
index 2bb3db677f40f85af0c3b6ab6006e3638fcfd344..3cbe1766fd3c7eda4480c989a2f8fc6c6df366b0 100644 (file)
     <parent>
         <artifactId>model-parent</artifactId>
         <groupId>org.opendaylight.yangtools.model</groupId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>yang-ext</artifactId>
-    <version>2013.09.07.7-SNAPSHOT</version>
+    <version>2013.09.07.8-SNAPSHOT</version>
     <name>${project.artifactId}</name>
     <description>${project.artifactId}</description>
 
diff --git a/pom.xml b/pom.xml
index e64f5c3bfe9bf6c56bfbea7efc8f9b2105c8011c..395da84e1b98f839ead10c4284afa644b7e5e98b 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -13,7 +13,7 @@
     <parent>
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yangtools-parent</artifactId>
-      <version>0.7.0-SNAPSHOT</version>
+      <version>0.8.0-SNAPSHOT</version>
       <relativePath>common/parent</relativePath>
     </parent>
 
index fba0fb7d03ba2e67d937a9126f5b4c516277e216..084719b9979d79cc51257d7ad50f3536e1984b87 100644 (file)
@@ -10,7 +10,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>../common/parent</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
index 130e7dffbbbb1532dded88ad00f9ccb1dead98cc..2f2f003255a19c959ef9e35dfe7fa6ac90411885 100644 (file)
@@ -15,7 +15,7 @@
    <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>restconf-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
     <dependencies>
         <dependency>
index fe46d36d92b218e7e7db529914e726635580ac11..690c391d251b8bd572ce5f0a8efd9ffa277a0a82 100644 (file)
@@ -14,7 +14,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>restconf-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
   <artifactId>restconf-client-impl</artifactId>
index dbb4819085c9cf225890047d2d415d95bdefcc26..89926c8af84a5e4a6092e8f8629939b0067f45d4 100644 (file)
@@ -14,7 +14,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>restconf-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>restconf-common</artifactId>
index aa91bc614bed2c1fdb70357fa9b2073a515ab6fc..3ea648c92783ca5e0ee03af3fa9604fd550d6852 100644 (file)
@@ -13,7 +13,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>restconf-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
     <artifactId>restconf-jaxrs-api</artifactId>
     <name>restconf-jaxrs-api</name>
index 7c079b9c0f31bd9af6245a7f0ba994bcfce41317..9f36d6f9351b77ffe0c790543a6ac5cfe2d0b25b 100644 (file)
@@ -14,7 +14,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>restconf-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>restconf-test-service</artifactId>
index 9ebb9ba3a4e47ad18055bcf22a06a9ae16e7bc8b..3110382acae9bdaea82f838dcaa2efc73d78f465 100644 (file)
@@ -11,7 +11,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>restconf-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>restconf-util</artifactId>
index 7442f99b3a8205f92a85394e2cb97142e5badb5a..95ef64179c4aa186e0eb0fce30bcdf19f5051c8c 100644 (file)
@@ -14,7 +14,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>third-party-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
index c22c469cc2f12640b191530b351e5e98d44ab405..1727bdba7db9728d1c24c431f80dfc043a5fb228 100644 (file)
@@ -14,7 +14,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>../parent/pom.xml</relativePath>
     </parent>
 
index 8acd61daaffd8783a2a79b4b7731e98b1a7490dd..ab7fdff9d4d3f725ea05e17ef4b12addbb8748c7 100644 (file)
@@ -13,7 +13,7 @@
     <parent>
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yangtools-parent</artifactId>
-      <version>0.7.0-SNAPSHOT</version>
+      <version>0.8.0-SNAPSHOT</version>
       <relativePath>../common/parent</relativePath>
     </parent>
 
index 341099985966b42f5bf6985d8c7bae426651bbfd..5ed7bf67479054a387307f560c3b52f2ca4453d5 100644 (file)
@@ -14,7 +14,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 8dbaa1df2373af2b0b5a88fa4d9919aeb6859852..cbbc6ce6ea745b357efa347cd79aa4d2785a6159 100644 (file)
@@ -13,7 +13,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-aggregator</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
     </parent>
     <artifactId>yang-validation-tool</artifactId>
 
index 01e71bd5477661fc2afa507ff58fb3cfaa7a909a..546339a2abe179af3806e7b963d98d2edd3ce5d4 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yangtools-parent</artifactId>
-      <version>0.7.0-SNAPSHOT</version>
+      <version>0.8.0-SNAPSHOT</version>
       <relativePath>../common/parent</relativePath>
     </parent>
 
index ada7f5a89ddd2a74a95f6d30a1f79c16af367a58..0d03ad751a775f524ff4700c6c2209a52613330a 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index dc732e3dab4aaf34e357bf2b469472b27a03ed21..19a2656d88d96fbc63b164f220743247b1c30571 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 688dbb1fdbe2757fdfe7c8cd5b9c0bfb368558cf..73505cd9977ba7c4f4ed73583946bd19df13d779 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 5863b31168a0d1a21323a88091dfe90041581e7e..53b8343cd18760a5977a2681c879672c10dcbfde 100644 (file)
@@ -71,12 +71,16 @@ import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
  * @see <a href="http://tools.ietf.org/html/rfc6020#section-9.13">RFC6020</a>
  */
 public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier>, Immutable, Serializable {
+    /**
+     * An empty {@link YangInstanceIdentifier}. It corresponds to the path of the conceptual
+     * root of the YANG namespace.
+     */
+    public static final YangInstanceIdentifier EMPTY = trustedCreate(Collections.<PathArgument>emptyList());
     @SuppressWarnings("rawtypes")
     private static final AtomicReferenceFieldUpdater<YangInstanceIdentifier, ImmutableList> LEGACYPATH_UPDATER =
             AtomicReferenceFieldUpdater.newUpdater(YangInstanceIdentifier.class, ImmutableList.class, "legacyPath");
     private static final AtomicReferenceFieldUpdater<YangInstanceIdentifier, String> TOSTRINGCACHE_UPDATER =
             AtomicReferenceFieldUpdater.newUpdater(YangInstanceIdentifier.class, String.class, "toStringCache");
-    private static final YangInstanceIdentifier EMPTY = trustedCreate(Collections.<PathArgument>emptyList());
     private static final Field PATHARGUMENTS_FIELD;
 
     private static final long serialVersionUID = 3L;
diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/BackendFailedException.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/BackendFailedException.java
new file mode 100644 (file)
index 0000000..e683947
--- /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.data.api.schema.tree;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Exception thrown when the backed of a {@link DataTreeSnapshotCursor}
+ * detects an errors which prevents it from completing the requested operation.
+ */
+@Beta
+public class BackendFailedException extends IllegalStateException {
+    private static final long serialVersionUID = 1L;
+
+    public BackendFailedException(final String message) {
+        super(message);
+    }
+
+    public BackendFailedException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/CursorAwareDataTreeModification.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/CursorAwareDataTreeModification.java
new file mode 100644 (file)
index 0000000..9154d0a
--- /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.data.api.schema.tree;
+
+import com.google.common.annotations.Beta;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+/**
+ * A {@link DataTreeModification} which allows creation of a {@link DataTreeModificationCursor}.
+ */
+@Beta
+public interface CursorAwareDataTreeModification extends DataTreeModification, CursorAwareDataTreeSnapshot {
+    /**
+     * Create a new {@link DataTreeModificationCursor} at specified path. May fail
+     * if specified path does not exist. It is a programming error to use normal
+     *
+     *
+     * @param path Path at which the cursor is to be anchored
+     * @return A new cursor, or null if the path does not exist.
+     * @throws IllegalStateException if there is another cursor currently open,
+     *                               or the modification is already {@link #ready()}.
+     */
+    @Override
+    @Nullable DataTreeModificationCursor createCursor(@Nonnull YangInstanceIdentifier path);
+}
diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/CursorAwareDataTreeSnapshot.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/CursorAwareDataTreeSnapshot.java
new file mode 100644 (file)
index 0000000..a9252ba
--- /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.data.api.schema.tree;
+
+import com.google.common.annotations.Beta;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+/**
+ * A {@link DataTreeSnapshot} which allows creation of a {@link DataTreeSnapshotCursor}.
+ */
+@Beta
+public interface CursorAwareDataTreeSnapshot extends DataTreeSnapshot {
+    /**
+     * Create a new {@link DataTreeSnapshotCursor} at specified path. May fail
+     * if specified path does not exist.
+     *
+     * @param path Path at which the cursor is to be anchored
+     * @return A new cursor, or null if the path does not exist.
+     * @throws IllegalStateException if there is another cursor currently open.
+     */
+    @Nullable DataTreeSnapshotCursor createCursor(@Nonnull YangInstanceIdentifier path);
+}
index 441f92776373383156f78479ff9838a91e578cc1..99256397b0e9197f9cb156060c8c03fb7b76278f 100644 (file)
@@ -10,12 +10,15 @@ package org.opendaylight.yangtools.yang.data.api.schema.tree;
 import com.google.common.annotations.Beta;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Utility class holding methods useful when dealing with {@link DataTreeCandidate} instances.
  */
 @Beta
 public final class DataTreeCandidates {
+    private static final Logger LOG = LoggerFactory.getLogger(DataTreeCandidates.class);
     private DataTreeCandidates() {
         throw new UnsupportedOperationException();
     }
@@ -29,24 +32,57 @@ public final class DataTreeCandidates {
     }
 
     public static void applyToModification(final DataTreeModification modification, final DataTreeCandidate candidate) {
-        applyNode(modification, candidate.getRootPath(), candidate.getRootNode());
+        if (modification instanceof CursorAwareDataTreeModification) {
+            try (DataTreeModificationCursor cursor = ((CursorAwareDataTreeModification) modification).createCursor(candidate.getRootPath())) {
+                applyNode(cursor, candidate.getRootNode());
+            }
+        } else {
+            applyNode(modification, candidate.getRootPath(), candidate.getRootNode());
+        }
     }
 
     private static void applyNode(final DataTreeModification modification, final YangInstanceIdentifier path, final DataTreeCandidateNode node) {
         switch (node.getModificationType()) {
         case DELETE:
             modification.delete(path);
+            LOG.debug("Modification {} deleted path {}", modification, path);
             break;
         case SUBTREE_MODIFIED:
+            LOG.debug("Modification {} modified path {}", modification, path);
             for (DataTreeCandidateNode child : node.getChildNodes()) {
                 applyNode(modification, path.node(child.getIdentifier()), child);
             }
             break;
         case UNMODIFIED:
+            LOG.debug("Modification {} unmodified path {}", modification, path);
             // No-op
             break;
         case WRITE:
             modification.write(path, node.getDataAfter().get());
+            LOG.debug("Modification {} written path {}", modification, path);
+            break;
+        default:
+            throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+        }
+    }
+
+    private static void applyNode(final DataTreeModificationCursor cursor, final DataTreeCandidateNode node) {
+        switch (node.getModificationType()) {
+        case DELETE:
+            cursor.delete(node.getIdentifier());
+            break;
+        case SUBTREE_MODIFIED:
+            cursor.enter(node.getIdentifier());
+            for (DataTreeCandidateNode child : node.getChildNodes()) {
+                applyNode(cursor, child);
+            }
+            cursor.exit();
+            break;
+        case UNMODIFIED:
+            // No-op
+            break;
+        case WRITE:
+            cursor.write(node.getIdentifier(), node.getDataAfter().get());
             break;
         default:
             throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
index 2d11f106b079391d86f283c34faadfa463b44abf..1ee737805710a1954d03bc89b6fe2395f743599a 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.data.api.schema.tree;
 
+import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
@@ -42,9 +43,20 @@ public interface DataTreeModification extends DataTreeSnapshot {
 
     /**
      * Finish creation of a modification, making it ready for application
-     * to the data tree. Any calls to this object's methods will result
+     * to the data tree. Any calls to this object's methods except
+     * {@link #applyToCursor(DataTreeModificationCursor)} will result
      * in undefined behavior, possibly with an
      * {@link IllegalStateException} being thrown.
      */
     void ready();
+
+    /**
+     * Apply the contents of this modification to a cursor. This can be used
+     * to replicate this modification onto another one. The cursor's position
+     * must match the root of this modification, otherwise performing this
+     * operation will result in undefined behavior.
+     *
+     * @param cursor cursor to which this modification
+     */
+    void applyToCursor(@Nonnull DataTreeModificationCursor cursor);
 }
diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/DataTreeModificationCursor.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/DataTreeModificationCursor.java
new file mode 100644 (file)
index 0000000..964ec83
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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.api.schema.tree;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Extension to the {@link DataTreeSnapshotCursor} which allows modifying the data tree.
+ * An instance of this interface can be obtained from {@link CursorAwareDataTreeModification}
+ * and modifications made through this interface are staged in the parent modification.
+ */
+@Beta
+public interface DataTreeModificationCursor extends DataTreeSnapshotCursor {
+    /**
+     * Delete the specified child.
+     *
+     * @param child Child identifier
+     * @throws BackendFailedException when implementation-specific errors occurs
+     *                                while servicing the request.
+     */
+    void delete(PathArgument child);
+
+    /**
+     * Merge the specified data with the currently-present data
+     * at specified path.
+     *
+     * @param child Child identifier
+     * @param data Data to be merged
+     * @throws BackendFailedException when implementation-specific errors occurs
+     *                                while servicing the request.
+     */
+    void merge(PathArgument child, NormalizedNode<?, ?> data);
+
+    /**
+     * Replace the data at specified path with supplied data.
+     *
+     * @param child Child identifier
+     * @param data New node data
+     * @throws BackendFailedException when implementation-specific errors occurs
+     *                                while servicing the request.
+     */
+    void write(PathArgument child, NormalizedNode<?, ?> data);
+}
diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/DataTreeSnapshotCursor.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/DataTreeSnapshotCursor.java
new file mode 100644 (file)
index 0000000..a2ebb4f
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * 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.api.schema.tree;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
+
+/**
+ * A cursor holding a logical position within a {@link DataTreeSnapshot}. It allows
+ * operations relative to that position, as well as moving the position up or down
+ * the tree.
+ */
+@Beta
+public interface DataTreeSnapshotCursor extends AutoCloseable {
+    /**
+     * Move the cursor to the specified child of the current position.
+     *
+     * @param child Child identifier
+     * @throws BackendFailedException when implementation-specific errors occurs
+     *                                while servicing the request.
+     * @throws IllegalArgumentException when specified identifier does not identify
+     *                                  a valid child, or if that child is not an
+     *                                  instance of {@link NormalizedNodeContainer}.
+     */
+    void enter(@Nonnull PathArgument child);
+
+    /**
+     * Move the cursor to the specified child of the current position. This is
+     * the equivalent of multiple invocations of {@link #enter(PathArgument)},
+     * except the operation is performed atomically.
+     *
+     * @param path Nested child identifier
+     * @throws BackendFailedException when implementation-specific errors occurs
+     *                                while servicing the request.
+     * @throws IllegalArgumentException when specified path does not identify
+     *                                  a valid child, or if that child is not an
+     *                                  instance of {@link NormalizedNodeContainer}.
+     */
+    void enter(@Nonnull PathArgument... path);
+
+    /**
+     * Move the cursor to the specified child of the current position. This is
+     * equivalent to {@link #enter(PathArgument...)}, except it takes an {@link Iterable}
+     * argument.
+     *
+     * @param path Nested child identifier
+     * @throws BackendFailedException when implementation-specific errors occurs
+     *                                while servicing the request.
+     * @throws IllegalArgumentException when specified path does not identify
+     *                                  a valid child, or if that child is not an
+     *                                  instance of {@link NormalizedNodeContainer}.
+     */
+    void enter(@Nonnull Iterable<PathArgument> path);
+
+    /**
+     * Move the cursor up to the parent of current position. This is equivalent of
+     * invoking <code>exit(1)</code>.
+     *
+     * @throws IllegalStateException when exiting would violate containment, typically
+     *                               by attempting to exit more levels than previously
+     *                               entered.
+     */
+    void exit();
+
+    /**
+     * Move the cursor up by specified amounts of steps from the current position.
+     * This is equivalent of invoking {@link #exit()} multiple times, except the
+     * operation is performed atomically.
+     *
+     * @param depth number of steps to exit
+     * @throws IllegalArgumentException when depth is negative.
+     * @throws IllegalStateException when exiting would violate containment, typically
+     *                               by attempting to exit more levels than previously
+     *                               entered.
+     */
+    void exit(int depth);
+
+    /**
+     * Read a particular node from the snapshot.
+     *
+     * @param child Child identifier
+     * @return Optional result encapsulating the presence and value of the node
+     * @throws BackendFailedException when implementation-specific error occurs while
+     *                                servicing the request.
+     * @throws IllegalArgumentException when specified path does not identify a valid child.
+     */
+    Optional<NormalizedNode<?, ?>> readNode(@Nonnull PathArgument child);
+
+    /**
+     * Close this cursor. Attempting any further operations on the cursor will lead
+     * to undefined behavior.
+     */
+    @Override
+    void close();
+}
index 81aa6dcd82cde602c98b7f676601cb3037a6335f..8491a42488b1c79a4f896d82c3e62df9f574e1bd 100644 (file)
@@ -57,4 +57,9 @@ public final class SynchronizedDataTreeModification implements DataTreeModificat
     public synchronized void ready() {
         delegate.ready();
     }
+
+    @Override
+    public synchronized void applyToCursor(final DataTreeModificationCursor cursor) {
+        delegate.applyToCursor(cursor);
+    }
 }
index fd7481133768f0e605af26ad45b15cd741c1cbc0..f366cc1ebf227372e26255a3cbc8525dbd3909be 100644 (file)
@@ -11,7 +11,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 0b64b2296782e939dc239f5a6b93e9abb6b8a3ef..b9fddf3ecf5a063c86ddeab1a93b958f7f07641a 100644 (file)
@@ -93,8 +93,9 @@ final class RpcAsContainer implements ContainerSchemaNode {
                 return delegate.getInput();
             case "output":
                 return delegate.getOutput();
+            default:
+                return null;
         }
-        return null;
     }
 
     @Override
@@ -114,7 +115,7 @@ final class RpcAsContainer implements ContainerSchemaNode {
 
     @Override
     public Collection<DataSchemaNode> getChildNodes() {
-        final ArrayList<DataSchemaNode> ret = new ArrayList<>();
+        final List<DataSchemaNode> ret = new ArrayList<>();
         final ContainerSchemaNode input = getInput();
         final ContainerSchemaNode output = getOutput();
         if(input != null) {
index 0953073f529a66582b9b9537aa560d0f1d92572b..ca55ad025516d66f82dd670031ee6104b3e1ae4c 100644 (file)
@@ -10,7 +10,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
 
     <build>
         <plugins>
+            <plugin>
+                <groupId>org.antlr</groupId>
+                <artifactId>antlr4-maven-plugin</artifactId>
+                <version>4.0</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>antlr4</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <sourceDirectory>src/main/antlr</sourceDirectory>
+                    <outputDirectory>target/generated-sources/parser/org/opendaylight/yangtools/yang/data/impl/leafref</outputDirectory>
+                    <visitor>true</visitor>
+                    <listener>true</listener>
+                </configuration>
+            </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-plugin</artifactId>
                 </configuration>
             </plugin>
         </plugins>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.eclipse.m2e</groupId>
+                    <artifactId>lifecycle-mapping</artifactId>
+                    <version>1.0.0</version>
+                    <configuration>
+                        <lifecycleMappingMetadata>
+                            <pluginExecutions>
+                                <pluginExecution>
+                                    <pluginExecutionFilter>
+                                        <groupId>org.antlr</groupId>
+                                        <artifactId>antlr4-maven-plugin</artifactId>
+                                        <versionRange>[4.0,)</versionRange>
+                                        <goals>
+                                            <goal>antlr4</goal>
+                                        </goals>
+                                    </pluginExecutionFilter>
+                                    <action>
+                                        <execute />
+                                    </action>
+                                </pluginExecution>
+                            </pluginExecutions>
+                        </lifecycleMappingMetadata>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
     </build>
 
     <dependencies>
             <groupId>com.google.code.findbugs</groupId>
             <artifactId>jsr305</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.antlr</groupId>
+            <artifactId>antlr4-runtime</artifactId>
+            <version>4.0</version>
+        </dependency>
     </dependencies>
 </project>
diff --git a/yang/yang-data-impl/src/main/antlr/LeafRefPathLexer.g4 b/yang/yang-data-impl/src/main/antlr/LeafRefPathLexer.g4
new file mode 100644 (file)
index 0000000..526c7ca
--- /dev/null
@@ -0,0 +1,20 @@
+lexer grammar LeafRefPathLexer;\r
+\r
+@header {\r
+package org.opendaylight.yangtools.yang.data.impl.leafref;\r
+}\r
+\r
+COLON : ':' ;\r
+SLASH : '/' ;\r
+DOTS : '..' ;\r
+EQUAL : '=' ;\r
+LEFT_SQUARE_BRACKET : '[' ;\r
+RIGHT_SQUARE_BRACKET : ']' ;\r
+LEFT_PARENTHESIS : '(' ;\r
+RIGHT_PARENTHESIS : ')' ;\r
+\r
+CURRENT_KEYWORD : 'current';\r
+\r
+SEP: [ \n\r\t]+ ;\r
+IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_\-.]*;\r
+\r
diff --git a/yang/yang-data-impl/src/main/antlr/LeafRefPathParser.g4 b/yang/yang-data-impl/src/main/antlr/LeafRefPathParser.g4
new file mode 100644 (file)
index 0000000..535d040
--- /dev/null
@@ -0,0 +1,39 @@
+parser grammar LeafRefPathParser;\r
+\r
+@header {\r
+package org.opendaylight.yangtools.yang.data.impl.leafref;\r
+}\r
+\r
+options{\r
+ tokenVocab = LeafRefPathLexer;\r
+}\r
+\r
+path_arg : absolute_path | relative_path;\r
+\r
+absolute_path : (SLASH node_identifier (path_predicate)*)+; \r
+\r
+relative_path : (DOTS SLASH)* descendant_path;\r
+\r
+descendant_path : node_identifier ((path_predicate)* absolute_path)?;\r
+\r
+path_predicate : LEFT_SQUARE_BRACKET SEP? path_equality_expr SEP? RIGHT_SQUARE_BRACKET;\r
+\r
+path_equality_expr : node_identifier SEP? EQUAL SEP? path_key_expr;\r
+\r
+path_key_expr : current_function_invocation SEP? SLASH SEP? rel_path_keyexpr;\r
+\r
+rel_path_keyexpr : (DOTS SEP? SLASH SEP?)* (node_identifier SEP? SLASH SEP?)* node_identifier;\r
+\r
+node_identifier : (prefix COLON)? identifier;\r
+\r
+current_function_invocation : CURRENT_KEYWORD SEP? LEFT_PARENTHESIS SEP? RIGHT_PARENTHESIS;\r
+\r
+descendant_schema_nodeid :  node_identifier\r
+                            absolute_schema_nodeid;\r
+\r
+absolute_schema_nodeid : (SLASH node_identifier)+;\r
+\r
+prefix : identifier;\r
+\r
+identifier: IDENTIFIER | CURRENT_KEYWORD;\r
+\r
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContext.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContext.java
new file mode 100644 (file)
index 0000000..4762290
--- /dev/null
@@ -0,0 +1,134 @@
+/**
+ * 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.impl.leafref;
+
+import com.google.common.collect.ImmutableMap;
+import java.io.IOException;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+final public class LeafRefContext {
+
+    private final QName currentNodeQName;
+    private final SchemaPath currentNodePath;
+    private final SchemaContext schemaContext;
+    private final Module module;
+
+    private final LeafRefPath leafRefTargetPath;
+    private final LeafRefPath absoluteLeafRefTargetPath ;
+    private final String leafRefTargetPathString;
+
+    private final boolean isReferencedBy;
+    private final boolean isReferencing;
+
+    private final Map<QName, LeafRefContext> referencingChilds;
+    private final Map<QName, LeafRefContext> referencedByChilds;
+    private final Map<QName, LeafRefContext> referencedByLeafRefCtx;
+
+    LeafRefContext(final LeafRefContextBuilder leafRefContextBuilder) {
+        this.currentNodeQName = leafRefContextBuilder.getCurrentNodeQName();
+        this.currentNodePath = leafRefContextBuilder.getCurrentNodePath();
+        this.schemaContext = leafRefContextBuilder.getSchemaContext();
+        this.leafRefTargetPath = leafRefContextBuilder.getLeafRefTargetPath();
+        this.absoluteLeafRefTargetPath = leafRefContextBuilder
+                .getAbsoluteLeafRefTargetPath();
+        this.leafRefTargetPathString = leafRefContextBuilder
+                .getLeafRefTargetPathString();
+        this.isReferencedBy = leafRefContextBuilder.isReferencedBy();
+        this.isReferencing = leafRefContextBuilder.isReferencing();
+        this.referencingChilds = ImmutableMap.copyOf(leafRefContextBuilder.getReferencingChilds());
+        this.referencedByChilds = ImmutableMap.copyOf(leafRefContextBuilder.getReferencedByChilds());
+        this.referencedByLeafRefCtx = ImmutableMap.copyOf(leafRefContextBuilder
+                .getAllReferencedByLeafRefCtxs());
+        this.module = leafRefContextBuilder.getLeafRefContextModule();
+    }
+
+    public static final LeafRefContext create(final SchemaContext ctx) {
+        try {
+            return new LeafRefContextTreeBuilder(ctx).buildLeafRefContextTree();
+        } catch (IOException | LeafRefYangSyntaxErrorException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public boolean hasLeafRefContextChild() {
+        return hasReferencedChild() || hasReferencingChild();
+    }
+
+    public boolean hasReferencedChild() {
+        return !referencedByChilds.isEmpty();
+    }
+
+    public boolean hasReferencingChild() {
+        return !referencingChilds.isEmpty();
+    }
+
+    public boolean isReferenced() {
+        return isReferencedBy;
+    }
+
+    public boolean isReferencing() {
+        return isReferencing;
+    }
+
+    public LeafRefContext getReferencingChildByName(final QName name) {
+        return referencingChilds.get(name);
+    }
+
+    public Map<QName, LeafRefContext> getReferencingChilds() {
+        return referencingChilds;
+    }
+
+    public LeafRefContext getReferencedChildByName(final QName name) {
+        return referencedByChilds.get(name);
+    }
+
+    public Map<QName, LeafRefContext> getReferencedByChilds() {
+        return referencedByChilds;
+    }
+
+    public SchemaPath getCurrentNodePath() {
+        return currentNodePath;
+    }
+
+    public LeafRefPath getLeafRefTargetPath() {
+        return leafRefTargetPath;
+    }
+
+    public String getLeafRefTargetPathString() {
+        return leafRefTargetPathString;
+    }
+
+    public QName getNodeName() {
+        return currentNodeQName;
+    }
+
+    SchemaContext getSchemaContext() {
+        return schemaContext;
+    }
+
+    public LeafRefPath getAbsoluteLeafRefTargetPath() {
+        return absoluteLeafRefTargetPath;
+    }
+
+    public Module getLeafRefContextModule() {
+        return module;
+    }
+
+    public LeafRefContext getReferencedByLeafRefCtxByName(final QName qname) {
+        return referencedByLeafRefCtx.get(qname);
+    }
+
+    public Map<QName, LeafRefContext> getAllReferencedByLeafRefCtxs() {
+        return referencedByLeafRefCtx;
+    }
+
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextBuilder.java
new file mode 100644 (file)
index 0000000..4349bd5
--- /dev/null
@@ -0,0 +1,178 @@
+/**
+ * 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.impl.leafref;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+class LeafRefContextBuilder {
+
+    private QName currentNodeQName;
+    private SchemaPath currentNodePath;
+    private SchemaContext schemaContext;
+
+    private LeafRefPath leafRefTargetPath = null;
+    private LeafRefPath absoluteLeafRefTargetPath = null;
+    private String leafRefTargetPathString = "";
+
+    private boolean isReferencedBy = false;
+    private boolean isReferencing = false;
+
+    private Map<QName, LeafRefContext> referencingChilds = new HashMap<QName, LeafRefContext>();
+    private Map<QName, LeafRefContext> referencedByChilds = new HashMap<QName, LeafRefContext>();
+    private Map<QName, LeafRefContext> referencedByLeafRefCtx = new HashMap<QName, LeafRefContext>();
+
+    public LeafRefContextBuilder(final QName currentNodeQName,
+            final SchemaPath currentNodePath, final SchemaContext schemaContext) {
+        this.currentNodeQName = currentNodeQName;
+        this.currentNodePath = currentNodePath;
+        this.schemaContext = schemaContext;
+    }
+
+    public LeafRefContext build() {
+        final LeafRefContext leafRefContext = new LeafRefContext(this);
+
+        referencingChilds = new HashMap<QName, LeafRefContext>();
+        referencedByChilds = new HashMap<QName, LeafRefContext>();
+        referencedByLeafRefCtx = new HashMap<QName, LeafRefContext>();
+
+        return leafRefContext;
+    }
+
+    public boolean hasLeafRefContextChild() {
+        return hasReferencedByChild() || hasReferencingChild();
+    }
+
+    public boolean hasReferencedByChild() {
+        return !referencedByChilds.isEmpty();
+    }
+
+    public boolean hasReferencingChild() {
+        return !referencingChilds.isEmpty();
+    }
+
+    public boolean isReferencedBy() {
+        return isReferencedBy;
+    }
+
+    public void setReferencedBy(final boolean isReferencedBy) {
+        this.isReferencedBy = isReferencedBy;
+    }
+
+    public boolean isReferencing() {
+        return isReferencing;
+    }
+
+    public void setReferencing(final boolean isReferencing) {
+        this.isReferencing = isReferencing;
+    }
+
+    public void addReferencingChild(final LeafRefContext child, final QName childQName) {
+        referencingChilds.put(childQName, child);
+    }
+
+    public LeafRefContext getReferencingChildByName(final QName name) {
+        return referencingChilds.get(name);
+    }
+
+    public Map<QName, LeafRefContext> getReferencingChilds() {
+        return referencingChilds;
+    }
+
+    public void addReferencedByChild(final LeafRefContext child, final QName childQName) {
+        referencedByChilds.put(childQName, child);
+    }
+
+    public LeafRefContext getReferencedByChildByName(final QName name) {
+        return referencedByChilds.get(name);
+    }
+
+    public Map<QName, LeafRefContext> getReferencedByChilds() {
+        return referencedByChilds;
+    }
+
+    public SchemaPath getCurrentNodePath() {
+        return currentNodePath;
+    }
+
+    public void setCurrentNodePath(final SchemaPath currentNodePath) {
+        this.currentNodePath = currentNodePath;
+    }
+
+    public LeafRefPath getLeafRefTargetPath() {
+        return leafRefTargetPath;
+    }
+
+    public void setLeafRefTargetPath(final LeafRefPath leafRefPath) {
+        this.leafRefTargetPath = leafRefPath;
+    }
+
+    public String getLeafRefTargetPathString() {
+        return leafRefTargetPathString;
+    }
+
+    public void setLeafRefTargetPathString(final String leafRefPathString) {
+        this.leafRefTargetPathString = leafRefPathString;
+    }
+
+    public QName getCurrentNodeQName() {
+        return currentNodeQName;
+    }
+
+    public void setCurrentNodeQName(final QName currentNodeQName) {
+        this.currentNodeQName = currentNodeQName;
+    }
+
+    public SchemaContext getSchemaContext() {
+        return schemaContext;
+    }
+
+    public void setSchemaContext(final SchemaContext schemaContext) {
+        this.schemaContext = schemaContext;
+    }
+
+    public LeafRefPath getAbsoluteLeafRefTargetPath() {
+
+        if (isReferencing && absoluteLeafRefTargetPath == null) {
+            if (leafRefTargetPath.isAbsolute()) {
+                absoluteLeafRefTargetPath = leafRefTargetPath;
+            } else {
+                absoluteLeafRefTargetPath = LeafRefUtils
+                        .createAbsoluteLeafRefPath(leafRefTargetPath,
+                                currentNodePath, getLeafRefContextModule());
+            }
+        }
+
+        return absoluteLeafRefTargetPath;
+    }
+
+    public Module getLeafRefContextModule() {
+        final QNameModule qnameModule = currentNodeQName.getModule();
+
+        return schemaContext.findModuleByNamespaceAndRevision(
+                qnameModule.getNamespace(), qnameModule.getRevision());
+    }
+
+    public void addReferencedByLeafRefCtx(final QName qname, final LeafRefContext leafRef) {
+        referencedByLeafRefCtx.put(qname, leafRef);
+    }
+
+    public LeafRefContext getReferencedByLeafRefCtxByName(final QName qname) {
+        return referencedByLeafRefCtx.get(qname);
+    }
+
+    public Map<QName, LeafRefContext> getAllReferencedByLeafRefCtxs() {
+        return referencedByLeafRefCtx;
+    }
+
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextTreeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextTreeBuilder.java
new file mode 100644 (file)
index 0000000..38dfb75
--- /dev/null
@@ -0,0 +1,257 @@
+/**
+ * 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.impl.leafref;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.Leafref;
+
+class LeafRefContextTreeBuilder {
+    private final SchemaContext schemaContext;
+    private final LinkedList<LeafRefContext> leafRefs;
+
+    public LeafRefContextTreeBuilder(final SchemaContext schemaContext) {
+        this.schemaContext = schemaContext;
+        this.leafRefs = new LinkedList<LeafRefContext>();
+    }
+
+    public LeafRefContext buildLeafRefContextTree() throws IOException,
+            LeafRefYangSyntaxErrorException {
+        final LeafRefContextBuilder rootBuilder = new LeafRefContextBuilder(
+                schemaContext.getQName(), schemaContext.getPath(),
+                schemaContext);
+
+        final Set<Module> modules = schemaContext.getModules();
+        for (final Module module : modules) {
+            final Collection<DataSchemaNode> childNodes = module.getChildNodes();
+            for (final DataSchemaNode childNode : childNodes) {
+                final LeafRefContext childLeafRefContext = buildLeafRefContextReferencingTree(
+                        childNode, module);
+
+                if (childLeafRefContext.hasReferencingChild()
+                        || childLeafRefContext.isReferencing()) {
+                    rootBuilder.addReferencingChild(childLeafRefContext,
+                            childLeafRefContext.getNodeName());
+                }
+            }
+        }
+
+        for (final Module module : modules) {
+            final Collection<DataSchemaNode> childNodes = module.getChildNodes();
+            for (final DataSchemaNode childNode : childNodes) {
+                final LeafRefContext childLeafRefContext = buildLeafRefContextReferencedByTree(
+                        childNode, module);
+
+                if (childLeafRefContext.hasReferencedChild()
+                        || childLeafRefContext.isReferenced()) {
+                    rootBuilder.addReferencedByChild(childLeafRefContext,
+                            childLeafRefContext.getNodeName());
+                }
+            }
+        }
+
+        // FIXME: it might be useful to merge these subtrees (i.e. referencing
+        // and referencedBy subtree)
+
+        return rootBuilder.build();
+    }
+
+    private LeafRefContext buildLeafRefContextReferencingTree(
+            final DataSchemaNode node, final Module currentModule) throws IOException,
+            LeafRefYangSyntaxErrorException {
+
+        final LeafRefContextBuilder currentLeafRefContextBuilder = new LeafRefContextBuilder(
+                node.getQName(), node.getPath(), schemaContext);
+
+        if (node instanceof DataNodeContainer) {
+            final DataNodeContainer dataNodeContainer = (DataNodeContainer) node;
+            final Collection<DataSchemaNode> childNodes = dataNodeContainer
+                    .getChildNodes();
+
+            for (final DataSchemaNode childNode : childNodes) {
+                final LeafRefContext childLeafRefContext = buildLeafRefContextReferencingTree(
+                        childNode, currentModule);
+
+                if (childLeafRefContext.hasReferencingChild()
+                        || childLeafRefContext.isReferencing()) {
+                    currentLeafRefContextBuilder.addReferencingChild(
+                            childLeafRefContext,
+                            childLeafRefContext.getNodeName());
+                }
+            }
+        } else if (node instanceof ChoiceSchemaNode) {
+
+            final ChoiceSchemaNode choice = (ChoiceSchemaNode) node;
+            final Set<ChoiceCaseNode> cases = choice.getCases();
+            // :FIXME choice without case
+
+            for (final ChoiceCaseNode caseNode : cases) {
+                final LeafRefContext childLeafRefContext = buildLeafRefContextReferencingTree(
+                        caseNode, currentModule);
+
+                if (childLeafRefContext.hasReferencingChild()
+                        || childLeafRefContext.isReferencing()) {
+                    currentLeafRefContextBuilder.addReferencingChild(
+                            childLeafRefContext,
+                            childLeafRefContext.getNodeName());
+                }
+            }
+
+        } else if (node instanceof LeafSchemaNode
+                || node instanceof LeafListSchemaNode) {
+
+            TypeDefinition<?> type = null;
+
+            if (node instanceof LeafSchemaNode) {
+                type = ((LeafSchemaNode) node).getType();
+            } else {
+                type = ((LeafListSchemaNode) node).getType();
+            }
+
+            // FIXME: fix case when type is e.g. typdef -> typedef -> leafref
+            if (type instanceof Leafref) {
+                final Leafref leafrefType = (Leafref) type;
+                final String leafRefPathString = leafrefType.getPathStatement()
+                        .toString();
+
+                currentLeafRefContextBuilder
+                        .setLeafRefTargetPathString(leafRefPathString);
+                currentLeafRefContextBuilder.setReferencing(true);
+
+                final LeafRefPathParserImpl leafRefPathParser = new LeafRefPathParserImpl(
+                        schemaContext, currentModule, node);
+
+                final ByteArrayInputStream leafRefPathInputStream = new ByteArrayInputStream(
+                        leafRefPathString.getBytes(Charset.forName("UTF-8")));
+                final LeafRefPath leafRefPath = leafRefPathParser
+                        .parseLeafRefPathSourceToSchemaPath(leafRefPathInputStream);
+
+                currentLeafRefContextBuilder.setLeafRefTargetPath(leafRefPath);
+
+                final LeafRefContext currentLeafRefContext = currentLeafRefContextBuilder
+                        .build();
+                leafRefs.add(currentLeafRefContext);
+                return currentLeafRefContext;
+            }
+        }
+
+        return currentLeafRefContextBuilder.build();
+    }
+
+    private LeafRefContext buildLeafRefContextReferencedByTree(
+            final DataSchemaNode node, final Module currentModule) throws IOException,
+            LeafRefYangSyntaxErrorException {
+
+        final LeafRefContextBuilder currentLeafRefContextBuilder = new LeafRefContextBuilder(
+                node.getQName(), node.getPath(), schemaContext);
+
+        if (node instanceof DataNodeContainer) {
+            final DataNodeContainer dataNodeContainer = (DataNodeContainer) node;
+            final Collection<DataSchemaNode> childNodes = dataNodeContainer
+                    .getChildNodes();
+
+            for (final DataSchemaNode childNode : childNodes) {
+                final LeafRefContext childLeafRefContext = buildLeafRefContextReferencedByTree(
+                        childNode, currentModule);
+
+                if (childLeafRefContext.hasReferencedChild()
+                        || childLeafRefContext.isReferenced()) {
+                    currentLeafRefContextBuilder.addReferencedByChild(
+                            childLeafRefContext,
+                            childLeafRefContext.getNodeName());
+                }
+            }
+        } else if (node instanceof ChoiceSchemaNode) {
+
+            final ChoiceSchemaNode choice = (ChoiceSchemaNode) node;
+            final Set<ChoiceCaseNode> cases = choice.getCases();
+
+            for (final ChoiceCaseNode caseNode : cases) {
+                final LeafRefContext childLeafRefContext = buildLeafRefContextReferencedByTree(
+                        caseNode, currentModule);
+
+                if (childLeafRefContext.hasReferencedChild()
+                        || childLeafRefContext.isReferenced()) {
+                    currentLeafRefContextBuilder.addReferencedByChild(
+                            childLeafRefContext,
+                            childLeafRefContext.getNodeName());
+                }
+            }
+
+        } else if (node instanceof LeafSchemaNode
+                || node instanceof LeafListSchemaNode) {
+
+            final LinkedList<LeafRefContext> foundLeafRefs = getLeafRefsFor(node,
+                    currentModule);
+            if (!foundLeafRefs.isEmpty()) {
+                currentLeafRefContextBuilder.setReferencedBy(true);
+                for (final LeafRefContext leafRef : foundLeafRefs) {
+                    currentLeafRefContextBuilder.addReferencedByLeafRefCtx(
+                            leafRef.getNodeName(), leafRef);
+                }
+            }
+        }
+
+        return currentLeafRefContextBuilder.build();
+    }
+
+    private LinkedList<LeafRefContext> getLeafRefsFor(final DataSchemaNode node,
+            final Module module) {
+        final LeafRefPath nodeXPath = LeafRefUtils.schemaPathToLeafRefPath(
+                node.getPath(), module);
+
+        final LinkedList<LeafRefContext> foundLeafRefs = new LinkedList<LeafRefContext>();
+
+        for (final LeafRefContext leafref : leafRefs) {
+            final LeafRefPath leafRefTargetPath = leafref
+                    .getAbsoluteLeafRefTargetPath();
+            if (leafRefTargetPath.equals(nodeXPath)) {
+                foundLeafRefs.add(leafref);
+            }
+        }
+
+        return foundLeafRefs;
+    }
+
+    // private LeafRefContext buildLeafRefContextTreeFor(LeafRefContext parent,
+    // Module module) {
+    //
+    // Collection<DataSchemaNode> childNodes = module.getChildNodes();
+    // for (DataSchemaNode childNode : childNodes) {
+    // LeafRefContext childLeafRefContext = buildLeafRefContextTreeFor(parent,
+    // childNode);
+    //
+    // if(childLeafRefContext.hasReferencedByChild() ||
+    // childLeafRefContext.isReferencedBy()) {
+    // parent.addReferencedByChild(childLeafRefContext,
+    // childLeafRefContext.getCurrentNodeQName());
+    // }
+    // if(childLeafRefContext.hasReferencingChild() ||
+    // childLeafRefContext.isReferencing()) {
+    // parent.addReferencingChild(childLeafRefContext,
+    // childLeafRefContext.getCurrentNodeQName());
+    // }
+    // }
+    //
+    // return node;
+    // }
+
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextUtils.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextUtils.java
new file mode 100644 (file)
index 0000000..6206df8
--- /dev/null
@@ -0,0 +1,250 @@
+/**
+ * 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.impl.leafref;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public final class LeafRefContextUtils {
+
+    private LeafRefContextUtils() {
+        throw new UnsupportedOperationException();
+    }
+
+    public static LeafRefContext getLeafRefReferencingContext(final SchemaNode node,
+            final LeafRefContext root) {
+        final SchemaPath schemaPath = node.getPath();
+        return getLeafRefReferencingContext(schemaPath, root);
+    }
+
+    public static LeafRefContext getLeafRefReferencingContext(
+            final SchemaPath schemaPath, final LeafRefContext root) {
+        final Iterable<QName> pathFromRoot = schemaPath.getPathFromRoot();
+        return getLeafRefReferencingContext(pathFromRoot, root);
+    }
+
+    public static LeafRefContext getLeafRefReferencingContext(
+            final Iterable<QName> pathFromRoot, LeafRefContext root) {
+
+        LeafRefContext leafRefCtx = null;
+        final Iterator<QName> iterator = pathFromRoot.iterator();
+        while (iterator.hasNext() && root != null) {
+            final QName qname = iterator.next();
+            leafRefCtx = root.getReferencingChildByName(qname);
+            if (iterator.hasNext()) {
+                root = leafRefCtx;
+            }
+        }
+
+        return leafRefCtx;
+    }
+
+    public static LeafRefContext getLeafRefReferencedByContext(final SchemaNode node,
+            final LeafRefContext root) {
+        final SchemaPath schemaPath = node.getPath();
+        return getLeafRefReferencedByContext(schemaPath, root);
+    }
+
+    public static LeafRefContext getLeafRefReferencedByContext(
+            final SchemaPath schemaPath, final LeafRefContext root) {
+        final Iterable<QName> pathFromRoot = schemaPath.getPathFromRoot();
+        return getLeafRefReferencedByContext(pathFromRoot, root);
+    }
+
+    public static LeafRefContext getLeafRefReferencedByContext(
+            final Iterable<QName> pathFromRoot, LeafRefContext root) {
+
+        LeafRefContext leafRefCtx = null;
+        final Iterator<QName> iterator = pathFromRoot.iterator();
+        while (iterator.hasNext() && root != null) {
+            final QName qname = iterator.next();
+            leafRefCtx = root.getReferencedChildByName(qname);
+            if (iterator.hasNext()) {
+                root = leafRefCtx;
+            }
+        }
+
+        return leafRefCtx;
+    }
+
+    public static boolean isLeafRef(final SchemaNode node, final LeafRefContext root) {
+
+        if ((node == null) || (root == null))
+            return false;
+
+        final LeafRefContext leafRefReferencingContext = getLeafRefReferencingContext(
+                node, root);
+        if (leafRefReferencingContext == null)
+            return false;
+
+        return leafRefReferencingContext.isReferencing();
+    }
+
+    public static boolean hasLeafRefChild(final SchemaNode node, final LeafRefContext root) {
+
+        if ((node == null) || (root == null))
+            return false;
+
+        final LeafRefContext leafRefReferencingContext = getLeafRefReferencingContext(
+                node, root);
+        if (leafRefReferencingContext == null)
+            return false;
+
+        return leafRefReferencingContext.hasReferencingChild();
+    }
+
+    public static boolean isReferencedByLeafRef(final SchemaNode node,
+            final LeafRefContext root) {
+
+        if ((node == null) || (root == null))
+            return false;
+
+        final LeafRefContext leafRefReferencedByContext = getLeafRefReferencedByContext(
+                node, root);
+        if (leafRefReferencedByContext == null)
+            return false;
+
+        return leafRefReferencedByContext.isReferenced();
+    }
+
+    public static boolean hasChildReferencedByLeafRef(final SchemaNode node,
+            final LeafRefContext root) {
+
+        if ((node == null) || (root == null))
+            return false;
+
+        final LeafRefContext leafRefReferencedByContext = getLeafRefReferencedByContext(
+                node, root);
+        if (leafRefReferencedByContext == null)
+            return false;
+
+        return leafRefReferencedByContext.hasReferencedChild();
+    }
+
+    public static List<LeafRefContext> findAllLeafRefChilds(final SchemaNode node,
+            final LeafRefContext root) {
+
+        return findAllLeafRefChilds(node.getPath(), root);
+    }
+
+    public static List<LeafRefContext> findAllLeafRefChilds(
+            final SchemaPath schemaPath, final LeafRefContext root) {
+
+        return findAllLeafRefChilds(schemaPath.getPathFromRoot(), root);
+    }
+
+    public static List<LeafRefContext> findAllLeafRefChilds(
+            final Iterable<QName> pathFromRoot, final LeafRefContext root) {
+
+        final LeafRefContext leafRefReferencingContext = getLeafRefReferencingContext(
+                pathFromRoot, root);
+        final List<LeafRefContext> allLeafRefsChilds = findAllLeafRefChilds(leafRefReferencingContext);
+
+        return allLeafRefsChilds;
+    }
+
+    public static List<LeafRefContext> findAllLeafRefChilds(
+            final LeafRefContext parent) {
+
+        final LinkedList<LeafRefContext> leafRefChilds = new LinkedList<LeafRefContext>();
+
+        if (parent == null) {
+            return leafRefChilds;
+        }
+
+        if (parent.isReferencing()) {
+            leafRefChilds.add(parent);
+            return leafRefChilds;
+        } else {
+            final Set<Entry<QName, LeafRefContext>> childs = parent
+                    .getReferencingChilds().entrySet();
+            for (final Entry<QName, LeafRefContext> child : childs) {
+                leafRefChilds.addAll(findAllLeafRefChilds(child.getValue()));
+            }
+        }
+        return leafRefChilds;
+    }
+
+    public static List<LeafRefContext> findAllChildsReferencedByLeafRef(
+            final SchemaNode node, final LeafRefContext root) {
+
+        return findAllChildsReferencedByLeafRef(node.getPath(), root);
+    }
+
+    public static List<LeafRefContext> findAllChildsReferencedByLeafRef(
+            final SchemaPath schemaPath, final LeafRefContext root) {
+
+        return findAllChildsReferencedByLeafRef(schemaPath.getPathFromRoot(),
+                root);
+    }
+
+    public static List<LeafRefContext> findAllChildsReferencedByLeafRef(
+            final Iterable<QName> pathFromRoot, final LeafRefContext root) {
+
+        final LeafRefContext leafRefReferencedByContext = getLeafRefReferencedByContext(
+                pathFromRoot, root);
+        final List<LeafRefContext> allChildsReferencedByLeafRef = findAllChildsReferencedByLeafRef(leafRefReferencedByContext);
+
+        return allChildsReferencedByLeafRef;
+    }
+
+    public static List<LeafRefContext> findAllChildsReferencedByLeafRef(
+            final LeafRefContext parent) {
+
+        final LinkedList<LeafRefContext> childsReferencedByLeafRef = new LinkedList<LeafRefContext>();
+
+        if (parent == null) {
+            return childsReferencedByLeafRef;
+        }
+
+        if (parent.isReferenced()) {
+            childsReferencedByLeafRef.add(parent);
+            return childsReferencedByLeafRef;
+        } else {
+            final Set<Entry<QName, LeafRefContext>> childs = parent
+                    .getReferencedByChilds().entrySet();
+            for (final Entry<QName, LeafRefContext> child : childs) {
+                childsReferencedByLeafRef
+                        .addAll(findAllChildsReferencedByLeafRef(child
+                                .getValue()));
+            }
+        }
+        return childsReferencedByLeafRef;
+    }
+
+    public static Map<QName, LeafRefContext> getAllLeafRefsReferencingThisNode(
+            final SchemaNode node, final LeafRefContext root) {
+        return getAllLeafRefsReferencingThisNode(node.getPath(), root);
+    }
+
+    public static Map<QName, LeafRefContext> getAllLeafRefsReferencingThisNode(
+            final SchemaPath path, final LeafRefContext root) {
+        return getAllLeafRefsReferencingThisNode(path.getPathFromRoot(), root);
+    }
+
+    public static Map<QName, LeafRefContext> getAllLeafRefsReferencingThisNode(
+            final Iterable<QName> pathFromRoot, final LeafRefContext root) {
+
+        final LeafRefContext leafRefReferencedByContext = getLeafRefReferencedByContext(
+                pathFromRoot, root);
+
+        if (leafRefReferencedByContext == null)
+            return new HashMap<QName, LeafRefContext>();
+
+        return leafRefReferencedByContext.getAllReferencedByLeafRefCtxs();
+    }
+
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefDataValidationFailedException.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefDataValidationFailedException.java
new file mode 100644 (file)
index 0000000..3ddb01e
--- /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.data.impl.leafref;
+
+public class LeafRefDataValidationFailedException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+    private int errorsCount = 1;
+
+    public LeafRefDataValidationFailedException(String message) {
+        super(message);
+    }
+
+    public LeafRefDataValidationFailedException(String message, int errorsCount) {
+        super(message);
+        this.errorsCount = errorsCount;
+    }
+
+    public LeafRefDataValidationFailedException(String message,
+            final Throwable cause) {
+        super(message, cause);
+    }
+
+    public int getValidationsErrorsCount() {
+        return errorsCount;
+    }
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPath.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPath.java
new file mode 100644 (file)
index 0000000..649d911
--- /dev/null
@@ -0,0 +1,374 @@
+/**
+ * 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.impl.leafref;
+
+import org.opendaylight.yangtools.concepts.Immutable;
+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;
+
+public abstract class LeafRefPath implements Immutable {
+
+    /**
+     * An absolute LeafRefPath.
+     */
+    private static final class AbsoluteLeafRefPath extends LeafRefPath {
+        private AbsoluteLeafRefPath(final LeafRefPath parent,
+                final QNameWithPredicate qname) {
+            super(parent, qname);
+        }
+
+        @Override
+        public boolean isAbsolute() {
+            return true;
+        }
+
+        @Override
+        protected LeafRefPath createInstance(final LeafRefPath parent,
+                final QNameWithPredicate qname) {
+            return new AbsoluteLeafRefPath(parent, qname);
+        }
+    }
+
+    /**
+     * A relative LeafRefPath.
+     */
+    private static final class RelativeLeafRefPath extends LeafRefPath {
+        private RelativeLeafRefPath(final LeafRefPath parent,
+                final QNameWithPredicate qname) {
+            super(parent, qname);
+        }
+
+        @Override
+        public boolean isAbsolute() {
+            return false;
+        }
+
+        @Override
+        protected LeafRefPath createInstance(final LeafRefPath parent,
+                final QNameWithPredicate qname) {
+            return new RelativeLeafRefPath(parent, qname);
+        }
+    }
+
+    @SuppressWarnings("rawtypes")
+    private static final AtomicReferenceFieldUpdater<LeafRefPath, ImmutableList> LEGACYPATH_UPDATER = AtomicReferenceFieldUpdater
+            .newUpdater(LeafRefPath.class, ImmutableList.class, "legacyPath");
+
+    /**
+     * Shared instance of the conceptual root schema node.
+     */
+    public static final LeafRefPath ROOT = new AbsoluteLeafRefPath(null, null);
+
+    /**
+     * Shared instance of the "same" relative schema node.
+     */
+    public static final LeafRefPath SAME = new RelativeLeafRefPath(null, null);
+
+    /**
+     * Parent path.
+     */
+    private final LeafRefPath parent;
+
+    /**
+     * This component.
+     */
+    private final QNameWithPredicate 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<QNameWithPredicate> legacyPath;
+
+    private ImmutableList<QNameWithPredicate> getLegacyPath() {
+        ImmutableList<QNameWithPredicate> 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>QNameWithPredicate</code> instances which
+     *         represents complete path to schema node
+     *
+     * @deprecated Use {@link #getPathFromRoot()} instead.
+     */
+    @Deprecated
+    public List<QNameWithPredicate> getPath() {
+        return getLegacyPath();
+    }
+
+    protected LeafRefPath(final LeafRefPath parent,
+            final QNameWithPredicate 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 QNameWithPredicate instances which specifies exact
+     *            path to the module node
+     * @param absolute
+     *            boolean value which specifies if the path is absolute or
+     *            relative
+     *
+     * @return A LeafRefPath instance.
+     */
+    public static LeafRefPath create(final Iterable<QNameWithPredicate> path,
+            final boolean absolute) {
+        final LeafRefPath 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 QNameWithPredicate instances which specifies exact
+     *            path to the module node
+     *
+     * @return A LeafRefPath instance.
+     */
+    public static LeafRefPath create(final boolean absolute,
+            final QNameWithPredicate... path) {
+        return create(Arrays.asList(path), absolute);
+    }
+
+    /**
+     * Create a new instance.
+     *
+     * @param parent
+     *            Parent LeafRefPath
+     * @param qname
+     *            next path element
+     * @return A new LeafRefPath instance
+     */
+    protected abstract LeafRefPath createInstance(LeafRefPath parent,
+            QNameWithPredicate 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 LeafRefPath createChild(final Iterable<QNameWithPredicate> relative) {
+        if (Iterables.isEmpty(relative)) {
+            return this;
+        }
+
+        LeafRefPath parent = this;
+        for (QNameWithPredicate 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 LeafRefPath
+     * @return A new child path
+     */
+    public LeafRefPath createChild(final LeafRefPath relative) {
+        Preconditions.checkArgument(!relative.isAbsolute(),
+                "Child creation requires relative path");
+
+        LeafRefPath parent = this;
+        for (QNameWithPredicate 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 LeafRefPath elements
+     * @return A new child path
+     */
+    public LeafRefPath createChild(final QNameWithPredicate... 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 LeafRefPaths) 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<QNameWithPredicate> 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 LeafRefPaths).
+     *
+     * @return list of <code>qname</code> instances which represents path from
+     *         the schema node towards the root.
+     */
+    public Iterable<QNameWithPredicate> getPathTowardsRoot() {
+        return new Iterable<QNameWithPredicate>() {
+            @Override
+            public Iterator<QNameWithPredicate> iterator() {
+                return new Iterator<QNameWithPredicate>() {
+                    private LeafRefPath current = LeafRefPath.this;
+
+                    @Override
+                    public boolean hasNext() {
+                        return current.parent != null;
+                    }
+
+                    @Override
+                    public QNameWithPredicate next() {
+                        if (current.parent != null) {
+                            final QNameWithPredicate 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 LeafRefPath.
+     *
+     * @return Parent path, null if this LeafRefPath is already toplevel.
+     */
+    public LeafRefPath getParent() {
+        return parent;
+    }
+
+    /**
+     * Get the last component of this path.
+     *
+     * @return The last component of this path.
+     */
+    public final QNameWithPredicate getLastComponent() {
+        return qname;
+    }
+
+    /**
+     * Describes whether schema path 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 LeafRefPath other = (LeafRefPath) 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 String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        Iterable<QNameWithPredicate> pathFromRoot = this.getPathFromRoot();
+
+        sb.append(isAbsolute() ? "Absolute path:" : "Relative path:");
+
+        for (QNameWithPredicate qName : pathFromRoot) {
+            sb.append("/" + qName);
+        }
+
+        return sb.toString();
+
+    }
+
+    // @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-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathErrorListener.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathErrorListener.java
new file mode 100644 (file)
index 0000000..c8098e2
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * 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.impl.leafref;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.antlr.v4.runtime.BaseErrorListener;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.Recognizer;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class LeafRefPathErrorListener extends BaseErrorListener {
+    private static final Logger LOG = LoggerFactory
+            .getLogger(LeafRefPathErrorListener.class);
+    private final List<LeafRefPathSyntaxErrorException> exceptions = new ArrayList<>();
+    private final Module module;
+
+    public LeafRefPathErrorListener(final Module module) {
+        this.module = module;
+    }
+
+    @Override
+    public void syntaxError(final Recognizer<?, ?> recognizer,
+            final Object offendingSymbol, final int line,
+            final int charPositionInLine, final String msg,
+            final RecognitionException e) {
+        LOG.debug("Syntax error in module {} at {}:{}: {}", module.getName(), line, charPositionInLine, msg, e);
+
+        exceptions.add(new LeafRefPathSyntaxErrorException(module.getName(), line,
+                charPositionInLine, msg, e));
+    }
+
+    public void validate() throws LeafRefPathSyntaxErrorException {
+        if (exceptions.isEmpty()) {
+            return;
+        }
+
+        // Single exception: just throw it
+        if (exceptions.size() == 1) {
+            throw exceptions.get(0);
+        }
+
+        final StringBuilder sb = new StringBuilder();
+        String module = null;
+        boolean first = true;
+        for (final LeafRefPathSyntaxErrorException e : exceptions) {
+            if (module == null) {
+                module = e.getModule();
+            }
+            if (first) {
+                first = false;
+            } else {
+                sb.append('\n');
+            }
+
+            sb.append(e.getFormattedMessage());
+        }
+
+        throw new LeafRefPathSyntaxErrorException(module, 0, 0, sb.toString());
+    }
+
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParseException.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParseException.java
new file mode 100644 (file)
index 0000000..55f6030
--- /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.data.impl.leafref;
+
+class LeafRefPathParseException extends RuntimeException {
+
+    private static final long serialVersionUID = 7819033841757805240L;
+
+    public LeafRefPathParseException(final String errorMsg) {
+        super(errorMsg);
+
+    }
+
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserImpl.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserImpl.java
new file mode 100644 (file)
index 0000000..e7d03c1
--- /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.data.impl.leafref;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.tree.ParseTreeWalker;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Path_argContext;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+
+final class LeafRefPathParserImpl {
+    private final SchemaContext schemaContext;
+    private final Module module;
+    private final SchemaNode node;
+
+     public LeafRefPathParserImpl(final SchemaContext schemaContext, final Module currentModule, final SchemaNode currentNode) {
+        this.schemaContext = schemaContext;
+        this.module = currentModule;
+        this.node = currentNode;
+    }
+
+    public LeafRefPath parseLeafRefPathSourceToSchemaPath(final InputStream stream) throws IOException, LeafRefYangSyntaxErrorException {
+
+        final Path_argContext pathCtx = parseLeafRefPathSource(stream);
+
+        final ParseTreeWalker walker = new ParseTreeWalker();
+        final LeafRefPathParserListenerImpl leafRefPathParserListenerImpl = new LeafRefPathParserListenerImpl(schemaContext, module, node);
+        walker.walk(leafRefPathParserListenerImpl,pathCtx);
+
+        final LeafRefPath leafRefPath = leafRefPathParserListenerImpl.getLeafRefPath();
+
+        return leafRefPath;
+    }
+
+
+    private Path_argContext parseLeafRefPathSource(final InputStream stream) throws IOException, LeafRefYangSyntaxErrorException {
+        final LeafRefPathLexer lexer = new LeafRefPathLexer(new ANTLRInputStream(stream));
+        final CommonTokenStream tokens = new CommonTokenStream(lexer);
+        final LeafRefPathParser parser = new LeafRefPathParser(tokens);
+        parser.removeErrorListeners();
+
+        final LeafRefPathErrorListener errorListener = new LeafRefPathErrorListener(module);
+        parser.addErrorListener(errorListener);
+
+        final Path_argContext result = parser.path_arg();
+        errorListener.validate();
+
+        return result;
+    }
+
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserListenerImpl.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserListenerImpl.java
new file mode 100644 (file)
index 0000000..4589fb4
--- /dev/null
@@ -0,0 +1,215 @@
+/**
+ * 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.impl.leafref;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+import java.net.URI;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.IdentifierContext;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Node_identifierContext;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Path_argContext;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Path_equality_exprContext;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Path_predicateContext;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.PrefixContext;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Rel_path_keyexprContext;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Relative_pathContext;
+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.api.SchemaNode;
+
+
+
+final class LeafRefPathParserListenerImpl extends LeafRefPathParserBaseListener{
+
+    private final SchemaContext schemaContext;
+    private final Module module;
+    private LeafRefPath leafRefPath;
+    private boolean relativePath=false;
+    private QNameWithPredicateBuilder currentLeafRefPathQName;
+    private QNamePredicateBuilder currentPredicate;
+    private QNameModule currentQnameModule;
+    private String currentQNameLocalName;
+    private final LinkedList<QNameWithPredicateBuilder> leafRefPathQnameList;
+    private LinkedList<QNameWithPredicateBuilder> predicatePathKeyQnameList;
+    private final SchemaNode node; //FIXME use for identifier path completion
+    private ParsingState currentParsingState;
+
+    Function<QNameWithPredicateBuilder, QNameWithPredicate> build = new Function<QNameWithPredicateBuilder, QNameWithPredicate>() {
+        @Override
+        public QNameWithPredicate apply(final QNameWithPredicateBuilder builder) {
+           return builder.build();
+        }
+     };
+
+    private enum ParsingState {
+        LEAF_REF_PATH, PATH_PREDICATE, PREDICATE_PATH_EQUALITY_EXPR, PATH_KEY_EXPR
+    }
+
+    public LeafRefPathParserListenerImpl(final SchemaContext schemaContext, final Module currentModule, final SchemaNode currentNode) {
+       this.schemaContext = schemaContext;
+       this.module = currentModule;
+       this.leafRefPathQnameList = new LinkedList<QNameWithPredicateBuilder>();
+       this.node=currentNode;
+       this.currentParsingState = ParsingState.LEAF_REF_PATH;
+    }
+
+    @Override
+    public void enterPath_predicate(final Path_predicateContext ctx) {
+        currentParsingState=ParsingState.PATH_PREDICATE;
+        currentPredicate = new QNamePredicateBuilder();
+    }
+
+
+    @Override
+    public void exitPath_predicate(final Path_predicateContext ctx) {
+        currentLeafRefPathQName.addQNamePredicate(currentPredicate.build());
+        currentPredicate = null;
+        currentParsingState=ParsingState.LEAF_REF_PATH;
+    }
+
+
+    @Override
+    public void enterRel_path_keyexpr(final Rel_path_keyexprContext ctx) {
+        currentParsingState=ParsingState.PATH_KEY_EXPR;
+        predicatePathKeyQnameList = new LinkedList<QNameWithPredicateBuilder>();
+        final List<TerminalNode> dots = ctx.DOTS();
+        for (final TerminalNode parent : dots) {
+            predicatePathKeyQnameList.add(QNameWithPredicateBuilder.UP_PARENT_BUILDER);
+        }
+    }
+
+
+    @Override
+    public void exitRel_path_keyexpr(final Rel_path_keyexprContext ctx) {
+
+        final LeafRefPath pathKeyExpression = LeafRefPath.create(Lists.transform(predicatePathKeyQnameList,build), false);
+        currentPredicate.setPathKeyExpression(pathKeyExpression);
+
+        currentParsingState=ParsingState.PREDICATE_PATH_EQUALITY_EXPR;
+    }
+
+    @Override
+    public void enterRelative_path(final Relative_pathContext ctx) {
+
+        relativePath = true;
+        final List<TerminalNode> dots = ctx.DOTS();
+        for (final TerminalNode parent : dots) {
+            leafRefPathQnameList.add(QNameWithPredicateBuilder.UP_PARENT_BUILDER);
+        }
+
+    }
+
+    @Override
+    public void enterPath_equality_expr(final Path_equality_exprContext ctx) {
+        currentParsingState=ParsingState.PREDICATE_PATH_EQUALITY_EXPR;
+    }
+
+
+    @Override
+    public void exitPath_equality_expr(final Path_equality_exprContext ctx) {
+
+        currentParsingState=ParsingState.PATH_PREDICATE;
+    }
+
+    @Override
+    public void enterPrefix(final PrefixContext ctx) {
+
+        if (module.getPrefix().equals(ctx.getText())) {
+            currentQnameModule = module.getQNameModule();
+        } else {
+            currentQnameModule = getQNameModuleForImportPrefix(ctx.getText());
+        }
+    }
+
+    @Override
+    public void exitPath_arg(final Path_argContext ctx) {
+        leafRefPath = LeafRefPath.create(Lists.transform(leafRefPathQnameList,build), !relativePath);
+    }
+
+
+    @Override
+    public void enterIdentifier(final IdentifierContext ctx) {
+        currentQNameLocalName = ctx.getText();
+    }
+
+    @Override
+    public void exitNode_identifier(final Node_identifierContext ctx) {
+
+        if (currentQnameModule == null) {
+            currentQnameModule = module.getQNameModule();
+        }
+
+        if (currentParsingState == ParsingState.PREDICATE_PATH_EQUALITY_EXPR) {
+            final QName qname = QName.create(currentQnameModule,
+                    currentQNameLocalName);
+            currentPredicate.setIdentifier(qname);
+        } else {
+
+            final QNameWithPredicateBuilder qnameBuilder = new QNameWithPredicateBuilder(
+                    currentQnameModule, currentQNameLocalName);
+
+            if (currentParsingState == ParsingState.PATH_KEY_EXPR) {
+                predicatePathKeyQnameList.add(qnameBuilder);
+            } else if (currentParsingState == ParsingState.LEAF_REF_PATH) {
+                currentLeafRefPathQName = qnameBuilder;
+                leafRefPathQnameList.add(qnameBuilder);
+            }
+        }
+        currentQnameModule = null;
+        currentQNameLocalName = null;
+    }
+
+    public LeafRefPath getLeafRefPath() {
+        return leafRefPath;
+    }
+
+
+    private URI getNamespaceForImportPrefix(final String prefix){
+        final ModuleImport moduleImport = getModuleImport(prefix);
+        final Module findedModule = schemaContext.findModuleByName(moduleImport.getModuleName(), moduleImport.getRevision());
+
+        return findedModule.getNamespace();
+    }
+
+    private QNameModule getQNameModuleForImportPrefix(final String prefix) {
+        final ModuleImport moduleImport = getModuleImport(prefix);
+
+        if (moduleImport == null) {
+            throw new LeafRefPathParseException("No module import for prefix: "
+                    + prefix + " in module: " + module.getName());
+        }
+
+        final String moduleName = moduleImport.getModuleName();
+        final Date revision = moduleImport.getRevision();
+        final Module findedModule = schemaContext.findModuleByName(moduleName,
+                revision);
+
+        return findedModule.getQNameModule();
+    }
+
+
+    private ModuleImport getModuleImport(final String prefix) {
+        final Set<ModuleImport> imports = module.getImports();
+
+        for (final ModuleImport moduleImport : imports) {
+            if(moduleImport.getPrefix().equals(prefix)) {
+                return moduleImport;
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathSyntaxErrorException.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathSyntaxErrorException.java
new file mode 100644 (file)
index 0000000..01e68ac
--- /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.data.impl.leafref;
+
+public class LeafRefPathSyntaxErrorException extends LeafRefYangSyntaxErrorException{
+
+    private static final long serialVersionUID = 1L;
+
+    public LeafRefPathSyntaxErrorException(final String module, final int line, final int charPositionInLine,
+            final String message) {
+        super(module, line, charPositionInLine, message, null);
+    }
+
+    public LeafRefPathSyntaxErrorException(final String module, final int line, final int charPositionInLine,
+            final String message, final Throwable cause) {
+        super(module,line,charPositionInLine,message,cause);
+    }
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefUtils.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefUtils.java
new file mode 100644 (file)
index 0000000..ec06075
--- /dev/null
@@ -0,0 +1,118 @@
+/**
+ * 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.impl.leafref;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public class LeafRefUtils {
+
+    /**
+     * @param leafRefPath
+     * @param contextNodeSchemaPath
+     * @return
+     */
+    public static LeafRefPath createAbsoluteLeafRefPath(
+            final LeafRefPath leafRefPath, final SchemaPath contextNodeSchemaPath,
+            final Module module) {
+
+        if (leafRefPath.isAbsolute())
+            return leafRefPath;
+
+        final LinkedList<QNameWithPredicate> absoluteLeafRefTargetPathList = schemaPathToXPathQNames(
+                contextNodeSchemaPath, module);
+
+        final Iterable<QNameWithPredicate> leafRefTargetPathFromRoot = leafRefPath
+                .getPathFromRoot();
+        final Iterator<QNameWithPredicate> leafRefTgtPathFromRootIterator = leafRefTargetPathFromRoot
+                .iterator();
+
+        while (leafRefTgtPathFromRootIterator.hasNext()) {
+            final QNameWithPredicate qname = leafRefTgtPathFromRootIterator.next();
+            if (qname.equals(QNameWithPredicate.UP_PARENT)) {
+                absoluteLeafRefTargetPathList.removeLast();
+            } else {
+                absoluteLeafRefTargetPathList.add(qname);
+            }
+        }
+
+        return LeafRefPath.create(absoluteLeafRefTargetPathList, true);
+    }
+
+    /**
+     * @param currentNodePath
+     * @param module
+     * @param absoluteLeafRefTargetPathList
+     */
+    private static LinkedList<QNameWithPredicate> schemaPathToXPathQNames(
+            final SchemaPath nodePath, final Module module) {
+
+        final LinkedList<QNameWithPredicate> xpath = new LinkedList<QNameWithPredicate>();
+
+        final Iterator<QName> nodePathIterator = nodePath.getPathFromRoot()
+                .iterator();
+
+        DataNodeContainer currenDataNodeContainer = module;
+        while (nodePathIterator.hasNext()) {
+            final QName qname = nodePathIterator.next();
+            final DataSchemaNode child = currenDataNodeContainer
+                    .getDataChildByName(qname);
+
+            if (child instanceof DataNodeContainer) {
+                if (!(child instanceof ChoiceCaseNode)) {
+                    final QNameWithPredicate newQName = new QNameWithPredicateBuilder(
+                            qname.getModule(), qname.getLocalName()).build();
+                    xpath.add(newQName);
+                }
+                currenDataNodeContainer = (DataNodeContainer) child;
+            } else if (child instanceof ChoiceSchemaNode) {
+                if (nodePathIterator.hasNext()) {
+                    currenDataNodeContainer = ((ChoiceSchemaNode) child)
+                            .getCaseNodeByName(nodePathIterator.next());
+                } else {
+                    break;
+                }
+            } else if (child instanceof LeafSchemaNode
+                    || child instanceof LeafListSchemaNode) {
+
+                final QNameWithPredicate newQName = new QNameWithPredicateBuilder(
+                        qname.getModule(), qname.getLocalName()).build();
+                xpath.add(newQName);
+                break;
+
+            } else if (child == null) {
+                throw new IllegalArgumentException("No child " + qname
+                        + " found in node container " + currenDataNodeContainer
+                        + " in module " + module.getName());
+            } else {
+                throw new IllegalStateException(
+                        "Illegal schema node type in the path: "
+                                + child.getClass());
+            }
+        }
+
+        return xpath;
+    }
+
+    public static LeafRefPath schemaPathToLeafRefPath(final SchemaPath nodePath,
+            final Module module) {
+        final LinkedList<QNameWithPredicate> xpathQNames = schemaPathToXPathQNames(
+                nodePath, module);
+        return LeafRefPath.create(xpathQNames, true);
+    }
+
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefValidatation.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefValidatation.java
new file mode 100644 (file)
index 0000000..4200615
--- /dev/null
@@ -0,0 +1,699 @@
+/**
+ * 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.impl.leafref;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LeafRefValidatation {
+
+    private static final Logger LOG = LoggerFactory.getLogger(LeafRefValidatation.class);
+    private static final String NEW_LINE = System.getProperty("line.separator");
+
+    private final DataTreeCandidate tree;
+    private final LinkedList<String> errorsMessages =  new LinkedList<String>();
+    private final HashSet<LeafRefContext> validatedLeafRefCtx =  new HashSet<LeafRefContext>();
+
+    private LeafRefValidatation(final DataTreeCandidate tree) {
+        this.tree = tree;
+    }
+
+    public static void validate(final DataTreeCandidate tree, final LeafRefContext rootLeafRefCtx)
+            throws LeafRefDataValidationFailedException {
+        new LeafRefValidatation(tree).validate0(rootLeafRefCtx);
+    }
+    private void validate0(final LeafRefContext rootLeafRefCtx)
+            throws LeafRefDataValidationFailedException {
+
+        final DataTreeCandidateNode rootNode = tree.getRootNode();
+
+        final Collection<DataTreeCandidateNode> childNodes = rootNode.getChildNodes();
+        for (final DataTreeCandidateNode dataTreeCandidateNode : childNodes) {
+
+            final ModificationType modificationType = dataTreeCandidateNode
+                    .getModificationType();
+            if (modificationType != ModificationType.UNMODIFIED) {
+
+                final PathArgument identifier = dataTreeCandidateNode.getIdentifier();
+                final QName childQName = identifier.getNodeType();
+
+                final LeafRefContext referencedByCtx = rootLeafRefCtx
+                        .getReferencedChildByName(childQName);
+                final LeafRefContext referencingCtx = rootLeafRefCtx
+                        .getReferencingChildByName(childQName);
+                if (referencedByCtx != null || referencingCtx != null) {
+                    final YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier
+                            .create(dataTreeCandidateNode.getIdentifier());
+                    validateNode(dataTreeCandidateNode, referencedByCtx,
+                            referencingCtx, yangInstanceIdentifier);
+                }
+            }
+
+        }
+
+        if (!errorsMessages.isEmpty()) {
+            final StringBuilder message = new StringBuilder();
+            int errCount = 0;
+            for (final String errorMessage : errorsMessages) {
+                message.append(errorMessage);
+                errCount++;
+            }
+            throw new LeafRefDataValidationFailedException(message.toString(),
+                    errCount);
+        }
+
+    }
+
+    private void validateNode(final DataTreeCandidateNode node,
+            final LeafRefContext referencedByCtx, final LeafRefContext referencingCtx,
+            final YangInstanceIdentifier current) {
+
+        if ((node.getModificationType() == ModificationType.WRITE)
+                && node.getDataAfter().isPresent()) {
+            final Optional<NormalizedNode<?, ?>> dataAfter = node.getDataAfter();
+            final NormalizedNode<?, ?> normalizedNode = dataAfter.get();
+            validateNodeData(normalizedNode, referencedByCtx, referencingCtx,
+                    node.getModificationType(), current);
+            return;
+        }
+
+        if (node.getModificationType() == ModificationType.DELETE
+                && referencedByCtx != null) {
+            final Optional<NormalizedNode<?, ?>> dataBefor = node.getDataBefore();
+            final NormalizedNode<?, ?> normalizedNode = dataBefor.get();
+            validateNodeData(normalizedNode, referencedByCtx, null,
+                    node.getModificationType(), current);
+            return;
+        }
+
+        final Collection<DataTreeCandidateNode> childNodes = node.getChildNodes();
+        for (final DataTreeCandidateNode childNode : childNodes) {
+            final ModificationType modificationType = childNode.getModificationType();
+
+            if (modificationType != ModificationType.UNMODIFIED) {
+
+                final LeafRefContext childReferencedByCtx = getReferencedByCtxChild(
+                        referencedByCtx, childNode);
+                final LeafRefContext childReferencingCtx = getReferencingCtxChild(
+                        referencingCtx, childNode);
+
+                if (childReferencedByCtx != null || childReferencingCtx != null) {
+                    final YangInstanceIdentifier childYangInstanceIdentifier = current
+                            .node(childNode.getIdentifier());
+                    validateNode(childNode, childReferencedByCtx,
+                            childReferencingCtx, childYangInstanceIdentifier);
+                }
+            }
+
+        }
+
+    }
+
+    private LeafRefContext getReferencingCtxChild(
+            final LeafRefContext referencingCtx, final DataTreeCandidateNode childNode) {
+
+        LeafRefContext childReferencingCtx = null;
+        if (referencingCtx != null) {
+            final PathArgument identifier = childNode.getIdentifier();
+            final QName childQName = identifier.getNodeType();
+
+            childReferencingCtx = referencingCtx
+                    .getReferencingChildByName(childQName);
+
+            if (childReferencingCtx == null) {
+                final NormalizedNode<?, ?> data = childNode.getDataAfter().get();
+                if (data instanceof MapEntryNode
+                        || data instanceof UnkeyedListEntryNode) {
+                    childReferencingCtx = referencingCtx;
+                }
+            }
+        }
+
+        return childReferencingCtx;
+    }
+
+    private LeafRefContext getReferencedByCtxChild(
+            final LeafRefContext referencedByCtx, final DataTreeCandidateNode childNode) {
+
+        LeafRefContext childReferencedByCtx = null;
+        if (referencedByCtx != null) {
+            final PathArgument identifier = childNode.getIdentifier();
+            final QName childQName = identifier.getNodeType();
+
+            childReferencedByCtx = referencedByCtx
+                    .getReferencedChildByName(childQName);
+            if (childReferencedByCtx == null) {
+                final NormalizedNode<?, ?> data = childNode.getDataAfter().get();
+                if (data instanceof MapEntryNode
+                        || data instanceof UnkeyedListEntryNode) {
+                    childReferencedByCtx = referencedByCtx;
+                }
+            }
+        }
+
+        return childReferencedByCtx;
+    }
+
+    private void validateNodeData(final NormalizedNode<?, ?> node,
+            final LeafRefContext referencedByCtx, final LeafRefContext referencingCtx,
+            final ModificationType modificationType, final YangInstanceIdentifier current) {
+
+        if (node instanceof LeafNode) {
+            final LeafNode<?> leaf = (LeafNode<?>) node;
+
+            if (referencedByCtx != null && referencedByCtx.isReferenced()) {
+                validateLeafRefTargetNodeData(leaf, referencedByCtx,
+                        modificationType);
+            }
+            if (referencingCtx != null && referencingCtx.isReferencing()) {
+                validateLeafRefNodeData(leaf, referencingCtx, modificationType,
+                        current);
+            }
+
+            return;
+        }
+
+        if (node instanceof LeafSetNode) {
+            final LeafSetNode<?> leafSet = (LeafSetNode<?>) node;
+
+            if (referencedByCtx == null && referencingCtx == null) {
+                return;
+            }
+
+            final Iterable<? extends NormalizedNode<?, ?>> leafSetEntries = leafSet
+                    .getValue();
+            for (final NormalizedNode<?, ?> leafSetEntry : leafSetEntries) {
+                if (referencedByCtx != null && referencedByCtx.isReferenced()) {
+                    validateLeafRefTargetNodeData(leafSetEntry,
+                            referencedByCtx, modificationType);
+                }
+                if (referencingCtx != null && referencingCtx.isReferencing()) {
+                    validateLeafRefNodeData(leafSetEntry, referencingCtx,
+                            modificationType, current);
+                }
+            }
+
+            return;
+        }
+
+        if (node instanceof ChoiceNode) {
+            final ChoiceNode choice = (ChoiceNode) node;
+            final Iterable<DataContainerChild<? extends PathArgument, ?>> childs = choice
+                    .getValue();
+            for (final DataContainerChild<? extends PathArgument, ?> dataContainerChild : childs) {
+                final QName qname = dataContainerChild.getNodeType();
+
+                LeafRefContext childReferencedByCtx = null;
+                LeafRefContext childReferencingCtx = null;
+                if (referencedByCtx != null) {
+                    childReferencedByCtx = findReferencedByCtxUnderChoice(
+                            referencedByCtx, qname);
+                }
+                if (referencingCtx != null) {
+                    childReferencingCtx = findReferencingCtxUnderChoice(
+                            referencingCtx, qname);
+                }
+                if (childReferencedByCtx != null || childReferencingCtx != null) {
+                    final YangInstanceIdentifier childYangInstanceIdentifier = current
+                            .node(dataContainerChild.getIdentifier());
+                    validateNodeData(dataContainerChild, childReferencedByCtx,
+                            childReferencingCtx, modificationType,
+                            childYangInstanceIdentifier);
+                }
+            }
+        } else if (node instanceof DataContainerNode) {
+            final DataContainerNode<?> dataContainerNode = (DataContainerNode<?>) node;
+            final Iterable<DataContainerChild<? extends PathArgument, ?>> dataContainerChilds = dataContainerNode
+                    .getValue();
+
+            for (final DataContainerChild<? extends PathArgument, ?> dataContainerChild : dataContainerChilds) {
+                final QName qname = dataContainerChild.getNodeType();
+
+                LeafRefContext childReferencedByCtx = null;
+                LeafRefContext childReferencingCtx = null;
+                if (referencedByCtx != null) {
+                    childReferencedByCtx = referencedByCtx
+                            .getReferencedChildByName(qname);
+                }
+                if (referencingCtx != null) {
+                    childReferencingCtx = referencingCtx
+                            .getReferencingChildByName(qname);
+                }
+                if (childReferencedByCtx != null || childReferencingCtx != null) {
+                    final YangInstanceIdentifier childYangInstanceIdentifier = current
+                            .node(dataContainerChild.getIdentifier());
+                    validateNodeData(dataContainerChild, childReferencedByCtx,
+                            childReferencingCtx, modificationType,
+                            childYangInstanceIdentifier);
+                }
+            }
+        } else if (node instanceof MapNode) {
+            final MapNode map = (MapNode) node;
+            final Iterable<MapEntryNode> mapEntries = map.getValue();
+            for (final MapEntryNode mapEntry : mapEntries) {
+                final Iterable<DataContainerChild<? extends PathArgument, ?>> mapEntryNodes = mapEntry
+                        .getValue();
+                final YangInstanceIdentifier mapEntryYangInstanceIdentifier = current
+                        .node(mapEntry.getIdentifier());
+                for (final DataContainerChild<? extends PathArgument, ?> mapEntryNode : mapEntryNodes) {
+                    final QName qname = mapEntryNode.getNodeType();
+
+                    LeafRefContext childReferencedByCtx = null;
+                    LeafRefContext childReferencingCtx = null;
+                    if (referencedByCtx != null) {
+                        childReferencedByCtx = referencedByCtx
+                                .getReferencedChildByName(qname);
+                    }
+                    if (referencingCtx != null) {
+                        childReferencingCtx = referencingCtx
+                                .getReferencingChildByName(qname);
+                    }
+                    if (childReferencedByCtx != null
+                            || childReferencingCtx != null) {
+                        final YangInstanceIdentifier mapEntryNodeYangInstanceIdentifier = mapEntryYangInstanceIdentifier
+                                .node(mapEntryNode.getIdentifier());
+                        validateNodeData(mapEntryNode, childReferencedByCtx,
+                                childReferencingCtx, modificationType,
+                                mapEntryNodeYangInstanceIdentifier);
+                    }
+                }
+            }
+
+        }
+        // FIXME if(node instance of UnkeyedListNode ...
+    }
+
+    private LeafRefContext findReferencingCtxUnderChoice(
+            final LeafRefContext referencingCtx, final QName qname) {
+
+        final Map<QName, LeafRefContext> referencingChilds = referencingCtx
+                .getReferencingChilds();
+        final Set<Entry<QName, LeafRefContext>> childs = referencingChilds.entrySet();
+        for (final Entry<QName, LeafRefContext> child : childs) {
+            final LeafRefContext referencingChildByName = child.getValue()
+                    .getReferencingChildByName(qname);
+            if (referencingChildByName != null) {
+                return referencingChildByName;
+            }
+        }
+
+        return null;
+    }
+
+    private LeafRefContext findReferencedByCtxUnderChoice(
+            final LeafRefContext referencedByCtx, final QName qname) {
+
+        final Map<QName, LeafRefContext> referencedByChilds = referencedByCtx
+                .getReferencedByChilds();
+        final Set<Entry<QName, LeafRefContext>> childs = referencedByChilds
+                .entrySet();
+        for (final Entry<QName, LeafRefContext> child : childs) {
+            final LeafRefContext referencedByChildByName = child.getValue()
+                    .getReferencedChildByName(qname);
+            if (referencedByChildByName != null) {
+                return referencedByChildByName;
+            }
+        }
+
+        return null;
+    }
+
+    @SuppressWarnings("rawtypes")
+    private void validateLeafRefTargetNodeData(final NormalizedNode<?, ?> leaf,
+            final LeafRefContext referencedByCtx, final ModificationType modificationType) {
+
+        final StringBuilder header_log = new StringBuilder();
+        final StringBuilder log = new StringBuilder();
+        header_log.append("Operation [" + modificationType
+                + "] validate data of leafref TARGET node: name["
+                + referencedByCtx.getNodeName() + "] = value["
+                + leaf.getValue() + "]");
+
+        if (validatedLeafRefCtx.contains(referencedByCtx)) {
+            header_log.append(" -> SKIP: Already validated");
+            LOG.debug(header_log.toString());
+            return;
+        }
+
+        final Map<QName, LeafRefContext> allReferencedByLeafRefCtxs = referencedByCtx
+                .getAllReferencedByLeafRefCtxs();
+
+        final HashMap<LeafRefContext, HashSet> leafRefsValues = new HashMap<LeafRefContext, HashSet>();
+        final Collection<LeafRefContext> leafrefs = allReferencedByLeafRefCtxs
+                .values();
+        for (final LeafRefContext leafRefContext : leafrefs) {
+            if (leafRefContext.isReferencing()) {
+                final HashSet<Object> values = new HashSet<>();
+
+                final SchemaPath leafRefNodeSchemaPath = leafRefContext
+                        .getCurrentNodePath();
+                final LeafRefPath leafRefNodePath = LeafRefUtils
+                        .schemaPathToLeafRefPath(leafRefNodeSchemaPath,
+                                leafRefContext.getLeafRefContextModule());
+                final Iterable<QNameWithPredicate> pathFromRoot = leafRefNodePath
+                        .getPathFromRoot();
+                addValues(values, tree.getRootNode().getDataAfter(),
+                        pathFromRoot, null, QNameWithPredicate.ROOT);
+                leafRefsValues.put(leafRefContext, values);
+            }
+        }
+
+        final HashSet<Object> leafRefTargetNodeValues = new HashSet<>();
+        final SchemaPath nodeSchemaPath = referencedByCtx.getCurrentNodePath();
+        final LeafRefPath nodePath = LeafRefUtils.schemaPathToLeafRefPath(
+                nodeSchemaPath, referencedByCtx.getLeafRefContextModule());
+        addValues(leafRefTargetNodeValues, tree.getRootNode().getDataAfter(),
+                nodePath.getPathFromRoot(), null, QNameWithPredicate.ROOT);
+
+        boolean valid = true;
+        final Set<Entry<LeafRefContext, HashSet>> entrySet = leafRefsValues
+                .entrySet();
+        for (final Entry<LeafRefContext, HashSet> entry : entrySet) {
+            final LeafRefContext leafRefContext = entry.getKey();
+            final HashSet leafRefValuesSet = entry.getValue();
+            for (final Object leafRefsValue : leafRefValuesSet) {
+                if (!leafRefTargetNodeValues.contains(leafRefsValue)) {
+
+                    final StringBuilder sb = createInvalidTargetMessage(leaf,
+                            leafRefTargetNodeValues, leafRefContext,
+                            leafRefsValue);
+                    log.append(NEW_LINE);
+                    log.append(sb.toString());
+                    log.append(" -> FAILED");
+
+                    sb.append(NEW_LINE);
+                    errorsMessages.add(sb.toString());
+
+                    valid = false;
+                } else {
+                    log.append(NEW_LINE);
+                    log.append("Valid leafref value [");
+                    log.append(leafRefsValue);
+                    log.append("]");
+                    log.append(" -> OK");
+                }
+            }
+        }
+
+        header_log.append(valid ? " -> OK" : " -> FAILED");
+        LOG.debug(header_log.append(log.toString()).toString());
+
+        validatedLeafRefCtx.add(referencedByCtx);
+    }
+
+    private StringBuilder createInvalidTargetMessage(final NormalizedNode<?, ?> leaf,
+            final HashSet<?> leafRefTargetNodeValues, final LeafRefContext leafRefContext,
+            final Object leafRefsValue) {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("Invalid leafref value [");
+        sb.append(leafRefsValue);
+        sb.append("]");
+        sb.append(" allowed values ");
+        sb.append(leafRefTargetNodeValues);
+        sb.append(" by validation of leafref TARGET node: ");
+        sb.append(leaf.getNodeType());
+        sb.append(" path of invalid LEAFREF node: ");
+        sb.append(leafRefContext.getCurrentNodePath());
+        sb.append(" leafRef target path: ");
+        sb.append(leafRefContext.getAbsoluteLeafRefTargetPath());
+        return sb;
+    }
+
+    private void validateLeafRefNodeData(final NormalizedNode<?, ?> leaf,
+            final LeafRefContext referencingCtx, final ModificationType modificationType,
+            final YangInstanceIdentifier current) {
+
+        final StringBuilder header_log = new StringBuilder();
+        final StringBuilder log = new StringBuilder();
+
+        header_log.append("Operation [" + modificationType
+                + "] validate data of LEAFREF node: name["
+                + referencingCtx.getNodeName() + "] = value["
+                + leaf.getValue() + "]");
+
+        final HashSet<Object> values = new HashSet<>();
+        final LeafRefPath targetPath = referencingCtx.getAbsoluteLeafRefTargetPath();
+        final Iterable<QNameWithPredicate> pathFromRoot = targetPath
+                .getPathFromRoot();
+
+        addValues(values, tree.getRootNode().getDataAfter(), pathFromRoot,
+                current, QNameWithPredicate.ROOT);
+
+        if (!values.contains(leaf.getValue())) {
+            final StringBuilder sb = createInvalidLeafRefMessage(leaf,
+                    referencingCtx, values);
+            errorsMessages.add(sb.toString());
+
+            header_log.append(" -> FAILED");
+            log.append(sb.toString());
+        } else {
+            header_log.append(" -> OK");
+        }
+
+        LOG.debug(header_log.toString());
+        if (!log.toString().equals(""))
+            LOG.debug(log.toString());
+    }
+
+    private StringBuilder createInvalidLeafRefMessage(
+            final NormalizedNode<?, ?> leaf, final LeafRefContext referencingCtx,
+            final Set<?> values) {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("Invalid leafref value [");
+        sb.append(leaf.getValue());
+        sb.append("]");
+        sb.append(" allowed values ");
+        sb.append(values);
+        sb.append(" of LEAFREF node: ");
+        sb.append(leaf.getNodeType());
+        sb.append(" leafRef target path: ");
+        sb.append(referencingCtx.getAbsoluteLeafRefTargetPath());
+        sb.append(NEW_LINE);
+        return sb;
+    }
+
+    private void addValues(final Set<Object> values,
+            final Optional<? extends NormalizedNode<?, ?>> optDataNode,
+            final Iterable<QNameWithPredicate> path, final YangInstanceIdentifier current,
+            final QNameWithPredicate previousQName) {
+
+        if (!optDataNode.isPresent()) {
+            return;
+        }
+        final NormalizedNode<?, ?> node = optDataNode.get();
+
+        if (node instanceof LeafNode || node instanceof LeafSetEntryNode) {
+            values.add(node.getValue());
+            return;
+        } else if (node instanceof LeafSetNode<?>) {
+            final LeafSetNode<?> leafSetNode = (LeafSetNode<?>) node;
+            final Iterable<? extends NormalizedNode<?, ?>> entries = leafSetNode
+                    .getValue();
+            for (final NormalizedNode<?, ?> entry : entries) {
+                values.add(entry.getValue());
+            }
+            return;
+        }
+
+        final Iterator<QNameWithPredicate> iterator = path.iterator();
+        if (!iterator.hasNext()) {
+            return;
+        }
+        final QNameWithPredicate qnameWithPredicate = iterator.next();
+        final QName qName = qnameWithPredicate.getQName();
+        final PathArgument pathArgument = toPathArgument(qName);
+
+        if (node instanceof DataContainerNode) {
+            final DataContainerNode<?> dataContainerNode = (DataContainerNode<?>) node;
+            final Optional<DataContainerChild<? extends PathArgument, ?>> child = dataContainerNode
+                    .getChild(pathArgument);
+
+            if (child.isPresent()) {
+                addValues(values, child, nextLevel(path), current,
+                        qnameWithPredicate);
+            } else {
+                final Iterable<ChoiceNode> choiceNodes = getChoiceNodes(dataContainerNode);
+                for (final ChoiceNode choiceNode : choiceNodes) {
+                    addValues(values, Optional.of(choiceNode), path, current,
+                            qnameWithPredicate);
+                }
+            }
+
+        } else if (node instanceof MapNode) {
+            final MapNode map = (MapNode) node;
+            final List<QNamePredicate> qNamePredicates = previousQName
+                    .getQNamePredicates();
+            if (qNamePredicates.isEmpty() || current == null) {
+                final Iterable<MapEntryNode> value = map.getValue();
+                for (final MapEntryNode mapEntryNode : value) {
+                    final Optional<DataContainerChild<? extends PathArgument, ?>> child = mapEntryNode
+                            .getChild(pathArgument);
+
+                    if (child.isPresent()) {
+                        addValues(values, child, nextLevel(path), current,
+                                qnameWithPredicate);
+                    } else {
+                        final Iterable<ChoiceNode> choiceNodes = getChoiceNodes(mapEntryNode);
+                        for (final ChoiceNode choiceNode : choiceNodes) {
+                            addValues(values, Optional.of(choiceNode), path,
+                                    current, qnameWithPredicate);
+                        }
+                    }
+                }
+            } else {
+                final Map<QName, Set<?>> keyValues = new HashMap<QName, Set<?>>();
+
+                final Iterator<QNamePredicate> predicates = qNamePredicates
+                        .iterator();
+                while (predicates.hasNext()) {
+                    final QNamePredicate predicate = predicates.next();
+                    final QName identifier = predicate.getIdentifier();
+                    final LeafRefPath predicatePathKeyExpression = predicate
+                            .getPathKeyExpression();
+
+                    final Set<?> pathKeyExprValues = getPathKeyExpressionValues(
+                            predicatePathKeyExpression, current);
+
+                    keyValues.put(identifier, pathKeyExprValues);
+                }
+
+                final Iterable<MapEntryNode> mapEntryNodes = map.getValue();
+                for (final MapEntryNode mapEntryNode : mapEntryNodes) {
+                    if (isMatchingPredicate(mapEntryNode, keyValues)) {
+                        final Optional<DataContainerChild<? extends PathArgument, ?>> child = mapEntryNode
+                                .getChild(pathArgument);
+
+                        if (child.isPresent()) {
+                            addValues(values, child, nextLevel(path), current,
+                                    qnameWithPredicate);
+                        } else {
+                            final Iterable<ChoiceNode> choiceNodes = getChoiceNodes(mapEntryNode);
+                            for (final ChoiceNode choiceNode : choiceNodes) {
+                                addValues(values, Optional.of(choiceNode),
+                                        path, current, qnameWithPredicate);
+                            }
+                        }
+                    }
+                }
+
+            }
+        }
+    }
+
+    private Iterable<ChoiceNode> getChoiceNodes(
+            final DataContainerNode<?> dataContainerNode) {
+
+        final LinkedList<ChoiceNode> choiceNodes = new LinkedList<ChoiceNode>();
+
+        final Iterable<DataContainerChild<? extends PathArgument, ?>> childs = dataContainerNode
+                .getValue();
+        for (final DataContainerChild<? extends PathArgument, ?> child : childs) {
+            if (child instanceof ChoiceNode) {
+                choiceNodes.add((ChoiceNode) child);
+            }
+        }
+        return choiceNodes;
+    }
+
+    private boolean isMatchingPredicate(final MapEntryNode mapEntryNode,
+            final Map<QName, Set<?>> allowedKeyValues) {
+
+        final NodeIdentifierWithPredicates identifier = mapEntryNode.getIdentifier();
+        final Map<QName, Object> entryKeyValues = identifier.getKeyValues();
+
+        final Set<Entry<QName, Object>> entryKeyValueSet = entryKeyValues.entrySet();
+        for (final Entry<QName, Object> entryKeyValue : entryKeyValueSet) {
+            final QName key = entryKeyValue.getKey();
+            final Object value = entryKeyValue.getValue();
+
+            final Set<?> allowedValues = allowedKeyValues.get(key);
+            if (allowedValues != null && !allowedValues.contains(value)) {
+                return false;
+            }
+
+        }
+
+        return true;
+    }
+
+    private Set<?> getPathKeyExpressionValues(
+            final LeafRefPath predicatePathKeyExpression,
+            final YangInstanceIdentifier current) {
+
+        final Optional<NormalizedNode<?, ?>> parent = findParentNode(tree
+                .getRootNode().getDataAfter(), current);
+
+        final Iterable<QNameWithPredicate> predicatePathExpr = predicatePathKeyExpression
+                .getPathFromRoot();
+        final Iterable<QNameWithPredicate> predicatePath = nextLevel(predicatePathExpr);
+
+        final Set<Object> values = new HashSet<>();
+        if (parent != null) {
+            addValues(values, parent, predicatePath, null,
+                    QNameWithPredicate.ROOT);
+        }
+
+        return values;
+    }
+
+    private Optional<NormalizedNode<?, ?>> findParentNode(
+            final Optional<NormalizedNode<?, ?>> root, final YangInstanceIdentifier path) {
+        Optional<NormalizedNode<?, ?>> currentNode = root;
+        final Iterator<PathArgument> pathIterator = path.getPathArguments()
+                .iterator();
+        while (pathIterator.hasNext()) {
+            final PathArgument childPathArgument = pathIterator.next();
+            if (pathIterator.hasNext() && currentNode.isPresent()) {
+                currentNode = NormalizedNodes.getDirectChild(currentNode.get(),
+                        childPathArgument);
+            } else {
+                return currentNode;
+            }
+        }
+        return Optional.absent();
+    }
+
+    private Iterable<QNameWithPredicate> nextLevel(
+            final Iterable<QNameWithPredicate> path) {
+        return Iterables.skip(path, 1);
+    }
+
+    private PathArgument toPathArgument(final QName qName) {
+        return YangInstanceIdentifier.of(qName).getLastPathArgument();
+    }
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefYangSyntaxErrorException.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefYangSyntaxErrorException.java
new file mode 100644 (file)
index 0000000..f1a4698
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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/eplv10.html
+ */
+package org.opendaylight.yangtools.yang.data.impl.leafref;
+
+import com.google.common.base.Preconditions;
+
+public class LeafRefYangSyntaxErrorException extends Exception {
+    private static final long serialVersionUID = 1L;
+    private final String module;
+    private final int line;
+    private final int charPositionInLine;
+
+    public LeafRefYangSyntaxErrorException(final String module, final int line, final int charPositionInLine,
+            final String message) {
+        this(module, line, charPositionInLine, message, null);
+    }
+
+    public LeafRefYangSyntaxErrorException(final String module, final int line, final int charPositionInLine,
+            final String message, final Throwable cause) {
+        super(Preconditions.checkNotNull(message), cause);
+        this.module = module;
+        this.line = line;
+        this.charPositionInLine = charPositionInLine;
+    }
+
+    public String getModule() {
+        return module;
+    }
+
+    public int getLine() {
+        return line;
+    }
+
+    public int getCharPositionInLine() {
+        return charPositionInLine;
+    }
+
+    public String getFormattedMessage() {
+        final StringBuilder sb = new StringBuilder(getMessage());
+        if (module != null) {
+            sb.append(" in module ");
+            sb.append(module);
+        }
+        if (line != 0) {
+            sb.append(" on line ");
+            sb.append(line);
+            if (charPositionInLine != 0) {
+                sb.append(" character ");
+                sb.append(charPositionInLine);
+            }
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public String toString() {
+        return this.getClass().getName() + ": " + getFormattedMessage();
+    }
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNamePredicate.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNamePredicate.java
new file mode 100644 (file)
index 0000000..e4f5de6
--- /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.data.impl.leafref;
+
+import org.opendaylight.yangtools.yang.common.QName;
+
+public interface QNamePredicate {
+
+    public QName getIdentifier();
+
+    public LeafRefPath getPathKeyExpression();
+
+}
\ No newline at end of file
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNamePredicateBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNamePredicateBuilder.java
new file mode 100644 (file)
index 0000000..0cdb9dd
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * 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.impl.leafref;
+
+import org.opendaylight.yangtools.yang.common.QName;
+
+class QNamePredicateBuilder {
+
+    private QName identifier;
+    private LeafRefPath pathKeyExpression;
+
+    public QNamePredicateBuilder() {
+    }
+
+    public QNamePredicateBuilder(final QName identifier, final LeafRefPath pathKeyExpression) {
+        this.identifier = identifier;
+        this.pathKeyExpression = pathKeyExpression;
+    }
+
+    public QName getIdentifier() {
+        return identifier;
+    }
+
+    public void setIdentifier(final QName identifier) {
+        this.identifier = identifier;
+    }
+
+    public LeafRefPath getPathKeyExpression() {
+        return pathKeyExpression;
+    }
+
+    public void setPathKeyExpression(final LeafRefPath pathKeyExpression) {
+        this.pathKeyExpression = pathKeyExpression;
+    }
+
+    public QNamePredicate build() {
+        return new QNamePredicateImpl(identifier, pathKeyExpression);
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("[");
+
+        sb.append(identifier);
+        sb.append("=current()");
+
+        final Iterable<QNameWithPredicate> pathFromRoot = pathKeyExpression
+                .getPathFromRoot();
+
+        for (final QNameWithPredicate qName : pathFromRoot) {
+            sb.append("/" + qName);
+        }
+
+        sb.append("]");
+        return sb.toString();
+    }
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNamePredicateImpl.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNamePredicateImpl.java
new file mode 100644 (file)
index 0000000..6607475
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * 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.impl.leafref;
+
+import com.google.common.base.Preconditions;
+import java.io.Serializable;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.QName;
+
+class QNamePredicateImpl implements Immutable, Serializable,
+        QNamePredicate {
+
+    private static final long serialVersionUID = 1L;
+    private final QName identifier;
+    private final LeafRefPath pathKeyExpression;
+
+    public QNamePredicateImpl(final QName identifier, final LeafRefPath pathKeyExpression) {
+        this.identifier = Preconditions.checkNotNull(identifier, "QNamePredicate: identifier should not be null");
+        this.pathKeyExpression = Preconditions.checkNotNull(pathKeyExpression, "QNamePredicate: pathKeyExpression should not be null");
+    }
+
+    @Override
+    public QName getIdentifier() {
+        return identifier;
+    }
+
+    @Override
+    public LeafRefPath getPathKeyExpression() {
+        return pathKeyExpression;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("[");
+
+        sb.append(identifier);
+        sb.append("=current()");
+
+        final Iterable<QNameWithPredicate> pathFromRoot = pathKeyExpression
+                .getPathFromRoot();
+
+        for (final QNameWithPredicate qName : pathFromRoot) {
+            sb.append("/" + qName);
+        }
+
+        sb.append("]");
+        return sb.toString();
+    }
+
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNameWithPredicate.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNameWithPredicate.java
new file mode 100644 (file)
index 0000000..c3adece
--- /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.data.impl.leafref;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+
+public interface QNameWithPredicate {
+
+    static final QNameWithPredicate UP_PARENT = new QNameWithPredicateBuilder(
+            null, "..").build();
+
+    static final QNameWithPredicate ROOT = new QNameWithPredicateBuilder(
+            null, "").build();
+
+    public List<QNamePredicate> getQNamePredicates();
+
+    public QNameModule getModuleQname();
+
+    public String getLocalName();
+
+    public QName getQName();
+
+}
\ No newline at end of file
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNameWithPredicateBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNameWithPredicateBuilder.java
new file mode 100644 (file)
index 0000000..daa8dbd
--- /dev/null
@@ -0,0 +1,104 @@
+/**
+ * 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.impl.leafref;
+
+import java.util.LinkedList;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+
+class QNameWithPredicateBuilder {
+
+    private LinkedList<QNamePredicate> qnamePredicates;
+    private QNameModule moduleQname;
+    private String localName;
+
+    public static QNameWithPredicateBuilder UP_PARENT_BUILDER = new QNameWithPredicateBuilder(
+            null, "..") {
+        @Override
+        public QNameWithPredicate build() {
+            return QNameWithPredicate.UP_PARENT;
+        }
+    };
+
+    public QNameWithPredicateBuilder(final QNameModule moduleQname, final String localName) {
+        this.moduleQname = moduleQname;
+        this.localName = localName;
+        this.qnamePredicates = new LinkedList<QNamePredicate>();
+    }
+
+    public QNameWithPredicate build() {
+        final QNameWithPredicateImpl qNameWithPredicateImpl = new QNameWithPredicateImpl(
+                moduleQname, localName, qnamePredicates);
+
+        this.qnamePredicates = new LinkedList<QNamePredicate>();
+
+        return qNameWithPredicateImpl;
+    }
+
+    public LinkedList<QNamePredicate> getQNamePredicates() {
+        return qnamePredicates;
+    }
+
+    public void addQNamePredicate(final QNamePredicate qnamePredicate) {
+        qnamePredicates.add(qnamePredicate);
+    }
+
+    public QNameModule getModuleQname() {
+        return moduleQname;
+    }
+
+    public void setModuleQname(final QNameModule moduleQname) {
+        this.moduleQname = moduleQname;
+    }
+
+    public String getLocalName() {
+        return localName;
+    }
+
+    public void setLocalName(final String localName) {
+        this.localName = localName;
+    }
+
+    // FIXME: check also predicates ...
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof QNameWithPredicateBuilder)) {
+            return false;
+        }
+        final QNameWithPredicateBuilder other = (QNameWithPredicateBuilder) obj;
+        if (localName == null) {
+            if (other.localName != null) {
+                return false;
+            }
+        } else if (!localName.equals(other.localName)) {
+            return false;
+        }
+        return moduleQname.equals(other.moduleQname);
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+
+        if (moduleQname != null) {
+            sb.append("(" + moduleQname.getNamespace());
+            sb.append("?revision=" + moduleQname.getRevision());
+            sb.append(")");
+        }
+
+        sb.append(localName);
+
+        for (final QNamePredicate predicate : qnamePredicates) {
+            sb.append(predicate);
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNameWithPredicateImpl.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNameWithPredicateImpl.java
new file mode 100644 (file)
index 0000000..1661d9b
--- /dev/null
@@ -0,0 +1,91 @@
+/**
+ * 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.impl.leafref;
+
+import java.io.Serializable;
+import java.util.LinkedList;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+
+final class QNameWithPredicateImpl implements Immutable, Serializable,
+        QNameWithPredicate {
+
+    private static final long serialVersionUID = 1L;
+
+    private final LinkedList<QNamePredicate> qnamePredicates;
+    private final QNameModule moduleQname;
+    private final String localName;
+
+    public QNameWithPredicateImpl(final QNameModule moduleQname, final String localName,
+            final LinkedList<QNamePredicate> qnamePredicates) {
+        this.moduleQname = moduleQname;
+        this.localName = localName;
+        this.qnamePredicates = qnamePredicates;
+    }
+
+    @Override
+    public LinkedList<QNamePredicate> getQNamePredicates() {
+        return qnamePredicates;
+    }
+
+    @Override
+    public QNameModule getModuleQname() {
+        return moduleQname;
+    }
+
+    @Override
+    public String getLocalName() {
+        return localName;
+    }
+
+    @Override
+    public QName getQName() {
+        return QName.create(moduleQname, localName);
+    }
+
+    // FIXME: check also predicates ...
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof QNameWithPredicateImpl)) {
+            return false;
+        }
+        final QNameWithPredicateImpl other = (QNameWithPredicateImpl) obj;
+        if (localName == null) {
+            if (other.localName != null) {
+                return false;
+            }
+        } else if (!localName.equals(other.localName)) {
+            return false;
+        }
+        return moduleQname.equals(other.moduleQname);
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+
+        if (moduleQname != null) {
+            sb.append("(" + moduleQname.getNamespace());
+            sb.append("?revision=" + moduleQname.getRevision());
+            sb.append(")");
+        }
+
+        sb.append(localName);
+
+        for (final QNamePredicate predicate : qnamePredicates) {
+            sb.append(predicate);
+        }
+
+        return sb.toString();
+    }
+
+}
index 0fd44f478068ab4415afdc656cc04e89776a1b33..c7013c4a706ed9019cd4b0f31600a03fc2310224 100644 (file)
@@ -7,7 +7,12 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import java.util.Map;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 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.ChoiceNode;
@@ -15,6 +20,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder;
@@ -22,6 +28,8 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableCo
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public final class ImmutableNodes {
 
@@ -83,4 +91,46 @@ public final class ImmutableNodes {
     public static ChoiceNode choiceNode(final QName name) {
         return ImmutableChoiceNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(name)).build();
     }
+
+    /**
+     * Convert YangInstanceIdentifier into a normalized node structure
+     *
+     * @param ctx schema context to used during serialization
+     * @param id instance identifier to convert to node structure starting from root
+     * @return serialized normalized node for provided instance Id
+     */
+    public static NormalizedNode<?, ?> fromInstanceId(final SchemaContext ctx, final YangInstanceIdentifier id) {
+        return fromInstanceId(ctx, id, Optional.<NormalizedNode<?, ?>>absent(), Optional.<Map.Entry<QName, ModifyAction>>absent());
+    }
+
+    /**
+     * Convert YangInstanceIdentifier into a normalized node structure
+     *
+     * @param ctx schema context to used during serialization
+     * @param id instance identifier to convert to node structure starting from root
+     * @param deepestElement pre-built deepest child that will be inserted at the last path argument of provided instance Id
+     * @return serialized normalized node for provided instance Id with overridden last child.
+     */
+    public static NormalizedNode<?, ?> fromInstanceId(final SchemaContext ctx, final YangInstanceIdentifier id, final NormalizedNode<?, ?> deepestElement) {
+        return fromInstanceId(ctx, id, Optional.<NormalizedNode<?, ?>>of(deepestElement), Optional.<Map.Entry<QName, ModifyAction>>absent());
+    }
+
+    /**
+     * Convert YangInstanceIdentifier into a normalized node structure
+     *
+     * @param ctx schema context to used during serialization
+     * @param id instance identifier to convert to node structure starting from root
+     * @param deepestElement pre-built deepest child that will be inserted at the last path argument of provided instance Id
+     * @param operation modify operation attribute to be added to the deepest child. QName is the operation attribute key and ModifyAction is the value.
+     * @return serialized normalized node for provided instance Id with (optionally) overridden last child and (optionally) marked with specific operation attribute.
+     */
+    public static NormalizedNode<?, ?> fromInstanceId(final SchemaContext ctx, final YangInstanceIdentifier id, final Optional<NormalizedNode<?, ?>> deepestElement, final Optional<Map.Entry<QName, ModifyAction>> operation) {
+        Preconditions.checkNotNull(ctx);
+        Preconditions.checkNotNull(id);
+        final YangInstanceIdentifier.PathArgument topLevelElement = id.getPathArguments().iterator().next();
+        final DataSchemaNode dataChildByName = ctx.getDataChildByName(topLevelElement.getNodeType());
+        Preconditions.checkNotNull(dataChildByName, "Cannot find %s node in schema context. Instance identifier has to start from root", topLevelElement);
+        final InstanceIdToNodes<?> instanceIdToNodes = InstanceIdToNodes.fromSchemaAndQNameChecked(ctx, topLevelElement.getNodeType());
+        return instanceIdToNodes.create(id, deepestElement, operation);
+    }
 }
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/InstanceIdToCompositeNodes.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/InstanceIdToCompositeNodes.java
new file mode 100644 (file)
index 0000000..28e8d89
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ * 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.impl.schema;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.AttributesBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema;
+
+/**
+* Base strategy for converting an instance identifier into a normalized node structure for container-like types.
+*/
+abstract class InstanceIdToCompositeNodes<T extends YangInstanceIdentifier.PathArgument> extends
+        InstanceIdToNodes<T> {
+
+    protected InstanceIdToCompositeNodes(final T identifier) {
+        super(identifier);
+    }
+
+    private static YangInstanceIdentifier.AugmentationIdentifier augmentationIdentifierFrom(final AugmentationSchema augmentation) {
+        final ImmutableSet.Builder<QName> potentialChildren = ImmutableSet.builder();
+        for (final DataSchemaNode child : augmentation.getChildNodes()) {
+            potentialChildren.add(child.getQName());
+        }
+        return new YangInstanceIdentifier.AugmentationIdentifier(potentialChildren.build());
+    }
+
+    private static DataNodeContainer augmentationProxy(final AugmentationSchema augmentation, final DataNodeContainer schema) {
+        final Set<DataSchemaNode> children = new HashSet<>();
+        for (final DataSchemaNode augNode : augmentation.getChildNodes()) {
+            children.add(schema.getDataChildByName(augNode.getQName()));
+        }
+        return new EffectiveAugmentationSchema(augmentation, children);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public final NormalizedNode<?, ?> create(final YangInstanceIdentifier instanceId, final Optional<NormalizedNode<?, ?>> lastChild, final Optional<Map.Entry<QName,ModifyAction>> operation) {
+        checkNotNull(instanceId);
+        final Iterator<YangInstanceIdentifier.PathArgument> iterator = instanceId.getPathArguments().iterator();
+        final YangInstanceIdentifier.PathArgument legacyData = iterator.next();
+
+        if (!isMixin(this) && getIdentifier().getNodeType() != null) {
+            checkArgument(getIdentifier().getNodeType().equals(legacyData.getNodeType()),
+                    "Node QName must be %s was %s", getIdentifier().getNodeType(), legacyData.getNodeType());
+        }
+        final NormalizedNodeContainerBuilder builder = createBuilder(legacyData);
+
+        if (iterator.hasNext()) {
+            final YangInstanceIdentifier.PathArgument childPath = iterator.next();
+            final InstanceIdToNodes childOp = getChildOperation(childPath);
+
+            final YangInstanceIdentifier childId = YangInstanceIdentifier.create(Iterables.skip(instanceId.getPathArguments(), 1));
+            builder.addChild(childOp.create(childId, lastChild, operation));
+        } else {
+            if(lastChild.isPresent()) {
+                builder.withValue(Lists.newArrayList((Collection<?>) lastChild.get().getValue()));
+            }
+            if(operation.isPresent()) {
+                Preconditions.checkArgument(builder instanceof AttributesBuilder<?>);
+                addModifyOpIfPresent(operation, ((AttributesBuilder<?>) builder));
+            }
+        }
+
+        return builder.build();
+    }
+
+    private InstanceIdToNodes getChildOperation(final YangInstanceIdentifier.PathArgument childPath) {
+        final InstanceIdToNodes childOp;
+        try {
+            childOp = getChild(childPath);
+        } catch (final RuntimeException e) {
+            throw new IllegalArgumentException(String.format("Failed to process child node %s", childPath), e);
+        }
+        checkArgument(childOp != null, "Node %s is not allowed inside %s", childPath, getIdentifier());
+        return childOp;
+    }
+
+    @SuppressWarnings("rawtypes")
+    protected abstract NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final YangInstanceIdentifier.PathArgument compositeNode);
+
+    static abstract class DataContainerNormalizationOperation<T extends YangInstanceIdentifier.PathArgument> extends
+            InstanceIdToCompositeNodes<T> {
+
+        private final DataNodeContainer schema;
+        private final Map<YangInstanceIdentifier.PathArgument, InstanceIdToNodes<?>> byArg;
+
+        protected DataContainerNormalizationOperation(final T identifier, final DataNodeContainer schema) {
+            super(identifier);
+            this.schema = schema;
+            this.byArg = new ConcurrentHashMap<>();
+        }
+
+        @Override
+        public InstanceIdToNodes<?> getChild(final YangInstanceIdentifier.PathArgument child) {
+            InstanceIdToNodes<?> potential = byArg.get(child);
+            if (potential != null) {
+                return potential;
+            }
+            potential = fromLocalSchema(child);
+            return register(potential);
+        }
+
+        private InstanceIdToNodes<?> fromLocalSchema(final YangInstanceIdentifier.PathArgument child) {
+            if (child instanceof YangInstanceIdentifier.AugmentationIdentifier) {
+                return fromSchemaAndQNameChecked(schema, ((YangInstanceIdentifier.AugmentationIdentifier) child).getPossibleChildNames()
+                        .iterator().next());
+            }
+            return fromSchemaAndQNameChecked(schema, child.getNodeType());
+        }
+
+        private InstanceIdToNodes<?> register(final InstanceIdToNodes<?> potential) {
+            if (potential != null) {
+                byArg.put(potential.getIdentifier(), potential);
+            }
+            return potential;
+        }
+    }
+
+    static final class ListItemNormalization extends
+            DataContainerNormalizationOperation<YangInstanceIdentifier.NodeIdentifierWithPredicates> {
+
+        protected ListItemNormalization(final YangInstanceIdentifier.NodeIdentifierWithPredicates identifier, final ListSchemaNode schema) {
+            super(identifier, schema);
+        }
+
+        @Override
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final YangInstanceIdentifier.PathArgument currentArg) {
+            final DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> builder = Builders
+                    .mapEntryBuilder().withNodeIdentifier((YangInstanceIdentifier.NodeIdentifierWithPredicates) currentArg);
+            for (final Map.Entry<QName, Object> keyValue : ((YangInstanceIdentifier.NodeIdentifierWithPredicates) currentArg).getKeyValues().entrySet()) {
+                builder.addChild(Builders.leafBuilder()
+                        //
+                        .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(keyValue.getKey())).withValue(keyValue.getValue())
+                        .build());
+            }
+            return builder;
+        }
+
+    }
+
+    static final class UnkeyedListItemNormalization extends DataContainerNormalizationOperation<YangInstanceIdentifier.NodeIdentifier> {
+
+        protected UnkeyedListItemNormalization(final ListSchemaNode schema) {
+            super(new YangInstanceIdentifier.NodeIdentifier(schema.getQName()), schema);
+        }
+
+        @Override
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final YangInstanceIdentifier.PathArgument compositeNode) {
+            return Builders.unkeyedListEntryBuilder().withNodeIdentifier(getIdentifier());
+        }
+
+    }
+
+    static final class ContainerTransformation extends DataContainerNormalizationOperation<YangInstanceIdentifier.NodeIdentifier> {
+
+        protected ContainerTransformation(final ContainerSchemaNode schema) {
+            super(new YangInstanceIdentifier.NodeIdentifier(schema.getQName()), schema);
+        }
+
+        @Override
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final YangInstanceIdentifier.PathArgument compositeNode) {
+            return Builders.containerBuilder().withNodeIdentifier(getIdentifier());
+        }
+    }
+
+    static final class OrderedLeafListMixinNormalization extends UnorderedLeafListMixinNormalization {
+
+
+        public OrderedLeafListMixinNormalization(final LeafListSchemaNode potential) {
+            super(potential);
+        }
+
+        @Override
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final YangInstanceIdentifier.PathArgument compositeNode) {
+            return Builders.orderedLeafSetBuilder().withNodeIdentifier(getIdentifier());
+        }
+    }
+
+    static class UnorderedLeafListMixinNormalization extends InstanceIdToCompositeNodes<YangInstanceIdentifier.NodeIdentifier> implements MixinNormalizationOp {
+
+        private final InstanceIdToNodes<?> innerOp;
+
+        public UnorderedLeafListMixinNormalization(final LeafListSchemaNode potential) {
+            super(new YangInstanceIdentifier.NodeIdentifier(potential.getQName()));
+            innerOp = new InstanceIdToSimpleNodes.LeafListEntryNormalization(potential);
+        }
+
+        @Override
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final YangInstanceIdentifier.PathArgument compositeNode) {
+            return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier());
+        }
+
+        @Override
+        public InstanceIdToNodes<?> getChild(final YangInstanceIdentifier.PathArgument child) {
+            if (child instanceof YangInstanceIdentifier.NodeWithValue) {
+                return innerOp;
+            }
+            return null;
+        }
+    }
+
+    static final class AugmentationNormalization extends DataContainerNormalizationOperation<YangInstanceIdentifier.AugmentationIdentifier> implements MixinNormalizationOp {
+
+        public AugmentationNormalization(final AugmentationSchema augmentation, final DataNodeContainer schema) {
+            super(augmentationIdentifierFrom(augmentation), augmentationProxy(augmentation, schema));
+        }
+
+        @Override
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final YangInstanceIdentifier.PathArgument compositeNode) {
+            return Builders.augmentationBuilder().withNodeIdentifier(getIdentifier());
+        }
+    }
+
+    static class UnorderedMapMixinNormalization extends InstanceIdToCompositeNodes<YangInstanceIdentifier.NodeIdentifier> implements MixinNormalizationOp {
+
+        private final ListItemNormalization innerNode;
+
+        public UnorderedMapMixinNormalization(final ListSchemaNode list) {
+            super(new YangInstanceIdentifier.NodeIdentifier(list.getQName()));
+            this.innerNode = new ListItemNormalization(new YangInstanceIdentifier.NodeIdentifierWithPredicates(list.getQName(),
+                    Collections.<QName, Object>emptyMap()), list);
+        }
+
+        @Override
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final YangInstanceIdentifier.PathArgument compositeNode) {
+            return Builders.mapBuilder().withNodeIdentifier(getIdentifier());
+        }
+
+        @Override
+        public InstanceIdToNodes<?> getChild(final YangInstanceIdentifier.PathArgument child) {
+            if (child.getNodeType().equals(getIdentifier().getNodeType())) {
+                return innerNode;
+            }
+            return null;
+        }
+    }
+
+    static final class OrderedMapMixinNormalization extends UnorderedMapMixinNormalization {
+
+        public OrderedMapMixinNormalization(final ListSchemaNode list) {
+            super(list);
+        }
+
+        @Override
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final YangInstanceIdentifier.PathArgument compositeNode) {
+            return Builders.orderedMapBuilder().withNodeIdentifier(getIdentifier());
+        }
+
+    }
+
+    static class ChoiceNodeNormalization extends InstanceIdToCompositeNodes<YangInstanceIdentifier.NodeIdentifier> implements MixinNormalizationOp {
+
+        private final ImmutableMap<YangInstanceIdentifier.PathArgument, InstanceIdToNodes<?>> byArg;
+
+        protected ChoiceNodeNormalization(final ChoiceSchemaNode schema) {
+            super(new YangInstanceIdentifier.NodeIdentifier(schema.getQName()));
+            final ImmutableMap.Builder<YangInstanceIdentifier.PathArgument, InstanceIdToNodes<?>> byArgBuilder = ImmutableMap.builder();
+
+            for (final ChoiceCaseNode caze : schema.getCases()) {
+                for (final DataSchemaNode cazeChild : caze.getChildNodes()) {
+                    final InstanceIdToNodes<?> childOp = fromDataSchemaNode(cazeChild);
+                    byArgBuilder.put(childOp.getIdentifier(), childOp);
+                }
+            }
+            byArg = byArgBuilder.build();
+        }
+
+        @Override
+        public InstanceIdToNodes<?> getChild(final YangInstanceIdentifier.PathArgument child) {
+            return byArg.get(child);
+        }
+
+        @Override
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final YangInstanceIdentifier.PathArgument compositeNode) {
+            return Builders.choiceBuilder().withNodeIdentifier(getIdentifier());
+        }
+    }
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/InstanceIdToNodes.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/InstanceIdToNodes.java
new file mode 100644 (file)
index 0000000..0185f57
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * 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.impl.schema;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.FluentIterable;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map.Entry;
+import javax.xml.transform.dom.DOMSource;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.AttributesBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+/**
+ * Base strategy for converting an instance identifier into a normalized node structure.
+ * Use provided static methods for generic YangInstanceIdentifier -> NormalizedNode translation in ImmutableNodes.
+ */
+abstract class InstanceIdToNodes<T extends PathArgument> implements Identifiable<T> {
+
+    private final T identifier;
+
+    @Override
+    public T getIdentifier() {
+        return identifier;
+    }
+
+    protected InstanceIdToNodes(final T identifier) {
+        this.identifier = identifier;
+    }
+
+    /**
+     * Build a strategy for the next path argument
+     *
+     * @param child child identifier
+     * @return transformation strategy for a specific child
+     */
+    abstract InstanceIdToNodes<?> getChild(final PathArgument child);
+
+    /**
+     *
+     * Convert instance identifier into a NormalizedNode structure
+     *
+     * @param instanceId Instance identifier to transform into NormalizedNodes
+     * @param deepestChild Optional normalized node to be inserted as the last child
+     * @param operation Optional modify operation to be set on the last child
+     * @return NormalizedNode structure corresponding to submitted instance ID
+     */
+    abstract NormalizedNode<?, ?> create(YangInstanceIdentifier instanceId, Optional<NormalizedNode<?, ?>> deepestChild, Optional<Entry<QName,ModifyAction>> operation);
+
+
+    public void addModifyOpIfPresent(final Optional<Entry<QName,ModifyAction>> operation, final AttributesBuilder<?> builder) {
+        if(operation.isPresent()) {
+            builder.withAttributes(Collections.singletonMap(operation.get().getKey(), modifyOperationToXmlString(operation.get().getValue())));
+        }
+    }
+
+    public static String modifyOperationToXmlString(final ModifyAction operation) {
+        return operation.name().toLowerCase();
+    }
+
+    static boolean isMixin(final InstanceIdToNodes<?> op) {
+        return op instanceof MixinNormalizationOp;
+    }
+
+    /**
+     * Marker interface for Mixin nodes normalization operations
+     */
+    interface MixinNormalizationOp {}
+
+
+    private static class UnkeyedListMixinNormalization extends InstanceIdToCompositeNodes<NodeIdentifier> implements MixinNormalizationOp {
+
+        private final UnkeyedListItemNormalization innerNode;
+
+        public UnkeyedListMixinNormalization(final ListSchemaNode list) {
+            super(new NodeIdentifier(list.getQName()));
+            this.innerNode = new UnkeyedListItemNormalization(list);
+        }
+
+        @Override
+        protected NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final PathArgument compositeNode) {
+            return Builders.unkeyedListBuilder().withNodeIdentifier(getIdentifier());
+        }
+
+        @Override
+        public InstanceIdToNodes<?> getChild(final PathArgument child) {
+            if (child.getNodeType().equals(getIdentifier().getNodeType())) {
+                return innerNode;
+            }
+            return null;
+        }
+    }
+
+    private static class AnyXmlNormalization extends InstanceIdToNodes<NodeIdentifier> {
+
+        protected AnyXmlNormalization(final AnyXmlSchemaNode schema) {
+            super(new NodeIdentifier(schema.getQName()));
+        }
+
+        @Override
+        public InstanceIdToNodes<?> getChild(final PathArgument child) {
+            return null;
+        }
+
+        @Override
+        public NormalizedNode<?, ?> create(final YangInstanceIdentifier instanceId, final Optional<NormalizedNode<?, ?>> deepestChild, final Optional<Entry<QName,ModifyAction>> operation) {
+            if(deepestChild.isPresent()) {
+                Preconditions.checkState(deepestChild instanceof AnyXmlNode);
+                final NormalizedNodeAttrBuilder<NodeIdentifier, DOMSource, AnyXmlNode> anyXmlBuilder =
+                        Builders.anyXmlBuilder().withNodeIdentifier(getIdentifier()).withValue(((AnyXmlNode) deepestChild).getValue());
+                addModifyOpIfPresent(operation, anyXmlBuilder);
+                return anyXmlBuilder.build();
+            }
+
+            final NormalizedNodeAttrBuilder<NodeIdentifier, DOMSource, AnyXmlNode> builder =
+                    Builders.anyXmlBuilder().withNodeIdentifier(getIdentifier());
+            addModifyOpIfPresent(operation, builder);
+            return builder.build();
+        }
+
+    }
+
+    private static Optional<DataSchemaNode> findChildSchemaNode(final DataNodeContainer parent, final QName child) {
+        DataSchemaNode potential = parent.getDataChildByName(child);
+        if (potential == null) {
+            final Iterable<ChoiceSchemaNode> choices = FluentIterable.from(parent.getChildNodes()).filter(ChoiceSchemaNode.class);
+            potential = findChoice(choices, child);
+        }
+        return Optional.fromNullable(potential);
+    }
+
+    static InstanceIdToNodes<?> fromSchemaAndQNameChecked(final DataNodeContainer schema, final QName child) {
+        final Optional<DataSchemaNode> potential = findChildSchemaNode(schema, child);
+        Preconditions.checkArgument(potential.isPresent(),
+                "Supplied QName %s is not valid according to schema %s, potential children nodes: %s", child, schema, schema.getChildNodes());
+
+        final DataSchemaNode result = potential.get();
+        // We try to look up if this node was added by augmentation
+        if ((schema instanceof DataSchemaNode) && result.isAugmenting()) {
+            return fromAugmentation(schema, (AugmentationTarget) schema, result);
+        }
+        return fromDataSchemaNode(result);
+    }
+
+    private static ChoiceSchemaNode findChoice(final Iterable<ChoiceSchemaNode> choices, final QName child) {
+        ChoiceSchemaNode foundChoice = null;
+        choiceLoop:
+        for (final ChoiceSchemaNode choice : choices) {
+            for (final ChoiceCaseNode caze : choice.getCases()) {
+                if (findChildSchemaNode(caze, child).isPresent()) {
+                    foundChoice = choice;
+                    break choiceLoop;
+                }
+            }
+        }
+        return foundChoice;
+    }
+
+    /**
+     * Returns a SchemaPathUtil for provided child node
+     * <p/>
+     * If supplied child is added by Augmentation this operation returns
+     * a SchemaPathUtil for augmentation,
+     * otherwise returns a SchemaPathUtil for child as
+     * call for {@link #fromDataSchemaNode(org.opendaylight.yangtools.yang.model.api.DataSchemaNode)}.
+     */
+    private static InstanceIdToNodes<?> fromAugmentation(final DataNodeContainer parent,
+                                                          final AugmentationTarget parentAug, final DataSchemaNode child) {
+        AugmentationSchema augmentation = null;
+        for (final AugmentationSchema aug : parentAug.getAvailableAugmentations()) {
+            final DataSchemaNode potential = aug.getDataChildByName(child.getQName());
+            if (potential != null) {
+                augmentation = aug;
+                break;
+            }
+
+        }
+        if (augmentation != null) {
+            return new InstanceIdToCompositeNodes.AugmentationNormalization(augmentation, parent);
+        } else {
+            return fromDataSchemaNode(child);
+        }
+    }
+
+    static InstanceIdToNodes<?> fromDataSchemaNode(final DataSchemaNode potential) {
+        if (potential instanceof ContainerSchemaNode) {
+            return new InstanceIdToCompositeNodes.ContainerTransformation((ContainerSchemaNode) potential);
+        } else if (potential instanceof ListSchemaNode) {
+            return fromListSchemaNode((ListSchemaNode) potential);
+        } else if (potential instanceof LeafSchemaNode) {
+            return new InstanceIdToSimpleNodes.LeafNormalization((LeafSchemaNode) potential);
+        } else if (potential instanceof ChoiceSchemaNode) {
+            return new InstanceIdToCompositeNodes.ChoiceNodeNormalization((ChoiceSchemaNode) potential);
+        } else if (potential instanceof LeafListSchemaNode) {
+            return fromLeafListSchemaNode((LeafListSchemaNode) potential);
+        } else if (potential instanceof AnyXmlSchemaNode) {
+            return new AnyXmlNormalization((AnyXmlSchemaNode) potential);
+        }
+        return null;
+    }
+
+    private static InstanceIdToNodes<?> fromListSchemaNode(final ListSchemaNode potential) {
+        final List<QName> keyDefinition = potential.getKeyDefinition();
+        if (keyDefinition == null || keyDefinition.isEmpty()) {
+            return new UnkeyedListMixinNormalization(potential);
+        }
+        if (potential.isUserOrdered()) {
+            return new InstanceIdToCompositeNodes.OrderedMapMixinNormalization(potential);
+        }
+        return new InstanceIdToCompositeNodes.UnorderedMapMixinNormalization(potential);
+    }
+
+    private static InstanceIdToNodes<?> fromLeafListSchemaNode(final LeafListSchemaNode potential) {
+        if (potential.isUserOrdered()) {
+            return new InstanceIdToCompositeNodes.OrderedLeafListMixinNormalization(potential);
+        }
+        return new InstanceIdToCompositeNodes.UnorderedLeafListMixinNormalization(potential);
+    }
+
+
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/InstanceIdToSimpleNodes.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/InstanceIdToSimpleNodes.java
new file mode 100644 (file)
index 0000000..7a3e86a
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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.impl.schema;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+
+/**
+* Base strategy for converting an instance identifier into a normalized node structure for leaf and leaf-list types.
+*/
+abstract class InstanceIdToSimpleNodes<T extends YangInstanceIdentifier.PathArgument> extends InstanceIdToNodes<T> {
+
+    protected InstanceIdToSimpleNodes(final T identifier) {
+        super(identifier);
+    }
+
+    @Override
+    public NormalizedNode<?, ?> create(final YangInstanceIdentifier instanceId, final Optional<NormalizedNode<?, ?>> deepestChild, final Optional<Map.Entry<QName,ModifyAction>> operation) {
+        checkNotNull(instanceId);
+        final YangInstanceIdentifier.PathArgument pathArgument = Iterables.get(instanceId.getPathArguments(), 0);
+        final NormalizedNodeAttrBuilder<? extends YangInstanceIdentifier.PathArgument, Object, ? extends NormalizedNode<? extends YangInstanceIdentifier.PathArgument, Object>> builder = getBuilder(pathArgument);
+
+        if(deepestChild.isPresent()) {
+            builder.withValue(deepestChild.get().getValue());
+        }
+
+        addModifyOpIfPresent(operation, builder);
+        return builder.build();
+    }
+
+    protected abstract NormalizedNodeAttrBuilder<? extends YangInstanceIdentifier.PathArgument, Object, ? extends NormalizedNode<? extends YangInstanceIdentifier.PathArgument, Object>> getBuilder(YangInstanceIdentifier.PathArgument node);
+
+    @Override
+    public InstanceIdToNodes<?> getChild(final YangInstanceIdentifier.PathArgument child) {
+        return null;
+    }
+
+    static final class LeafNormalization extends InstanceIdToSimpleNodes<YangInstanceIdentifier.NodeIdentifier> {
+
+        protected LeafNormalization(final LeafSchemaNode potential) {
+            super(new YangInstanceIdentifier.NodeIdentifier(potential.getQName()));
+        }
+
+        @Override
+        protected NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, Object, LeafNode<Object>> getBuilder(final YangInstanceIdentifier.PathArgument node) {
+            return Builders.leafBuilder().withNodeIdentifier(getIdentifier());
+        }
+    }
+
+    static final class LeafListEntryNormalization extends InstanceIdToSimpleNodes<YangInstanceIdentifier.NodeWithValue> {
+
+        public LeafListEntryNormalization(final LeafListSchemaNode potential) {
+            super(new YangInstanceIdentifier.NodeWithValue(potential.getQName(), null));
+        }
+
+        @Override
+        protected NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeWithValue, Object, LeafSetEntryNode<Object>> getBuilder(final YangInstanceIdentifier.PathArgument node) {
+            Preconditions.checkArgument(node instanceof YangInstanceIdentifier.NodeWithValue);
+            return Builders.leafSetEntryBuilder().withNodeIdentifier((YangInstanceIdentifier.NodeWithValue) node).withValue(((YangInstanceIdentifier.NodeWithValue) node).getValue());
+        }
+
+    }
+}
index 53bdbd84bc53550a6222e3559ef24c7615b327d9..a5c5148548418596d13c1ef26543aa89c527aff4 100644 (file)
@@ -18,10 +18,12 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
@@ -80,6 +82,19 @@ public final class SchemaUtils {
         return dataChildByName == null ? findSchemaForChild(schema, qname, schema.getChildNodes()) : dataChildByName;
     }
 
+    @Nullable
+    public static DataSchemaNode findSchemaForChild(final DataNodeContainer schema, final QName qname, final boolean strictMode) {
+        if (strictMode) {
+            return findSchemaForChild(schema, qname);
+        }
+
+        Optional<DataSchemaNode> childSchemaOptional = findFirstSchema(qname, schema.getChildNodes());
+        if (!childSchemaOptional.isPresent()) {
+            return null;
+        }
+        return childSchemaOptional.get();
+    }
+
     public static DataSchemaNode findSchemaForChild(final DataNodeContainer schema, final QName qname, final Iterable<DataSchemaNode> childNodes) {
         Optional<DataSchemaNode> childSchema = findFirstSchema(qname, childNodes);
         Preconditions.checkState(childSchema.isPresent(),
index 1742c03357aee94c4e503ee98f6c4f427822990e..f382586ef2d79e121c2b3d96810a528190a777c9 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 
 import com.google.common.base.MoreObjects.ToStringHelper;
 
+// FIXME: are attributes part of hashCode/equals?
 public abstract class AbstractImmutableDataContainerAttrNode<K extends YangInstanceIdentifier.PathArgument>
         extends AbstractImmutableDataContainerNode<K>
     implements AttributesContainer {
@@ -44,26 +45,4 @@ public abstract class AbstractImmutableDataContainerAttrNode<K extends YangInsta
         return super.addToStringAttributes(toStringHelper).add("attributes", attributes);
     }
 
-// FIXME: are attributes part of hashCode/equals?
-//    @Override
-//    protected int valueHashCode() {
-//        int result = super.valueHashCode();
-//        for (final Entry<?, ?> a : attributes.entrySet()) {
-//            result = 31 * result + a.hashCode();
-//        }
-//        return result;
-//    }
-
- // FIXME: are attributes part of hashCode/equals?
-//    @Override
-//    protected boolean valueEquals(final NormalizedNode<?, ?> other) {
-//        if (!super.valueEquals(other)) {
-//            return false;
-//        }
-//        final Set<Entry<QName, String>> tas = getAttributes().entrySet();
-//        final Set<Entry<QName, String>> oas = container.getAttributes().entrySet();
-//
-//        return tas.containsAll(oas) && oas.containsAll(tas);
-//        return true;
-//    }
 }
index ec615025ebd5def89fdadb5d04cdac283122cb48..842cf231f7126290ee13ff4e3c5ddf4ee7baa4dd 100644 (file)
@@ -43,10 +43,7 @@ public abstract class AbstractImmutableNormalizedValueAttrNode<K extends YangIns
     @Override
     protected int valueHashCode() {
         final int result = getValue() != null ? getValue().hashCode() : 1;
-// FIXME: are attributes part of hashCode/equals?
-//        for (final Entry<?, ?> a : attributes.entrySet()) {
-//            result = 31 * result + a.hashCode();
-//        }
+        // FIXME: are attributes part of hashCode/equals?
         return result;
     }
 
@@ -60,11 +57,6 @@ public abstract class AbstractImmutableNormalizedValueAttrNode<K extends YangIns
         }
 
         // FIXME: are attributes part of hashCode/equals?
-        // final Set<Entry<QName, String>> tas = getAttributes().entrySet();
-        // final Set<Entry<QName, String>> oas =
-        // container.getAttributes().entrySet();
-        //
-        // return tas.containsAll(oas) && oas.containsAll(tas);
         return true;
     }
 
index 83fdc123cd14fabfa88378ea829ceb283589892e..7c3938fe088d92bc3bb6076bfa039cb9720e8102 100644 (file)
@@ -41,7 +41,7 @@ public abstract class AugmentationNodeBaseParser<E> extends
 
     @Override
     protected final DataSchemaNode getSchemaForChild(final AugmentationSchema schema, final QName childQName) {
-        return SchemaUtils.findSchemaForChild(schema, childQName);
+        return SchemaUtils.findSchemaForChild(schema, childQName, strictParsing());
     }
 
     @Override
index fba872d2f7fc1d29049549447669b9c73a30a14f..a594e5d763a8dbe51c8a33fd03d808b97d605d97 100644 (file)
@@ -109,6 +109,10 @@ public abstract class BaseDispatcherParser<E, N extends DataContainerNode<?>, S>
         // process Child nodes
         for (QName childPartialQName : mappedChildElements.keySet()) {
             DataSchemaNode childSchema = getSchemaForChild(schema, childPartialQName);
+            //with strict parsing an exception would be already thrown, with nonstrict we want to ignore this node
+            if (childSchema == null) {
+                continue;
+            }
             List<E> childrenForQName = mappedChildElements.get(childPartialQName);
 
             // Augment
@@ -153,6 +157,10 @@ public abstract class BaseDispatcherParser<E, N extends DataContainerNode<?>, S>
         return Collections.emptyMap();
     }
 
+    protected boolean strictParsing() {
+        return true;
+    }
+
     private boolean isMarkedAs(final Map<QName, ?> mappedAugmentChildNodes, final QName qName) {
         return mappedAugmentChildNodes.containsKey(qName);
     }
index 5fff36d5499e48d0bb8a3026cf6217bc256756c8..f7cca88155f52cfe18a504ce8a5e4b0849ffef4b 100644 (file)
@@ -48,7 +48,7 @@ public abstract class ContainerNodeBaseParser<E> extends
 
     @Override
     protected final DataSchemaNode getSchemaForChild(final ContainerSchemaNode schema, final QName childQName) {
-        return SchemaUtils.findSchemaForChild(schema, childQName);
+        return SchemaUtils.findSchemaForChild(schema, childQName, strictParsing());
     }
 
     @Override
index c2ec9fc7e4ba08fc7aa2eb718934e5de11f5486a..dfa34abcc7d6881bb2ba696deb4c7e62202556c1 100644 (file)
@@ -34,7 +34,7 @@ public abstract class ListEntryNodeBaseParser<E, N extends DataContainerNode<?>>
 
     @Override
     protected final DataSchemaNode getSchemaForChild(final ListSchemaNode schema, final QName childQName) {
-        return SchemaUtils.findSchemaForChild(schema, childQName);
+        return SchemaUtils.findSchemaForChild(schema, childQName, strictParsing());
     }
 
     @Override
index 7a5b551578ba850d88b65212b83eebfe6a793edf..73167f407a522232c3c105311ef26c2e5c1b9055 100644 (file)
@@ -19,9 +19,16 @@ import com.google.common.collect.LinkedListMultimap;
 final class AugmentationNodeDomParser extends AugmentationNodeBaseParser<Element> {
 
     private final NodeParserDispatcher<Element> dispatcher;
+    private final boolean strictParsing;
 
     AugmentationNodeDomParser(final NodeParserDispatcher<Element> dispatcher) {
         this.dispatcher = Preconditions.checkNotNull(dispatcher);
+        this.strictParsing = super.strictParsing();
+    }
+
+    AugmentationNodeDomParser(final NodeParserDispatcher<Element> dispatcher, final boolean strictParsing) {
+        this.dispatcher = Preconditions.checkNotNull(dispatcher);
+        this.strictParsing = strictParsing;
     }
 
     @Override
@@ -34,4 +41,8 @@ final class AugmentationNodeDomParser extends AugmentationNodeBaseParser<Element
         return dispatcher;
     }
 
+    @Override
+    protected boolean strictParsing() {
+        return strictParsing;
+    }
 }
index c03113af22cd5cbeae7c30feff0aa655082ea3ba..ed4f2772ed453d83430deeac6525b871091583bc 100644 (file)
@@ -21,9 +21,16 @@ import com.google.common.collect.LinkedListMultimap;
 final class ContainerNodeDomParser extends ContainerNodeBaseParser<Element> {
 
     private final NodeParserDispatcher<Element> dispatcher;
+    private final boolean strictParsing;
 
     ContainerNodeDomParser(final NodeParserDispatcher<Element> dispatcher) {
         this.dispatcher = Preconditions.checkNotNull(dispatcher);
+        this.strictParsing = super.strictParsing();
+    }
+
+    ContainerNodeDomParser(final NodeParserDispatcher<Element> dispatcher, final boolean strictParsing) {
+        this.dispatcher = Preconditions.checkNotNull(dispatcher);
+        this.strictParsing = strictParsing;
     }
 
     @Override
@@ -40,4 +47,9 @@ final class ContainerNodeDomParser extends ContainerNodeBaseParser<Element> {
     protected LinkedListMultimap<QName, Element> mapChildElements(Iterable<Element> elements) {
         return DomUtils.mapChildElementsForSingletonNode(elements.iterator().next());
     }
+
+    @Override
+    protected boolean strictParsing() {
+        return this.strictParsing;
+    }
 }
index af58c481543eb5b0a459fb381605d484507721ac..8e6381748ef856c7963739b0caf01a164795d64b 100644 (file)
@@ -47,7 +47,7 @@ public final class DomToNormalizedNodeParserFactory implements ToNormalizedNodeP
     private final OrderedListNodeDomParser orderedListNodeParser;
     private final AnyXmlDomParser anyXmlNodeParser;
 
-    private DomToNormalizedNodeParserFactory(final XmlCodecProvider codecProvider, final SchemaContext schema) {
+    private DomToNormalizedNodeParserFactory(final XmlCodecProvider codecProvider, final SchemaContext schema, final boolean strictParsing) {
         leafNodeParser = new LeafNodeDomParser(codecProvider, schema);
         leafSetEntryNodeParser = new LeafSetEntryNodeDomParser(codecProvider, schema);
         leafSetNodeParser = new LeafSetNodeDomParser(leafSetEntryNodeParser);
@@ -57,14 +57,14 @@ public final class DomToNormalizedNodeParserFactory implements ToNormalizedNodeP
 
         };
 
-        containerNodeParser = new ContainerNodeDomParser(dispatcher);
-        mapEntryNodeParser = new MapEntryNodeDomParser(dispatcher);
+        containerNodeParser = new ContainerNodeDomParser(dispatcher, strictParsing);
+        mapEntryNodeParser = new MapEntryNodeDomParser(dispatcher, strictParsing);
         mapNodeParser = new MapNodeDomParser(mapEntryNodeParser);
         orderedListNodeParser = new OrderedListNodeDomParser(mapEntryNodeParser);
         unkeyedListEntryNodeParser = new UnkeyedListEntryNodeDomParser(dispatcher);
         unkeyedListNodeParser = new UnkeyedListNodeDomParser(unkeyedListEntryNodeParser);
         choiceNodeParser = new ChoiceNodeDomParser(dispatcher);
-        augmentationNodeParser = new AugmentationNodeDomParser(dispatcher);
+        augmentationNodeParser = new AugmentationNodeDomParser(dispatcher, strictParsing);
     }
 
     @Deprecated
@@ -88,8 +88,12 @@ public final class DomToNormalizedNodeParserFactory implements ToNormalizedNodeP
         augmentationNodeParser = new AugmentationNodeDomParser(dispatcher);
     }
 
+    public static DomToNormalizedNodeParserFactory getInstance(final XmlCodecProvider codecProvider, final SchemaContext schema, final boolean strictParsing) {
+        return new DomToNormalizedNodeParserFactory(codecProvider, schema, strictParsing);
+    }
+
     public static DomToNormalizedNodeParserFactory getInstance(final XmlCodecProvider codecProvider, final SchemaContext schema) {
-        return new DomToNormalizedNodeParserFactory(codecProvider, schema);
+        return new DomToNormalizedNodeParserFactory(codecProvider, schema, true);
     }
 
     @Deprecated
index 4d4d35aa7debb12ab7dc1fac204ba9c39a45238c..a6c467c22224159dcb4120bf84233752bb18f13a 100644 (file)
@@ -17,8 +17,16 @@ import org.w3c.dom.Element;
 
 final class MapEntryNodeDomParser extends ListEntryNodeDomParser<MapEntryNode> {
 
+    private final boolean strictParsing;
+
     MapEntryNodeDomParser(final NodeParserDispatcher<Element> dispatcher) {
         super(dispatcher);
+        this.strictParsing = super.strictParsing();
+    }
+
+    MapEntryNodeDomParser(final NodeParserDispatcher<Element> dispatcher, final boolean strictParsing) {
+        super(dispatcher);
+        this.strictParsing = strictParsing;
     }
 
     @Override
@@ -26,4 +34,9 @@ final class MapEntryNodeDomParser extends ListEntryNodeDomParser<MapEntryNode> {
             ListSchemaNode schema) {
         return Builders.mapEntryBuilder(schema);
     }
+
+    @Override
+    protected boolean strictParsing() {
+        return strictParsing;
+    }
 }
index b2b132d1369485d14f6585afdeaf7d2f1d46a96b..9b1ef2d2ef50148aacbf47488c95ae4f718fe0d0 100644 (file)
@@ -51,7 +51,7 @@ abstract class AbstractDataTreeTip implements DataTreeTip {
 
         final Optional<TreeNode> newRoot = m.getStrategy().apply(m.getRootModification(),
             Optional.<TreeNode>of(currentRoot), m.getVersion());
-        Preconditions.checkState(newRoot.isPresent(), "Apply strategy failed to produce root node");
+        Preconditions.checkState(newRoot.isPresent(), "Apply strategy failed to produce root node for modification %s", modification);
         return new InMemoryDataTreeCandidate(PUBLIC_ROOT_PATH, root, currentRoot, newRoot.get());
     }
 }
index e0e136545803a902dc643fce86284ffa88c8c2a9..2dda1b3f654fc38527d6849b674e6315f6540bad 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Iterables;
+import java.util.Collection;
 import java.util.Map.Entry;
 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -17,6 +18,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgum
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModificationCursor;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNodes;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
@@ -201,4 +203,49 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     Version getVersion() {
         return version;
     }
+
+    private static void applyChildren(final DataTreeModificationCursor cursor, final ModifiedNode node) {
+        final Collection<ModifiedNode> children = node.getChildren();
+        if (!children.isEmpty()) {
+            cursor.enter(node.getIdentifier());
+            for (ModifiedNode child : children) {
+                applyNode(cursor, child);
+            }
+            cursor.exit();
+        }
+    }
+
+    private static void applyNode(final DataTreeModificationCursor cursor, final ModifiedNode node) {
+        switch (node.getOperation()) {
+        case NONE:
+            break;
+        case DELETE:
+            cursor.delete(node.getIdentifier());
+            break;
+        case MERGE:
+            cursor.merge(node.getIdentifier(), node.getWrittenValue());
+            applyChildren(cursor, node);
+            break;
+        case TOUCH:
+            // TODO: we could improve efficiency of cursor use if we could understand
+            //       nested TOUCH operations. One way of achieving that would be a proxy
+            //       cursor, which would keep track of consecutive enter and exit calls
+            //       and coalesce them.
+            applyChildren(cursor, node);
+            break;
+        case WRITE:
+            cursor.write(node.getIdentifier(), node.getWrittenValue());
+            applyChildren(cursor, node);
+            break;
+        default:
+            throw new IllegalArgumentException("Unhandled node operation " + node.getOperation());
+        }
+    }
+
+    @Override
+    public void applyToCursor(final DataTreeModificationCursor cursor) {
+        for (ModifiedNode child : rootNode.getChildren()) {
+            applyNode(cursor, child);
+        }
+    }
 }
index ad2e60b379bb2ed4d283fce10cd0813a0f12fd77..b771bccadf616380fe98279648c54161d9a93bcb 100644 (file)
@@ -173,7 +173,7 @@ abstract class SchemaAwareApplyOperation extends ModificationApplyOperation {
         }
     }
 
-    private void checkDeleteApplicable(final NodeModification modification, final Optional<TreeNode> current) {
+    private static void checkDeleteApplicable(final NodeModification modification, final Optional<TreeNode> current) {
         // Delete is always applicable, we do not expose it to subclasses
         if (current.isPresent()) {
             LOG.trace("Delete operation turned to no-op on missing node {}", modification);
@@ -192,7 +192,7 @@ abstract class SchemaAwareApplyOperation extends ModificationApplyOperation {
             modification.resolveModificationType(ModificationType.DELETE);
             return modification.setSnapshot(Optional.<TreeNode> absent());
         case TOUCH:
-            Preconditions.checkArgument(currentMeta.isPresent(), "Metadata not available for modification",
+            Preconditions.checkArgument(currentMeta.isPresent(), "Metadata not available for modification %s",
                     modification);
             return modification.setSnapshot(Optional.of(applyTouch(modification, currentMeta.get(),
                     version)));
diff --git a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/DataTreeCandidateValidatorTest.java b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/DataTreeCandidateValidatorTest.java
new file mode 100644 (file)
index 0000000..2c2d563
--- /dev/null
@@ -0,0 +1,810 @@
+/**
+ * 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.impl.leafref.context.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import org.apache.log4j.BasicConfigurator;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+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.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefContext;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefDataValidationFailedException;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefValidatation;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefYangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DataTreeCandidateValidatorTest {
+
+    private static SchemaContext context;
+    private static Module valModule;
+    private static QNameModule valModuleQname;
+    private static LeafRefContext rootLeafRefContext;
+    public static TipProducingDataTree inMemoryDataTree;
+
+    private static QName odl;
+    private static QName project;
+    private static QName name;
+    private static QName desc;
+    private static QName lead;
+    private static QName owner;
+    private static QName odlContributor;
+    private static QName contributor;
+    private static QName odlProjectName;
+    private static QName odlProjectDesc;
+    private static QName login;
+    private static QName contributorName;
+    private static QName l1;
+    private static QName l2;
+    private static QName con1;
+    private static QName ch1;
+    private static QName ch2;
+    private static QName leafrefInChoice;
+    private static QName listInChoice;
+
+    private static QName leafrefInChoiceToChoice;
+    private static QName con3;
+    private static QName list3InChoice;
+    private static QName l3;
+    private static QName choiceInCon3;
+
+    private static QName listInChoiceKey;
+    private static QName k;
+
+    private static QName leafrefLeafList;
+
+    private static final Logger LOG = LoggerFactory.getLogger("");
+    private static final String NEW_LINE = System.getProperty("line.separator");
+
+    static {
+        BasicConfigurator.configure();
+    }
+
+    @BeforeClass
+    public static void init() throws URISyntaxException, IOException,
+            YangSyntaxErrorException, LeafRefYangSyntaxErrorException {
+        initSchemaContext();
+
+        initLeafRefContext();
+
+        initQnames();
+
+        initDataTree();
+
+    }
+
+    private static void initSchemaContext() throws URISyntaxException,
+            IOException, YangSyntaxErrorException {
+        final File resourceFile = new File(DataTreeCandidateValidatorTest.class
+                .getResource("/leafref-validation/leafref-validation.yang")
+                .toURI());
+        final File resourceDir = resourceFile.getParentFile();
+
+        final YangParserImpl parser = YangParserImpl.getInstance();
+        context = parser.parseFile(resourceFile, resourceDir);
+
+        final Set<Module> modules = context.getModules();
+        for (final Module module : modules) {
+            if (module.getName().equals("leafref-validation")) {
+                valModule = module;
+            }
+        }
+
+        valModuleQname = valModule.getQNameModule();
+    }
+
+    private static void initLeafRefContext() throws IOException,
+            LeafRefYangSyntaxErrorException {
+        rootLeafRefContext = LeafRefContext.create(context);
+    }
+
+    private static void initQnames() {
+        odl = QName.create(valModuleQname, "odl-project");
+        project = QName.create(valModuleQname, "project");
+        name = QName.create(valModuleQname, "name");
+        desc = QName.create(valModuleQname, "desc");
+        lead = QName.create(valModuleQname, "project-lead");
+        owner = QName.create(valModuleQname, "project-owner");
+
+        odlContributor = QName.create(valModuleQname, "odl-contributor");
+        contributor = QName.create(valModuleQname, "contributor");
+        odlProjectName = QName.create(valModuleQname, "odl-project-name");
+        login = QName.create(valModuleQname, "login");
+        contributorName = QName.create(valModuleQname, "contributor-name");
+
+        con1 = QName.create(valModuleQname, "con1");
+        l1 = QName.create(valModuleQname, "l1");
+        l2 = QName.create(valModuleQname, "l2");
+        odlProjectDesc = QName.create(valModuleQname, "odl-project-desc");
+
+        ch1 = QName.create(valModuleQname, "ch1");
+        ch2 = QName.create(valModuleQname, "ch2");
+        leafrefInChoice = QName.create(valModuleQname, "leafref-in-choice");
+        listInChoice = QName.create(valModuleQname, "list-in-choice");
+
+        leafrefInChoiceToChoice = QName.create(valModuleQname,
+                "leafref-in-choice-to-choice");
+        con3 = QName.create(valModuleQname, "con3");
+        list3InChoice = QName.create(valModuleQname, "list3-in-choice");
+        l3 = QName.create(valModuleQname, "l3");
+        choiceInCon3 = QName.create(valModuleQname, "choice-in-con3");
+
+        listInChoiceKey = QName.create(valModuleQname, "list-in-choice-key");
+        k = QName.create(valModuleQname, "k");
+
+        leafrefLeafList = QName.create(valModuleQname, "leafref-leaf-list");
+
+    }
+
+    private static void initDataTree() {
+        inMemoryDataTree = InMemoryDataTreeFactory.getInstance().create();
+        inMemoryDataTree.setSchemaContext(context);
+
+        final DataTreeModification initialDataTreeModification = inMemoryDataTree
+                .takeSnapshot().newModification();
+
+        final ContainerSchemaNode odlProjContSchemaNode = (ContainerSchemaNode) valModule
+                .getDataChildByName(odl);
+
+        final ContainerNode odlProjectContainer = createOdlContainer(odlProjContSchemaNode);
+
+        final YangInstanceIdentifier path = YangInstanceIdentifier.of(odl);
+        initialDataTreeModification.write(path, odlProjectContainer);
+
+        final DataTreeCandidate writeContributorsCandidate = inMemoryDataTree
+                .prepare(initialDataTreeModification);
+        inMemoryDataTree.commit(writeContributorsCandidate);
+
+    }
+
+    @Test
+    public void dataTreeCanditateValidationTest() {
+        write();
+
+        write2();
+
+        delete();
+
+        writeContributors();
+
+        writeMapEntry();
+
+        writeIntoMapEntry();
+    }
+
+    private void writeContributors() {
+
+        final ContainerSchemaNode contributorContSchemaNode = (ContainerSchemaNode) valModule
+                .getDataChildByName(odlContributor);
+
+        final ContainerNode contributorContainer = createBasicContributorContainer(contributorContSchemaNode);
+
+        final YangInstanceIdentifier contributorPath = YangInstanceIdentifier
+                .of(odlContributor);
+        final DataTreeModification writeModification = inMemoryDataTree
+                .takeSnapshot().newModification();
+        writeModification.write(contributorPath, contributorContainer);
+
+        final DataTreeCandidate writeContributorsCandidate = inMemoryDataTree
+                .prepare(writeModification);
+
+        LOG.debug("*************************");
+        LOG.debug("Before write of contributors: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+        boolean exception = false;
+        try {
+            LeafRefValidatation.validate(writeContributorsCandidate, rootLeafRefContext);
+        } catch (final LeafRefDataValidationFailedException e) {
+            LOG.debug("All validation errors:" + NEW_LINE + e.getMessage());
+            assertEquals(3, e.getValidationsErrorsCount());
+            exception = true;
+        }
+
+        inMemoryDataTree.commit(writeContributorsCandidate);
+
+        LOG.debug("*************************");
+        LOG.debug("After write of contributors: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+        assertTrue(exception);
+
+    }
+
+    private void writeIntoMapEntry() {
+
+        final Map<QName, Object> keys = new HashMap<QName, Object>();
+        keys.put(name, "New Project");
+        final NodeIdentifierWithPredicates mapEntryPath = new NodeIdentifierWithPredicates(
+                project, keys);
+
+        final YangInstanceIdentifier leaderPath = YangInstanceIdentifier.of(odl)
+                .node(project).node(mapEntryPath).node(lead);
+
+        final LeafNode<String> leader = ImmutableNodes.leafNode(lead,
+                "Updated leader");
+
+        final DataTreeModification writeModification = inMemoryDataTree
+                .takeSnapshot().newModification();
+        writeModification.write(leaderPath, leader);
+
+        final DataTreeCandidate writeContributorsCandidate = inMemoryDataTree
+                .prepare(writeModification);
+
+        LOG.debug("*************************");
+        LOG.debug("Before write into map entry (update of leader name): ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+        boolean exception = false;
+        try {
+            LeafRefValidatation.validate(writeContributorsCandidate, rootLeafRefContext);
+        } catch (final LeafRefDataValidationFailedException e) {
+            LOG.debug("All validation errors:" + NEW_LINE + e.getMessage());
+            assertEquals(1, e.getValidationsErrorsCount());
+            exception = true;
+        }
+
+        inMemoryDataTree.commit(writeContributorsCandidate);
+
+        LOG.debug("*************************");
+        LOG.debug("After write into map entry (update of leader name): ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+        assertTrue(exception);
+
+    }
+
+    private void writeMapEntry() {
+
+        final Map<QName, Object> keys = new HashMap<QName, Object>();
+        keys.put(name, "New Project");
+        final NodeIdentifierWithPredicates mapEntryPath = new NodeIdentifierWithPredicates(
+                project, keys);
+
+        final YangInstanceIdentifier newOdlProjectMapEntryPath = YangInstanceIdentifier
+                .of(odl).node(project).node(mapEntryPath);
+
+        final ContainerSchemaNode odlProjContSchemaNode = (ContainerSchemaNode) valModule
+                .getDataChildByName(odl);
+        final ListSchemaNode projListSchemaNode = (ListSchemaNode) odlProjContSchemaNode
+                .getDataChildByName(project);
+        final MapEntryNode newProjectMapEntry = createProjectListEntry("New Project",
+                "New Project description ...", "Leader of New Project",
+                "Owner of New Project", projListSchemaNode);
+
+        final DataTreeModification writeModification = inMemoryDataTree
+                .takeSnapshot().newModification();
+        writeModification.write(newOdlProjectMapEntryPath, newProjectMapEntry);
+
+        final DataTreeCandidate writeContributorsCandidate = inMemoryDataTree
+                .prepare(writeModification);
+
+        LOG.debug("*************************");
+        LOG.debug("Before map entry write: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+        boolean exception = false;
+        try {
+            LeafRefValidatation.validate(writeContributorsCandidate, rootLeafRefContext);
+        } catch (final LeafRefDataValidationFailedException e) {
+            LOG.debug("All validation errors:" + NEW_LINE + e.getMessage());
+            assertEquals(2, e.getValidationsErrorsCount());
+            exception = true;
+        }
+
+        inMemoryDataTree.commit(writeContributorsCandidate);
+
+        LOG.debug("*************************");
+        LOG.debug("After map entry write: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+        assertTrue(exception);
+
+    }
+
+    private void write() {
+
+        final ContainerSchemaNode contributorContSchemaNode = (ContainerSchemaNode) valModule
+                .getDataChildByName(odlContributor);
+
+        final ContainerNode contributorContainer = createContributorContainer(contributorContSchemaNode);
+
+        final YangInstanceIdentifier contributorPath = YangInstanceIdentifier
+                .of(odlContributor);
+        final DataTreeModification writeModification = inMemoryDataTree
+                .takeSnapshot().newModification();
+        writeModification.write(contributorPath, contributorContainer);
+
+        writeModification.write(YangInstanceIdentifier.of(l1),
+                ImmutableNodes.leafNode(l1, "Leafref l1 under the root"));
+        writeModification
+                .write(YangInstanceIdentifier.of(l2), ImmutableNodes.leafNode(
+                        l2, "Leafref target l2 under the root"));
+
+        final DataTreeCandidate writeContributorsCandidate = inMemoryDataTree
+                .prepare(writeModification);
+
+        LOG.debug("*************************");
+        LOG.debug("Before write: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+        boolean exception = false;
+        try {
+            LeafRefValidatation.validate(writeContributorsCandidate, rootLeafRefContext);
+        } catch (final LeafRefDataValidationFailedException e) {
+            LOG.debug("All validation errors:" + NEW_LINE + e.getMessage());
+            assertEquals(12, e.getValidationsErrorsCount());
+            exception = true;
+        }
+
+        inMemoryDataTree.commit(writeContributorsCandidate);
+
+        LOG.debug("*************************");
+        LOG.debug("After write: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+        assertTrue(exception);
+    }
+
+    private void write2() {
+
+        final ContainerSchemaNode odlCon = (ContainerSchemaNode) valModule
+                .getDataChildByName(odl);
+        final ContainerSchemaNode con1Con = (ContainerSchemaNode) odlCon
+                .getDataChildByName(con1);
+        final LeafNode<String> l1Leaf = ImmutableNodes.leafNode(l1, "l1 value");
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> containerBuilder = Builders
+                .containerBuilder(con1Con);
+        containerBuilder.addChild(l1Leaf);
+        final ContainerNode con1Node = containerBuilder.build();
+
+        final YangInstanceIdentifier con1Path = YangInstanceIdentifier.of(odl).node(
+                con1);
+        final DataTreeModification writeModification = inMemoryDataTree
+                .takeSnapshot().newModification();
+        writeModification.write(con1Path, con1Node);
+
+        final ChoiceNode choiceNode = createChoiceNode();
+        final YangInstanceIdentifier choicePath = YangInstanceIdentifier.of(odl)
+                .node(ch1);
+        writeModification.write(choicePath, choiceNode);
+
+        final ContainerNode con3Node = createCon3Node();
+        final YangInstanceIdentifier con3Path = YangInstanceIdentifier.of(odl).node(
+                con3);
+        writeModification.write(con3Path, con3Node);
+
+        final LeafSetNode leafListNode = createLeafRefLeafListNode();
+        final YangInstanceIdentifier leafListPath = YangInstanceIdentifier.of(odl)
+                .node(leafrefLeafList);
+        writeModification.write(leafListPath, leafListNode);
+
+        final DataTreeCandidate writeContributorsCandidate = inMemoryDataTree
+                .prepare(writeModification);
+
+        LOG.debug("*************************");
+        LOG.debug("Before write2: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+        boolean exception = false;
+        try {
+            LeafRefValidatation.validate(writeContributorsCandidate, rootLeafRefContext);
+        } catch (final LeafRefDataValidationFailedException e) {
+            LOG.debug("All validation errors:" + NEW_LINE + e.getMessage());
+            assertEquals(6, e.getValidationsErrorsCount());
+            exception = true;
+        }
+
+        assertTrue(exception);
+
+        inMemoryDataTree.commit(writeContributorsCandidate);
+
+        LOG.debug("*************************");
+        LOG.debug("After write2: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+    }
+
+    private LeafSetNode createLeafRefLeafListNode() {
+
+        final ListNodeBuilder<Object, LeafSetEntryNode<Object>> leafSetBuilder = Builders
+                .leafSetBuilder();
+        leafSetBuilder.withNodeIdentifier(new NodeIdentifier(leafrefLeafList));
+
+        leafSetBuilder.addChild(createLeafSetEntry(leafrefLeafList, "k1"));
+        leafSetBuilder.addChild(createLeafSetEntry(leafrefLeafList, "k2"));
+        leafSetBuilder.addChild(createLeafSetEntry(leafrefLeafList, "k3"));
+
+        return leafSetBuilder.build();
+    }
+
+    private ContainerNode createCon3Node() {
+
+        final CollectionNodeBuilder<MapEntryNode, MapNode> mapBuilder = Builders
+                .mapBuilder();
+        mapBuilder.withNodeIdentifier(new NodeIdentifier(list3InChoice));
+
+        mapBuilder.addChild(createList3Entry("k1", "val1", "valA", "valX"));
+        mapBuilder.addChild(createList3Entry("k2", "val2", "valB", "valY"));
+
+        final DataContainerNodeBuilder<NodeIdentifier, ChoiceNode> choiceBuilder = Builders
+                .choiceBuilder();
+        choiceBuilder.withNodeIdentifier(new NodeIdentifier(choiceInCon3));
+
+        choiceBuilder.addChild(mapBuilder.build());
+
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> containerBuilder = Builders
+                .containerBuilder();
+        containerBuilder.withNodeIdentifier(new NodeIdentifier(con3));
+
+        containerBuilder.addChild(choiceBuilder.build());
+
+        return containerBuilder.build();
+    }
+
+    private MapEntryNode createList3Entry(final String kVal, final String l3Val1,
+            final String l3Val2, final String l3Val3) {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder = Builders
+                .mapEntryBuilder();
+        mapEntryBuilder.withNodeIdentifier(new NodeIdentifierWithPredicates(
+                list3InChoice, k, kVal));
+
+        final ListNodeBuilder<Object, LeafSetEntryNode<Object>> leafSetBuilder = Builders
+                .leafSetBuilder();
+        leafSetBuilder.withNodeIdentifier(new NodeIdentifier(l3));
+
+        leafSetBuilder.addChild(createLeafSetEntry(l3, l3Val1));
+        leafSetBuilder.addChild(createLeafSetEntry(l3, l3Val2));
+        leafSetBuilder.addChild(createLeafSetEntry(l3, l3Val3));
+
+        mapEntryBuilder.addChild(ImmutableNodes.leafNode(k, kVal));
+        mapEntryBuilder.addChild(leafSetBuilder.build());
+
+        return mapEntryBuilder.build();
+    }
+
+    private LeafSetEntryNode<Object> createLeafSetEntry(final QName qname, final String val) {
+        final NormalizedNodeAttrBuilder<NodeWithValue, Object, LeafSetEntryNode<Object>> leafSetEntryBuilder = Builders
+                .leafSetEntryBuilder();
+        leafSetEntryBuilder.withNodeIdentifier(new NodeWithValue(qname, val));
+        leafSetEntryBuilder.withValue(val);
+        return leafSetEntryBuilder.build();
+    }
+
+    private ChoiceNode createChoiceNode() {
+
+        final CollectionNodeBuilder<MapEntryNode, MapNode> listInChoiceBuilder = Builders
+                .mapBuilder();
+        listInChoiceBuilder
+                .withNodeIdentifier(new NodeIdentifier(listInChoice));
+
+        listInChoiceBuilder.addChild(createListInChoiceEntry("key1",
+                "leafref-in-choice value", "val1"));
+        listInChoiceBuilder.addChild(createListInChoiceEntry("key2",
+                "l1 value", "val2"));
+        listInChoiceBuilder.addChild(createListInChoiceEntry("key3",
+                "l1 value", "val3"));
+
+        final DataContainerNodeBuilder<NodeIdentifier, ChoiceNode> choice2Builder = Builders
+                .choiceBuilder();
+        choice2Builder.withNodeIdentifier(new NodeIdentifier(ch2));
+
+        choice2Builder.addChild(listInChoiceBuilder.build());
+
+        final DataContainerNodeBuilder<NodeIdentifier, ChoiceNode> choiceBuilder = Builders
+                .choiceBuilder();
+        choiceBuilder.withNodeIdentifier(new NodeIdentifier(ch1));
+        choiceBuilder.addChild(choice2Builder.build());
+
+        return choiceBuilder.build();
+    }
+
+    private MapEntryNode createListInChoiceEntry(final String keyVal,
+            final String leafrefInChoiceVal, final String leafrefInChoiceToChoiceVal) {
+
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder = Builders
+                .mapEntryBuilder();
+
+        mapEntryBuilder.withNodeIdentifier(new NodeIdentifierWithPredicates(
+                listInChoice, listInChoiceKey, keyVal));
+
+        mapEntryBuilder.addChild(ImmutableNodes.leafNode(listInChoiceKey,
+                keyVal));
+        mapEntryBuilder.addChild(ImmutableNodes.leafNode(leafrefInChoice,
+                leafrefInChoiceVal));
+        mapEntryBuilder.addChild(ImmutableNodes.leafNode(
+                leafrefInChoiceToChoice, leafrefInChoiceToChoiceVal));
+
+        return mapEntryBuilder.build();
+    }
+
+    private void delete() {
+
+        final YangInstanceIdentifier contributorPath = YangInstanceIdentifier
+                .of(odlContributor);
+        final DataTreeModification delete = inMemoryDataTree.takeSnapshot()
+                .newModification();
+        delete.delete(contributorPath);
+
+        final DataTreeCandidate deleteContributorsCanditate = inMemoryDataTree
+                .prepare(delete);
+
+        LOG.debug("*************************");
+        LOG.debug("Before delete: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+        boolean exception = false;
+        try {
+            LeafRefValidatation.validate(deleteContributorsCanditate, rootLeafRefContext);
+        } catch (final LeafRefDataValidationFailedException e) {
+            LOG.debug("All validation errors:" + NEW_LINE + e.getMessage());
+            assertEquals(6, e.getValidationsErrorsCount());
+            exception = true;
+        }
+
+        assertTrue(exception);
+
+        inMemoryDataTree.commit(deleteContributorsCanditate);
+
+        LOG.debug("*************************");
+        LOG.debug("After delete: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+    }
+
+    private ContainerNode createContributorContainer(
+            final ContainerSchemaNode contributorContSchemaNode) {
+
+        final ListSchemaNode contributorListSchemaNode = (ListSchemaNode) contributorContSchemaNode
+                .getDataChildByName(contributor);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> contributorContainerBldr = Builders
+                .containerBuilder(contributorContSchemaNode);
+
+        final MapNode contributorMap = createContributorList(contributorListSchemaNode);
+        contributorContainerBldr.addChild(contributorMap);
+
+        final ContainerNode contributorContainer = contributorContainerBldr.build();
+
+        return contributorContainer;
+
+    }
+
+    private MapNode createContributorList(
+            final ListSchemaNode contributorListSchemaNode) {
+
+        final CollectionNodeBuilder<MapEntryNode, MapNode> contributorMapBldr = Builders
+                .mapBuilder(contributorListSchemaNode);
+
+        final MapEntryNode contributorMapEntry1 = createContributorListEntry(
+                "Leader of Yangtools", "Yangtools Leader name", "Yangtools",
+                "Yangtools description ...", contributorListSchemaNode);
+        final MapEntryNode contributorMapEntry2 = createContributorListEntry(
+                "Leader of MD-SAL", "MD-SAL Leader name", "MD-SAL",
+                "MD-SAL description ...", contributorListSchemaNode);
+        final MapEntryNode contributorMapEntry3 = createContributorListEntry(
+                "Leader of Controller", "Controller Leader name", "Controller",
+                "Controller description ...", contributorListSchemaNode);
+
+        final MapEntryNode contributorMapEntry4 = createContributorListEntry("jdoe",
+                "John Doe", "MD-SAL", "Yangtools description ...",
+                contributorListSchemaNode);
+
+        final MapEntryNode contributorMapEntry5 = createContributorListEntry("foo",
+                "foo name", "Controller", "MD-SAL description ...",
+                contributorListSchemaNode);
+
+        final MapEntryNode contributorMapEntry6 = createContributorListEntry("bar",
+                "bar name", "Yangtools", "Controller description ...",
+                contributorListSchemaNode);
+
+        final MapEntryNode contributorMapEntry7 = createContributorListEntry("baz",
+                "baz name", "Unknown Project",
+                "Unknown Project description ...", contributorListSchemaNode);
+
+        final MapEntryNode contributorMapEntry8 = createContributorListEntry("pk",
+                "pk name", "Unknown Project 2", "Controller description ...",
+                contributorListSchemaNode);
+
+        contributorMapBldr.addChild(contributorMapEntry1);
+        contributorMapBldr.addChild(contributorMapEntry2);
+        contributorMapBldr.addChild(contributorMapEntry3);
+        contributorMapBldr.addChild(contributorMapEntry4);
+        contributorMapBldr.addChild(contributorMapEntry5);
+        contributorMapBldr.addChild(contributorMapEntry6);
+        contributorMapBldr.addChild(contributorMapEntry7);
+        contributorMapBldr.addChild(contributorMapEntry8);
+
+        final MapNode contributorMap = contributorMapBldr.build();
+
+        return contributorMap;
+
+    }
+
+    private MapEntryNode createContributorListEntry(final String loginVal,
+            final String contributorNameVal, final String odlProjectNameVal,
+            final String odlProjectDescVal, final ListSchemaNode contributorListSchemaNode) {
+
+        final LeafNode<String> loginLeaf = ImmutableNodes.leafNode(login, loginVal);
+        final LeafNode<String> contributorNameLeaf = ImmutableNodes.leafNode(
+                contributorName, contributorNameVal);
+        final LeafNode<String> odlProjectNameLeafRef = ImmutableNodes.leafNode(
+                odlProjectName, odlProjectNameVal);
+        final LeafNode<String> odlProjectDescLeafRef = ImmutableNodes.leafNode(
+                odlProjectDesc, odlProjectDescVal);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> contributorMapEntryBldr = Builders
+                .mapEntryBuilder(contributorListSchemaNode);
+
+        contributorMapEntryBldr.addChild(loginLeaf);
+        contributorMapEntryBldr.addChild(contributorNameLeaf);
+        contributorMapEntryBldr.addChild(odlProjectNameLeafRef);
+        contributorMapEntryBldr.addChild(odlProjectDescLeafRef);
+
+        final MapEntryNode contributorMapEntry = contributorMapEntryBldr.build();
+
+        return contributorMapEntry;
+    }
+
+    private static ContainerNode createOdlContainer(
+            final ContainerSchemaNode container) {
+
+        final ListSchemaNode projListSchemaNode = (ListSchemaNode) container
+                .getDataChildByName(project);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> odlProjectContainerBldr = Builders
+                .containerBuilder(container);
+
+        final MapNode projectMap = createProjectList(projListSchemaNode);
+        odlProjectContainerBldr.addChild(projectMap);
+
+        final ContainerNode odlProjectContainer = odlProjectContainerBldr.build();
+
+        return odlProjectContainer;
+    }
+
+    private static MapNode createProjectList(final ListSchemaNode projListSchemaNode) {
+
+        final CollectionNodeBuilder<MapEntryNode, MapNode> projectMapBldr = Builders
+                .mapBuilder(projListSchemaNode);
+
+        final MapEntryNode projMapEntry1 = createProjectListEntry("Yangtools",
+                "Yangtools description ...", "Leader of Yangtools",
+                "Owner of Yangtools", projListSchemaNode);
+        final MapEntryNode projMapEntry2 = createProjectListEntry("MD-SAL",
+                "MD-SAL description ...", "Leader of MD-SAL",
+                "Owner of MD-SAL", projListSchemaNode);
+        final MapEntryNode projMapEntry3 = createProjectListEntry("Controller",
+                "Controller description ...", "Leader of Controller",
+                "Owner of Controller", projListSchemaNode);
+
+        projectMapBldr.addChild(projMapEntry1);
+        projectMapBldr.addChild(projMapEntry2);
+        projectMapBldr.addChild(projMapEntry3);
+
+        final MapNode projectMap = projectMapBldr.build();
+
+        return projectMap;
+    }
+
+    private static MapEntryNode createProjectListEntry(final String nameVal,
+            final String descVal, final String leadVal, final String ownerVal,
+            final ListSchemaNode projListSchemaNode) {
+
+        final LeafNode<String> nameLeaf = ImmutableNodes.leafNode(name, nameVal);
+        final LeafNode<String> descLeaf = ImmutableNodes.leafNode(desc, descVal);
+        final LeafNode<String> leadLeafRef = ImmutableNodes.leafNode(lead, leadVal);
+        final LeafNode<String> ownerLeafRef = ImmutableNodes
+                .leafNode(owner, ownerVal);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> projMapEntryBldr = Builders
+                .mapEntryBuilder(projListSchemaNode);
+
+        projMapEntryBldr.addChild(nameLeaf);
+        projMapEntryBldr.addChild(descLeaf);
+        projMapEntryBldr.addChild(leadLeafRef);
+        projMapEntryBldr.addChild(ownerLeafRef);
+        final MapEntryNode projMapEntry = projMapEntryBldr.build();
+
+        return projMapEntry;
+    }
+
+    private ContainerNode createBasicContributorContainer(
+            final ContainerSchemaNode contributorContSchemaNode) {
+
+        final ListSchemaNode contributorListSchemaNode = (ListSchemaNode) contributorContSchemaNode
+                .getDataChildByName(contributor);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> contributorContainerBldr = Builders
+                .containerBuilder(contributorContSchemaNode);
+
+        final MapNode contributorMap = createBasicContributorList(contributorListSchemaNode);
+        contributorContainerBldr.addChild(contributorMap);
+
+        final ContainerNode contributorContainer = contributorContainerBldr.build();
+
+        return contributorContainer;
+
+    }
+
+    private MapNode createBasicContributorList(
+            final ListSchemaNode contributorListSchemaNode) {
+
+        final CollectionNodeBuilder<MapEntryNode, MapNode> contributorMapBldr = Builders
+                .mapBuilder(contributorListSchemaNode);
+
+        final MapEntryNode contributorMapEntry1 = createContributorListEntry(
+                "Leader of Yangtools", "Yangtools Leader name", "Yangtools",
+                "Yangtools description ...", contributorListSchemaNode);
+        final MapEntryNode contributorMapEntry2 = createContributorListEntry(
+                "Leader of MD-SAL", "MD-SAL Leader name", "MD-SAL",
+                "MD-SAL description ...", contributorListSchemaNode);
+        final MapEntryNode contributorMapEntry3 = createContributorListEntry(
+                "Leader of Controller", "Controller Leader name", "Controller",
+                "Controller description ...", contributorListSchemaNode);
+
+        contributorMapBldr.addChild(contributorMapEntry1);
+        contributorMapBldr.addChild(contributorMapEntry2);
+        contributorMapBldr.addChild(contributorMapEntry3);
+
+        final MapNode contributorMap = contributorMapBldr.build();
+
+        return contributorMap;
+
+    }
+
+}
diff --git a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/DataTreeCandidateValidatorTest2.java b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/DataTreeCandidateValidatorTest2.java
new file mode 100644 (file)
index 0000000..f73c1d2
--- /dev/null
@@ -0,0 +1,359 @@
+/**
+ * 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.impl.leafref.context.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Set;
+import org.apache.log4j.BasicConfigurator;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+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.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefContext;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefDataValidationFailedException;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefValidatation;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefYangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DataTreeCandidateValidatorTest2 {
+
+    private static SchemaContext context;
+    private static Module mainModule;
+    private static QNameModule rootModuleQname;
+    private static LeafRefContext rootLeafRefContext;
+    public static TipProducingDataTree inMemoryDataTree;
+
+    private static QName chips;
+    private static QName chip;
+    private static QName devType;
+    private static QName chipDesc;
+
+    private static QName devices;
+    private static QName device;
+    private static QName typeChoice;
+    private static QName typeText;
+    private static QName devDesc;
+    private static QName sn;
+    private static QName defaultIp;
+
+    private static QName deviceTypeStr;
+    private static QName deviceType;
+    private static QName type;
+    private static QName desc;
+
+    private static final Logger LOG = LoggerFactory.getLogger("");
+    private static final String NEW_LINE = System.getProperty("line.separator");
+
+    static {
+        BasicConfigurator.configure();
+    }
+
+    @BeforeClass
+    public static void init() throws URISyntaxException, IOException,
+            YangSyntaxErrorException, LeafRefYangSyntaxErrorException {
+
+        initSchemaContext();
+        initLeafRefContext();
+        initQnames();
+        initDataTree();
+    }
+
+    @Test
+    public void dataTreeCanditateValidationTest2() {
+
+        writeDevices();
+    }
+
+    private static void writeDevices() {
+
+        final ContainerSchemaNode devicesContSchemaNode = (ContainerSchemaNode) mainModule
+                .getDataChildByName(devices);
+
+        final ContainerNode devicesContainer = createDevicesContainer(devicesContSchemaNode);
+
+        final YangInstanceIdentifier devicesPath = YangInstanceIdentifier.of(devices);
+        final DataTreeModification writeModification = inMemoryDataTree
+                .takeSnapshot().newModification();
+        writeModification.write(devicesPath, devicesContainer);
+
+        final DataTreeCandidate writeDevicesCandidate = inMemoryDataTree
+                .prepare(writeModification);
+
+        LOG.debug("*************************");
+        LOG.debug("Before writeDevices: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+        boolean exception = false;
+        try {
+            LeafRefValidatation.validate(writeDevicesCandidate, rootLeafRefContext);
+        } catch (final LeafRefDataValidationFailedException e) {
+            LOG.debug("All validation errors:" + NEW_LINE + e.getMessage());
+
+            assertEquals(4, e.getValidationsErrorsCount());
+            exception = true;
+        }
+
+        assertTrue(exception);
+
+        inMemoryDataTree.commit(writeDevicesCandidate);
+
+        LOG.debug("*************************");
+        LOG.debug("After write: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+    }
+
+    private static void initQnames() {
+
+        chips = QName.create(rootModuleQname, "chips");
+        chip = QName.create(rootModuleQname, "chip");
+        devType = QName.create(rootModuleQname, "dev_type");
+        chipDesc = QName.create(rootModuleQname, "chip_desc");
+
+        devices = QName.create(rootModuleQname, "devices");
+        device = QName.create(rootModuleQname, "device");
+        typeText = QName.create(rootModuleQname, "type_text");
+        devDesc = QName.create(rootModuleQname, "dev_desc");
+        sn = QName.create(rootModuleQname, "sn");
+        defaultIp = QName.create(rootModuleQname, "default_ip");
+
+        deviceTypeStr = QName.create(rootModuleQname, "device_types");
+        deviceType = QName.create(rootModuleQname, "device_type");
+        type = QName.create(rootModuleQname, "type");
+        desc = QName.create(rootModuleQname, "desc");
+    }
+
+    private static void initSchemaContext() throws URISyntaxException,
+            IOException, YangSyntaxErrorException {
+
+        final File resourceFile = new File(DataTreeCandidateValidatorTest.class
+                .getResource("/leafref-validation/leafref-validation2.yang")
+                .toURI());
+        final File resourceDir = resourceFile.getParentFile();
+
+        final YangParserImpl parser = YangParserImpl.getInstance();
+        context = parser.parseFile(resourceFile, resourceDir);
+
+        final Set<Module> modules = context.getModules();
+        for (final Module module : modules) {
+            if (module.getName().equals("leafref-validation2")) {
+                mainModule = module;
+            }
+        }
+
+        rootModuleQname = mainModule.getQNameModule();
+    }
+
+    private static void initDataTree() {
+
+        inMemoryDataTree = InMemoryDataTreeFactory.getInstance().create();
+        inMemoryDataTree.setSchemaContext(context);
+
+        final DataTreeModification initialDataTreeModification = inMemoryDataTree
+                .takeSnapshot().newModification();
+
+        final ContainerSchemaNode chipsListContSchemaNode = (ContainerSchemaNode) mainModule
+                .getDataChildByName(chips);
+        final ContainerNode chipsContainer = createChipsContainer(chipsListContSchemaNode);
+        final YangInstanceIdentifier path1 = YangInstanceIdentifier.of(chips);
+        initialDataTreeModification.write(path1, chipsContainer);
+
+        final ContainerSchemaNode devTypesListContSchemaNode = (ContainerSchemaNode) mainModule
+                .getDataChildByName(deviceTypeStr);
+        final ContainerNode deviceTypesContainer = createDevTypeStrContainer(devTypesListContSchemaNode);
+        final YangInstanceIdentifier path2 = YangInstanceIdentifier.of(deviceTypeStr);
+        initialDataTreeModification.write(path2, deviceTypesContainer);
+
+        final DataTreeCandidate writeChipsCandidate = inMemoryDataTree
+                .prepare(initialDataTreeModification);
+
+        inMemoryDataTree.commit(writeChipsCandidate);
+
+        System.out.println(inMemoryDataTree.toString());
+    }
+
+    private static void initLeafRefContext() throws IOException,
+            LeafRefYangSyntaxErrorException {
+        rootLeafRefContext = LeafRefContext.create(context);
+    }
+
+    private static ContainerNode createDevTypeStrContainer(
+            final ContainerSchemaNode container) {
+
+        final ListSchemaNode devTypeListSchemaNode = (ListSchemaNode) container
+                .getDataChildByName(deviceType);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> devTypeContainerBldr = Builders
+                .containerBuilder(container);
+
+        final MapNode devTypeMap = createDevTypeList(devTypeListSchemaNode);
+        devTypeContainerBldr.addChild(devTypeMap);
+
+        return devTypeContainerBldr.build();
+    }
+
+    private static MapNode createDevTypeList(
+            final ListSchemaNode devTypeListSchemaNode) {
+
+        final CollectionNodeBuilder<MapEntryNode, MapNode> devTypeMapBldr = Builders
+                .mapBuilder(devTypeListSchemaNode);
+
+        devTypeMapBldr.addChild(createDevTypeListEntry("dev_type_1",
+                "typedesc1", devTypeListSchemaNode));
+        devTypeMapBldr.addChild(createDevTypeListEntry("dev_type_2",
+                "typedesc2", devTypeListSchemaNode));
+        devTypeMapBldr.addChild(createDevTypeListEntry("dev_type_3",
+                "typedesc3", devTypeListSchemaNode));
+
+        return devTypeMapBldr.build();
+    }
+
+    private static MapEntryNode createDevTypeListEntry(final String typeVal,
+            final String descVal, final ListSchemaNode devTypeListSchemaNode) {
+
+        final LeafNode<String> typeLeaf = ImmutableNodes.leafNode(type, typeVal);
+        final LeafNode<String> descLeaf = ImmutableNodes.leafNode(desc, descVal);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> devTypeMapEntryBldr = Builders
+                .mapEntryBuilder(devTypeListSchemaNode);
+
+        devTypeMapEntryBldr.addChild(typeLeaf);
+        devTypeMapEntryBldr.addChild(descLeaf);
+
+        return devTypeMapEntryBldr.build();
+    }
+
+    private static ContainerNode createChipsContainer(
+            final ContainerSchemaNode container) {
+
+        final ListSchemaNode chipsListSchemaNode = (ListSchemaNode) container
+                .getDataChildByName(chip);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> chipsContainerBldr = Builders
+                .containerBuilder(container);
+
+        final MapNode chipsMap = createChipsList(chipsListSchemaNode);
+        chipsContainerBldr.addChild(chipsMap);
+
+        return chipsContainerBldr.build();
+    }
+
+    private static MapNode createChipsList(final ListSchemaNode chipsListSchemaNode) {
+
+        final CollectionNodeBuilder<MapEntryNode, MapNode> chipsMapBldr = Builders
+                .mapBuilder(chipsListSchemaNode);
+
+        chipsMapBldr.addChild(createChipsListEntry("dev_type_1", "desc1",
+                chipsListSchemaNode));
+        chipsMapBldr.addChild(createChipsListEntry("dev_type_2", "desc2",
+                chipsListSchemaNode));
+
+        return chipsMapBldr.build();
+    }
+
+    private static MapEntryNode createChipsListEntry(final String devTypeVal,
+            final String chipDescVal, final ListSchemaNode chipsListSchemaNode) {
+
+        final LeafNode<String> devTypeLeaf = ImmutableNodes.leafNode(devType,
+                devTypeVal);
+        final LeafNode<String> chipDescLeaf = ImmutableNodes.leafNode(chipDesc,
+                chipDescVal);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> chipsMapEntryBldr = Builders
+                .mapEntryBuilder(chipsListSchemaNode);
+
+        chipsMapEntryBldr.addChild(devTypeLeaf);
+        chipsMapEntryBldr.addChild(chipDescLeaf);
+
+        return chipsMapEntryBldr.build();
+    }
+
+    private static ContainerNode createDevicesContainer(
+            final ContainerSchemaNode container) {
+
+        final ListSchemaNode devicesListSchemaNode = (ListSchemaNode) container
+                .getDataChildByName(device);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> devicesContainerBldr = Builders
+                .containerBuilder(container);
+
+        final MapNode devicesMap = createDeviceList(devicesListSchemaNode);
+        devicesContainerBldr.addChild(devicesMap);
+
+        return devicesContainerBldr.build();
+    }
+
+    private static MapNode createDeviceList(final ListSchemaNode deviceListSchemaNode) {
+
+        final CollectionNodeBuilder<MapEntryNode, MapNode> devicesMapBldr = Builders
+                .mapBuilder(deviceListSchemaNode);
+
+        devicesMapBldr.addChild(createDeviceListEntry("dev_type_1",
+                "typedesc1", 123456, "192.168.0.1", deviceListSchemaNode));
+        devicesMapBldr.addChild(createDeviceListEntry("dev_type_2",
+                "typedesc2", 123457, "192.168.0.1", deviceListSchemaNode));
+        devicesMapBldr.addChild(createDeviceListEntry("dev_type_2",
+                "typedesc3", 123457, "192.168.0.1", deviceListSchemaNode));
+        devicesMapBldr.addChild(createDeviceListEntry("dev_type_1",
+                "typedesc2", 123458, "192.168.0.1", deviceListSchemaNode));
+        devicesMapBldr.addChild(createDeviceListEntry("unknown", "unknown",
+                123457, "192.168.0.1", deviceListSchemaNode));
+
+        return devicesMapBldr.build();
+    }
+
+    private static MapEntryNode createDeviceListEntry(final String typeTextVal,
+            final String descVal, final int snVal, final String defaultIpVal,
+            final ListSchemaNode devicesListSchemaNode) {
+
+        final LeafNode<String> typeTextLeaf = ImmutableNodes.leafNode(typeText,
+                typeTextVal);
+        final LeafNode<String> descLeaf = ImmutableNodes.leafNode(devDesc, descVal);
+        final LeafNode<Integer> snValLeaf = ImmutableNodes.leafNode(sn, snVal);
+        final LeafNode<String> defaultIpLeaf = ImmutableNodes.leafNode(defaultIp,
+                defaultIpVal);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> devicesMapEntryBldr = Builders
+                .mapEntryBuilder(devicesListSchemaNode);
+
+        devicesMapEntryBldr.addChild(typeTextLeaf);
+        devicesMapEntryBldr.addChild(descLeaf);
+        devicesMapEntryBldr.addChild(snValLeaf);
+        devicesMapEntryBldr.addChild(defaultIpLeaf);
+
+        return devicesMapEntryBldr.build();
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/DataTreeCandidateValidatorTest3.java b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/DataTreeCandidateValidatorTest3.java
new file mode 100644 (file)
index 0000000..e345354
--- /dev/null
@@ -0,0 +1,459 @@
+/**
+ * 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.impl.leafref.context.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Set;
+import org.apache.log4j.BasicConfigurator;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+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.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefContext;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefDataValidationFailedException;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefValidatation;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefYangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DataTreeCandidateValidatorTest3 {
+
+    private static SchemaContext context;
+    private static Module mainModule;
+    private static QNameModule rootModuleQname;
+    private static LeafRefContext rootLeafRefContext;
+    public static TipProducingDataTree inMemoryDataTree;
+
+    private static QName chips;
+    private static QName chip;
+    private static QName devType;
+    private static QName chipDesc;
+
+    private static QName devices;
+    private static QName device;
+    private static QName typeText1;
+    private static QName typeText2;
+    private static QName typeText3;
+    private static QName devDesc;
+    private static QName sn;
+    private static QName defaultIp;
+
+    private static QName deviceTypeStr;
+    private static QName deviceType;
+    private static QName type1;
+    private static QName type2;
+    private static QName type3;
+    private static QName desc;
+
+    private static final Logger LOG = LoggerFactory.getLogger("");
+    private static final String NEW_LINE = System.getProperty("line.separator");
+
+    static {
+        BasicConfigurator.configure();
+    }
+
+    @BeforeClass
+    public static void init() throws URISyntaxException, IOException,
+            YangSyntaxErrorException, LeafRefYangSyntaxErrorException {
+
+        initSchemaContext();
+        initLeafRefContext();
+        initQnames();
+        initDataTree();
+    }
+
+    @Test
+    public void dataTreeCanditateValidationTest2() {
+
+        writeDevices();
+
+        mergeDevices();
+    }
+
+    private static void writeDevices() {
+
+        final ContainerSchemaNode devicesContSchemaNode = (ContainerSchemaNode) mainModule
+                .getDataChildByName(devices);
+
+        final ContainerNode devicesContainer = createDevicesContainer(devicesContSchemaNode);
+
+        final YangInstanceIdentifier devicesPath = YangInstanceIdentifier.of(devices);
+        final DataTreeModification writeModification = inMemoryDataTree
+                .takeSnapshot().newModification();
+        writeModification.write(devicesPath, devicesContainer);
+
+        final DataTreeCandidate writeDevicesCandidate = inMemoryDataTree
+                .prepare(writeModification);
+
+        LOG.debug("*************************");
+        LOG.debug("Before writeDevices: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+        boolean exception = false;
+        try {
+            LeafRefValidatation.validate(writeDevicesCandidate, rootLeafRefContext);
+        } catch (final LeafRefDataValidationFailedException e) {
+            LOG.debug("All validation errors:" + NEW_LINE + e.getMessage());
+            assertEquals(6, e.getValidationsErrorsCount());
+            exception = true;
+        }
+
+        assertTrue(exception);
+
+        inMemoryDataTree.commit(writeDevicesCandidate);
+
+        LOG.debug("*************************");
+        LOG.debug("After writeDevices: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+    }
+
+    private static void mergeDevices() {
+
+        final ContainerSchemaNode devicesContSchemaNode = (ContainerSchemaNode) mainModule
+                .getDataChildByName(devices);
+
+        final ContainerNode devicesContainer = createDevices2Container(devicesContSchemaNode);
+
+        final YangInstanceIdentifier devicesPath = YangInstanceIdentifier.of(devices);
+        final DataTreeModification mergeModification = inMemoryDataTree
+                .takeSnapshot().newModification();
+        // mergeModification.write(devicesPath, devicesContainer);
+        mergeModification.merge(devicesPath, devicesContainer);
+
+        final DataTreeCandidate mergeDevicesCandidate = inMemoryDataTree
+                .prepare(mergeModification);
+
+        LOG.debug("*************************");
+        LOG.debug("Before mergeDevices: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+        boolean exception = false;
+        try {
+            LeafRefValidatation.validate(mergeDevicesCandidate, rootLeafRefContext);
+        } catch (final LeafRefDataValidationFailedException e) {
+            LOG.debug("All validation errors:" + NEW_LINE + e.getMessage());
+            // :TODO verify errors count gz
+            assertEquals(6, e.getValidationsErrorsCount());
+            exception = true;
+        }
+
+        inMemoryDataTree.commit(mergeDevicesCandidate);
+
+        LOG.debug("*************************");
+        LOG.debug("After mergeDevices: ");
+        LOG.debug("*************************");
+        LOG.debug(inMemoryDataTree.toString());
+
+        assertTrue(exception);
+    }
+
+    private static void initQnames() {
+
+        chips = QName.create(rootModuleQname, "chips");
+        chip = QName.create(rootModuleQname, "chip");
+        devType = QName.create(rootModuleQname, "dev_type");
+        chipDesc = QName.create(rootModuleQname, "chip_desc");
+
+        devices = QName.create(rootModuleQname, "devices");
+        device = QName.create(rootModuleQname, "device");
+        typeText1 = QName.create(rootModuleQname, "type_text1");
+        typeText2 = QName.create(rootModuleQname, "type_text2");
+        typeText3 = QName.create(rootModuleQname, "type_text3");
+        devDesc = QName.create(rootModuleQname, "dev_desc");
+        sn = QName.create(rootModuleQname, "sn");
+        defaultIp = QName.create(rootModuleQname, "default_ip");
+
+        deviceTypeStr = QName.create(rootModuleQname, "device_types");
+        deviceType = QName.create(rootModuleQname, "device_type");
+        type1 = QName.create(rootModuleQname, "type1");
+        type2 = QName.create(rootModuleQname, "type2");
+        type3 = QName.create(rootModuleQname, "type3");
+        desc = QName.create(rootModuleQname, "desc");
+    }
+
+    private static void initSchemaContext() throws URISyntaxException,
+            IOException, YangSyntaxErrorException {
+
+        final File resourceFile = new File(DataTreeCandidateValidatorTest.class
+                .getResource("/leafref-validation/leafref-validation3.yang")
+                .toURI());
+        final File resourceDir = resourceFile.getParentFile();
+
+        final YangParserImpl parser = YangParserImpl.getInstance();
+        context = parser.parseFile(resourceFile, resourceDir);
+
+        final Set<Module> modules = context.getModules();
+        for (final Module module : modules) {
+            if (module.getName().equals("leafref-validation3")) {
+                mainModule = module;
+            }
+        }
+
+        rootModuleQname = mainModule.getQNameModule();
+    }
+
+    private static void initDataTree() {
+
+        inMemoryDataTree = InMemoryDataTreeFactory.getInstance().create();
+        inMemoryDataTree.setSchemaContext(context);
+
+        final DataTreeModification initialDataTreeModification = inMemoryDataTree
+                .takeSnapshot().newModification();
+
+        final ContainerSchemaNode chipsListContSchemaNode = (ContainerSchemaNode) mainModule
+                .getDataChildByName(chips);
+        final ContainerNode chipsContainer = createChipsContainer(chipsListContSchemaNode);
+        final YangInstanceIdentifier path1 = YangInstanceIdentifier.of(chips);
+        initialDataTreeModification.write(path1, chipsContainer);
+
+        final ContainerSchemaNode devTypesListContSchemaNode = (ContainerSchemaNode) mainModule
+                .getDataChildByName(deviceTypeStr);
+        final ContainerNode deviceTypesContainer = createDevTypeStrContainer(devTypesListContSchemaNode);
+        final YangInstanceIdentifier path2 = YangInstanceIdentifier.of(deviceTypeStr);
+        initialDataTreeModification.write(path2, deviceTypesContainer);
+
+        final DataTreeCandidate writeChipsCandidate = inMemoryDataTree
+                .prepare(initialDataTreeModification);
+
+        inMemoryDataTree.commit(writeChipsCandidate);
+
+        System.out.println(inMemoryDataTree.toString());
+    }
+
+    private static void initLeafRefContext() throws IOException,
+            LeafRefYangSyntaxErrorException {
+        rootLeafRefContext = LeafRefContext.create(context);
+    }
+
+    private static ContainerNode createDevTypeStrContainer(
+            final ContainerSchemaNode container) {
+
+        final ListSchemaNode devTypeListSchemaNode = (ListSchemaNode) container
+                .getDataChildByName(deviceType);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> devTypeContainerBldr = Builders
+                .containerBuilder(container);
+
+        final MapNode devTypeMap = createDevTypeList(devTypeListSchemaNode);
+        devTypeContainerBldr.addChild(devTypeMap);
+
+        return devTypeContainerBldr.build();
+    }
+
+    private static MapNode createDevTypeList(
+            final ListSchemaNode devTypeListSchemaNode) {
+
+        final CollectionNodeBuilder<MapEntryNode, MapNode> devTypeMapBldr = Builders
+                .mapBuilder(devTypeListSchemaNode);
+
+        devTypeMapBldr.addChild(createDevTypeListEntry("dev_type1_1",
+                "dev_type2_1", "dev_type3_1", "typedesc1",
+                devTypeListSchemaNode));
+        devTypeMapBldr.addChild(createDevTypeListEntry("dev_type1_2",
+                "dev_type2_2", "dev_type3_2", "typedesc2",
+                devTypeListSchemaNode));
+        devTypeMapBldr.addChild(createDevTypeListEntry("dev_type1_3",
+                "dev_type2_3", "dev_type3_3", "typedesc3",
+                devTypeListSchemaNode));
+
+        return devTypeMapBldr.build();
+    }
+
+    private static MapEntryNode createDevTypeListEntry(final String type1Val,
+            final String type2Val, final String type3Val, final String descVal,
+            final ListSchemaNode devTypeListSchemaNode) {
+
+        final LeafNode<String> type1Leaf = ImmutableNodes.leafNode(type1, type1Val);
+        final LeafNode<String> type2Leaf = ImmutableNodes.leafNode(type2, type2Val);
+        final LeafNode<String> type3Leaf = ImmutableNodes.leafNode(type3, type3Val);
+        final LeafNode<String> descLeaf = ImmutableNodes.leafNode(desc, descVal);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> devTypeMapEntryBldr = Builders
+                .mapEntryBuilder(devTypeListSchemaNode);
+
+        devTypeMapEntryBldr.addChild(type1Leaf);
+        devTypeMapEntryBldr.addChild(type2Leaf);
+        devTypeMapEntryBldr.addChild(type3Leaf);
+        devTypeMapEntryBldr.addChild(descLeaf);
+
+        return devTypeMapEntryBldr.build();
+    }
+
+    private static ContainerNode createChipsContainer(
+            final ContainerSchemaNode container) {
+
+        final ListSchemaNode chipsListSchemaNode = (ListSchemaNode) container
+                .getDataChildByName(chip);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> chipsContainerBldr = Builders
+                .containerBuilder(container);
+
+        final MapNode chipsMap = createChipsList(chipsListSchemaNode);
+        chipsContainerBldr.addChild(chipsMap);
+
+        return chipsContainerBldr.build();
+    }
+
+    private static MapNode createChipsList(final ListSchemaNode chipsListSchemaNode) {
+
+        final CollectionNodeBuilder<MapEntryNode, MapNode> chipsMapBldr = Builders
+                .mapBuilder(chipsListSchemaNode);
+
+        chipsMapBldr.addChild(createChipsListEntry("dev_type_1", "desc1",
+                chipsListSchemaNode));
+        chipsMapBldr.addChild(createChipsListEntry("dev_type_2", "desc2",
+                chipsListSchemaNode));
+
+        return chipsMapBldr.build();
+    }
+
+    private static MapEntryNode createChipsListEntry(final String devTypeVal,
+            final String chipDescVal, final ListSchemaNode chipsListSchemaNode) {
+
+        final LeafNode<String> devTypeLeaf = ImmutableNodes.leafNode(devType,
+                devTypeVal);
+        final LeafNode<String> chipDescLeaf = ImmutableNodes.leafNode(chipDesc,
+                chipDescVal);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> chipsMapEntryBldr = Builders
+                .mapEntryBuilder(chipsListSchemaNode);
+
+        chipsMapEntryBldr.addChild(devTypeLeaf);
+        chipsMapEntryBldr.addChild(chipDescLeaf);
+
+        return chipsMapEntryBldr.build();
+    }
+
+    private static ContainerNode createDevicesContainer(
+            final ContainerSchemaNode container) {
+
+        final ListSchemaNode devicesListSchemaNode = (ListSchemaNode) container
+                .getDataChildByName(device);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> devicesContainerBldr = Builders
+                .containerBuilder(container);
+
+        final MapNode devicesMap = createDeviceList(devicesListSchemaNode);
+        devicesContainerBldr.addChild(devicesMap);
+
+        return devicesContainerBldr.build();
+    }
+
+    private static MapNode createDeviceList(final ListSchemaNode deviceListSchemaNode) {
+
+        final CollectionNodeBuilder<MapEntryNode, MapNode> devicesMapBldr = Builders
+                .mapBuilder(deviceListSchemaNode);
+
+        devicesMapBldr.addChild(createDeviceListEntry("dev_type1_1",
+                "dev_type2_1", "dev_type3_1", "typedesc1", 123456,
+                "192.168.0.1", deviceListSchemaNode));
+        devicesMapBldr.addChild(createDeviceListEntry("dev_type1_2",
+                "dev_type2_2", "dev_type3_2", "typedesc1", 123457,
+                "192.168.0.1", deviceListSchemaNode));
+        devicesMapBldr.addChild(createDeviceListEntry("dev_type1_1",
+                "dev_type2_2", "dev_type3_3", "typedesc2", 123458,
+                "192.168.0.1", deviceListSchemaNode));
+        devicesMapBldr.addChild(createDeviceListEntry("unk11", "unk22",
+                "unk33", "unk_desc2", 123457, "192.168.0.1",
+                deviceListSchemaNode));
+
+        return devicesMapBldr.build();
+    }
+
+    private static ContainerNode createDevices2Container(
+            final ContainerSchemaNode container) {
+
+        final ListSchemaNode devicesListSchemaNode = (ListSchemaNode) container
+                .getDataChildByName(device);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> devicesContainerBldr = Builders
+                .containerBuilder(container);
+
+        final MapNode devicesMap = createDevice2List(devicesListSchemaNode);
+        devicesContainerBldr.addChild(devicesMap);
+
+        return devicesContainerBldr.build();
+    }
+
+    private static MapNode createDevice2List(final ListSchemaNode deviceListSchemaNode) {
+
+        final CollectionNodeBuilder<MapEntryNode, MapNode> devicesMapBldr = Builders
+                .mapBuilder(deviceListSchemaNode);
+
+        devicesMapBldr.addChild(createDeviceListEntry("dev_type1_3",
+                "dev_type2_3", "dev_type3_3", "typedesc3", 123459,
+                "192.168.0.1", deviceListSchemaNode));
+        devicesMapBldr.addChild(createDeviceListEntry("dev_type1_3",
+                "dev_type2_3", "dev_type3_3", "typedesc2", 123460,
+                "192.168.0.1", deviceListSchemaNode));
+        devicesMapBldr.addChild(createDeviceListEntry("dev_type1_3",
+                "dev_type2_2", "dev_type3_1", "typedesc1", 123461,
+                "192.168.0.1", deviceListSchemaNode));
+        devicesMapBldr.addChild(createDeviceListEntry("unk1", "unk2", "unk3",
+                "unk_desc", 123462, "192.168.0.1", deviceListSchemaNode));
+
+        return devicesMapBldr.build();
+    }
+
+    private static MapEntryNode createDeviceListEntry(final String type1TextVal,
+            final String type2TextVal, final String type3TextVal, final String descVal,
+            final int snVal, final String defaultIpVal, final ListSchemaNode devicesListSchemaNode) {
+
+        final LeafNode<String> typeText1Leaf = ImmutableNodes.leafNode(typeText1,
+                type1TextVal);
+        final LeafNode<String> typeText2Leaf = ImmutableNodes.leafNode(typeText2,
+                type2TextVal);
+        final LeafNode<String> typeText3Leaf = ImmutableNodes.leafNode(typeText3,
+                type3TextVal);
+        final LeafNode<String> descLeaf = ImmutableNodes.leafNode(devDesc, descVal);
+        final LeafNode<Integer> snValLeaf = ImmutableNodes.leafNode(sn, snVal);
+        final LeafNode<String> defaultIpLeaf = ImmutableNodes.leafNode(defaultIp,
+                defaultIpVal);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> devicesMapEntryBldr = Builders
+                .mapEntryBuilder(devicesListSchemaNode);
+
+        devicesMapEntryBldr.addChild(typeText1Leaf);
+        devicesMapEntryBldr.addChild(typeText2Leaf);
+        devicesMapEntryBldr.addChild(typeText3Leaf);
+        devicesMapEntryBldr.addChild(descLeaf);
+        devicesMapEntryBldr.addChild(snValLeaf);
+        devicesMapEntryBldr.addChild(defaultIpLeaf);
+
+        return devicesMapEntryBldr.build();
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/LeafRefContextTest.java b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/LeafRefContextTest.java
new file mode 100644 (file)
index 0000000..eb3143d
--- /dev/null
@@ -0,0 +1,112 @@
+/**
+ * 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.impl.leafref.context.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Map;
+import java.util.Set;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefContext;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefContextUtils;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefYangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+public class LeafRefContextTest {
+
+    private static SchemaContext context;
+    private static Module rootMod;
+    private static QNameModule root;
+    private static LeafRefContext rootLeafRefContext;
+
+    @BeforeClass
+    public static void init() throws URISyntaxException, IOException,
+            YangSyntaxErrorException, LeafRefYangSyntaxErrorException {
+
+        final File resourceFile = new File(
+                LeafRefContextTreeBuilderTest.class
+                        .getResource(
+                                "/leafref-context-test/correct-modules/leafref-test2.yang")
+                        .toURI());
+
+        final File resourceDir = resourceFile.getParentFile();
+
+        final YangParserImpl parser = YangParserImpl.getInstance();
+        context = parser.parseFile(resourceFile, resourceDir);
+
+        final Set<Module> modules = context.getModules();
+        for (final Module module : modules) {
+            if (module.getName().equals("leafref-test2")) {
+                rootMod = module;
+            }
+        }
+
+        root = rootMod.getQNameModule();
+        rootLeafRefContext = LeafRefContext.create(context);
+    }
+
+    @Test
+    public void test() {
+
+        final QName q1 = QName.create(root, "ref1");
+        final QName q2 = QName.create(root, "leaf1");
+        final QName q3 = QName.create(root, "cont1");
+        final QName q4 = QName.create(root, "cont2");
+        final QName q5 = QName.create(root, "list1");
+        final QName q6 = QName.create(root, "name");
+
+        final DataSchemaNode leafRefNode = rootMod.getDataChildByName(q1);
+        final DataSchemaNode targetNode = rootMod.getDataChildByName(q2);
+        final DataSchemaNode cont1Node = rootMod.getDataChildByName(q3);
+        final DataSchemaNode cont2Node = rootMod.getDataChildByName(q4);
+        final DataSchemaNode name1Node = ((DataNodeContainer) ((DataNodeContainer) rootMod
+                .getDataChildByName(q3)).getDataChildByName(q5))
+                .getDataChildByName(q6);
+
+        assertTrue(LeafRefContextUtils.isLeafRef(leafRefNode,
+                rootLeafRefContext));
+        assertFalse(LeafRefContextUtils.isLeafRef(targetNode,
+                rootLeafRefContext));
+
+        assertTrue(LeafRefContextUtils.hasLeafRefChild(cont1Node,
+                rootLeafRefContext));
+        assertFalse(LeafRefContextUtils.hasLeafRefChild(leafRefNode,
+                rootLeafRefContext));
+
+        assertTrue(LeafRefContextUtils.isReferencedByLeafRef(targetNode,
+                rootLeafRefContext));
+        assertFalse(LeafRefContextUtils.isReferencedByLeafRef(leafRefNode,
+                rootLeafRefContext));
+
+        assertTrue(LeafRefContextUtils.hasChildReferencedByLeafRef(cont2Node,
+                rootLeafRefContext));
+        assertFalse(LeafRefContextUtils.hasChildReferencedByLeafRef(
+                leafRefNode, rootLeafRefContext));
+
+        Map<QName, LeafRefContext> leafRefs = LeafRefContextUtils
+                .getAllLeafRefsReferencingThisNode(name1Node,
+                        rootLeafRefContext);
+        assertEquals(4, leafRefs.size());
+        leafRefs = LeafRefContextUtils.getAllLeafRefsReferencingThisNode(
+                leafRefNode, rootLeafRefContext);
+        assertTrue(leafRefs.isEmpty());
+    }
+}
diff --git a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/LeafRefContextTreeBuilderTest.java b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/leafref/context/test/LeafRefContextTreeBuilderTest.java
new file mode 100644 (file)
index 0000000..110f246
--- /dev/null
@@ -0,0 +1,281 @@
+/**
+ * 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.impl.leafref.context.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Set;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefContext;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefContextUtils;
+import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefYangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+public class LeafRefContextTreeBuilderTest {
+
+    private static SchemaContext context;
+    private static Module impMod;
+    private static Module tstMod;
+    private static QNameModule imp;
+    private static QNameModule tst;
+    private static LeafRefContext rootLeafRefContext;
+
+    @BeforeClass
+    public static void init() throws URISyntaxException, IOException,
+            YangSyntaxErrorException, LeafRefYangSyntaxErrorException {
+        final File resourceFile = new File(
+                LeafRefContextTreeBuilderTest.class
+                        .getResource(
+                                "/leafref-context-test/correct-modules/leafref-test.yang")
+                        .toURI());
+        final File resourceDir = resourceFile.getParentFile();
+
+        final YangParserImpl parser = YangParserImpl.getInstance();
+        context = parser.parseFile(resourceFile, resourceDir);
+
+        final Set<Module> modules = context.getModules();
+        for (final Module module : modules) {
+            if (module.getName().equals("import-mod")) {
+                impMod = module;
+            }
+            if (module.getName().equals("leafref-test")) {
+                tstMod = module;
+            }
+        }
+
+        imp = impMod.getQNameModule();
+        tst = tstMod.getQNameModule();
+
+        rootLeafRefContext = LeafRefContext.create(context);
+    }
+
+    @Test
+    public void buildLeafRefContextTreeTest1() {
+
+        final QName q1 = QName.create(tst, "odl-project");
+        final QName q2 = QName.create(tst, "project");
+        final QName q3 = QName.create(tst, "project-lead");
+
+        final LeafRefContext leafRefCtx = rootLeafRefContext
+                .getReferencingChildByName(q1).getReferencingChildByName(q2)
+                .getReferencingChildByName(q3);
+
+        assertTrue(leafRefCtx.isReferencing());
+        assertNotNull(leafRefCtx.getLeafRefTargetPath());
+        assertFalse(leafRefCtx.getLeafRefTargetPath().isAbsolute());
+        assertNotNull(leafRefCtx.getAbsoluteLeafRefTargetPath());
+        assertTrue(leafRefCtx.getAbsoluteLeafRefTargetPath().isAbsolute());
+
+        System.out.println();
+        System.out.println("******* Test 1 ************");
+        System.out.println("Original definition string:");
+        System.out.println(leafRefCtx.getLeafRefTargetPathString());
+        System.out.println("Parsed leafref path:");
+        System.out.println(leafRefCtx.getLeafRefTargetPath().toString());
+        System.out.println("Absolute leafref path:");
+        System.out
+                .println(leafRefCtx.getAbsoluteLeafRefTargetPath().toString());
+    }
+
+    @Test
+    public void buildLeafRefContextTreeTest2() {
+
+        final QName q1 = QName.create(tst, "odl-project");
+        final QName q2 = QName.create(tst, "project");
+        final QName q4 = QName.create(tst, "project-lead2");
+
+        final LeafRefContext leafRefCtx2 = rootLeafRefContext
+                .getReferencingChildByName(q1).getReferencingChildByName(q2)
+                .getReferencingChildByName(q4);
+
+        assertTrue(leafRefCtx2.isReferencing());
+        assertNotNull(leafRefCtx2.getLeafRefTargetPath());
+        assertTrue(leafRefCtx2.getLeafRefTargetPath().isAbsolute());
+        assertNotNull(leafRefCtx2.getAbsoluteLeafRefTargetPath());
+        assertTrue(leafRefCtx2.getAbsoluteLeafRefTargetPath().isAbsolute());
+
+        System.out.println();
+        System.out.println("******* Test 2 ************");
+        System.out.println("Original definition string2:");
+        System.out.println(leafRefCtx2.getLeafRefTargetPathString());
+        System.out.println("Parsed leafref path2:");
+        System.out.println(leafRefCtx2.getLeafRefTargetPath().toString());
+        System.out.println("Absolute leafref path2:");
+        System.out.println(leafRefCtx2.getAbsoluteLeafRefTargetPath()
+                .toString());
+        System.out.println();
+
+    }
+
+    @Test
+    public void buildLeafRefContextTreeXPathTest() {
+        final QName q1 = QName.create(tst, "odl-project");
+        final QName q2 = QName.create(tst, "project");
+        final QName q5 = QName.create(tst, "ch1");
+        final QName q6 = QName.create(tst, "c1");
+        final QName q7 = QName.create(tst, "ch2");
+        final QName q8 = QName.create(tst, "l1");
+        final LeafRefContext leafRefCtx3 = rootLeafRefContext
+                .getReferencingChildByName(q1).getReferencingChildByName(q2)
+                .getReferencingChildByName(q5).getReferencingChildByName(q6)
+                .getReferencingChildByName(q7).getReferencingChildByName(q6)
+                .getReferencingChildByName(q8);
+
+        assertTrue(leafRefCtx3.isReferencing());
+        assertNotNull(leafRefCtx3.getLeafRefTargetPath());
+        assertFalse(leafRefCtx3.getLeafRefTargetPath().isAbsolute());
+        assertNotNull(leafRefCtx3.getAbsoluteLeafRefTargetPath());
+        assertTrue(leafRefCtx3.getAbsoluteLeafRefTargetPath().isAbsolute());
+
+        System.out.println();
+        System.out.println("******* Test 3 ************");
+        System.out.println("Original definition string2:");
+        System.out.println(leafRefCtx3.getLeafRefTargetPathString());
+        System.out.println("Parsed leafref path2:");
+        System.out.println(leafRefCtx3.getLeafRefTargetPath().toString());
+        System.out.println("Absolute leafref path2:");
+        System.out.println(leafRefCtx3.getAbsoluteLeafRefTargetPath()
+                .toString());
+        System.out.println();
+    }
+
+    @Test
+    public void buildLeafRefContextTreeTest4() {
+        final QName q9 = QName.create(tst, "odl-project");
+        final QName q10 = QName.create(tst, "project");
+        final QName q11 = QName.create(tst, "name");
+
+        final LeafRefContext leafRefCtx4 = rootLeafRefContext
+                .getReferencedChildByName(q9).getReferencedChildByName(q10)
+                .getReferencedChildByName(q11);
+
+        assertNotNull(leafRefCtx4);
+        assertTrue(leafRefCtx4.isReferenced());
+        assertEquals(6, leafRefCtx4.getAllReferencedByLeafRefCtxs().size());
+
+    }
+
+    @Test
+    public void leafRefContextUtilsTest() {
+        final QName q1 = QName.create(tst, "odl-contributor");
+        final QName q2 = QName.create(tst, "contributor");
+        final QName q3 = QName.create(tst, "odl-project-name");
+
+        final LeafRefContext odlContrProjNameCtx = rootLeafRefContext
+                .getReferencingChildByName(q1).getReferencingChildByName(q2)
+                .getReferencingChildByName(q3);
+
+        final DataSchemaNode odlContrProjNameNode = ((DataNodeContainer) ((DataNodeContainer) tstMod
+                .getDataChildByName(q1)).getDataChildByName(q2))
+                .getDataChildByName(q3);
+
+        final LeafRefContext foundOdlContrProjNameCtx = LeafRefContextUtils
+                .getLeafRefReferencingContext(odlContrProjNameNode,
+                        rootLeafRefContext);
+
+        assertNotNull(foundOdlContrProjNameCtx);
+        assertTrue(foundOdlContrProjNameCtx.isReferencing());
+        assertNotNull(foundOdlContrProjNameCtx.getLeafRefTargetPath());
+        assertEquals(odlContrProjNameCtx, foundOdlContrProjNameCtx);
+    }
+
+    @Test
+    public void leafRefContextUtilsTest2() {
+        final QName q1 = QName.create(tst, "odl-project");
+        final QName q2 = QName.create(tst, "project");
+        final QName q3 = QName.create(tst, "name");
+
+        final LeafRefContext leafRefCtx = rootLeafRefContext
+                .getReferencedChildByName(q1).getReferencedChildByName(q2)
+                .getReferencedChildByName(q3);
+
+        final DataSchemaNode odlProjNameNode = ((DataNodeContainer) ((DataNodeContainer) tstMod
+                .getDataChildByName(q1)).getDataChildByName(q2))
+                .getDataChildByName(q3);
+
+        LeafRefContext foundOdlProjNameCtx = LeafRefContextUtils
+                .getLeafRefReferencingContext(odlProjNameNode,
+                        rootLeafRefContext);
+
+        assertNull(foundOdlProjNameCtx);
+
+        foundOdlProjNameCtx = LeafRefContextUtils
+                .getLeafRefReferencedByContext(odlProjNameNode,
+                        rootLeafRefContext);
+
+        assertNotNull(foundOdlProjNameCtx);
+        assertTrue(foundOdlProjNameCtx.isReferenced());
+        assertFalse(foundOdlProjNameCtx.getAllReferencedByLeafRefCtxs()
+                .isEmpty());
+        assertEquals(6, foundOdlProjNameCtx.getAllReferencedByLeafRefCtxs()
+                .size());
+        assertEquals(leafRefCtx, foundOdlProjNameCtx);
+    }
+
+    @Test
+    public void leafRefContextUtilsTest3() {
+        final QName q16 = QName.create(tst, "con1");
+        final DataSchemaNode con1 = tstMod.getDataChildByName(q16);
+        final List<LeafRefContext> allLeafRefChilds = LeafRefContextUtils
+                .findAllLeafRefChilds(con1, rootLeafRefContext);
+
+        assertNotNull(allLeafRefChilds);
+        assertFalse(allLeafRefChilds.isEmpty());
+        assertEquals(4, allLeafRefChilds.size());
+
+        final QName q17 = QName.create(tst, "odl-contributor");
+        final DataSchemaNode odlContributorNode = tstMod.getDataChildByName(q17);
+        List<LeafRefContext> allChildsReferencedByLeafRef = LeafRefContextUtils
+                .findAllChildsReferencedByLeafRef(odlContributorNode,
+                        rootLeafRefContext);
+
+        assertNotNull(allChildsReferencedByLeafRef);
+        assertFalse(allChildsReferencedByLeafRef.isEmpty());
+        assertEquals(1, allChildsReferencedByLeafRef.size());
+
+        allChildsReferencedByLeafRef = LeafRefContextUtils
+                .findAllChildsReferencedByLeafRef(con1, rootLeafRefContext);
+
+        assertNotNull(allChildsReferencedByLeafRef);
+        assertTrue(allChildsReferencedByLeafRef.isEmpty());
+
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void incorrectLeafRefPathTest() throws URISyntaxException,
+            IOException, YangSyntaxErrorException,
+            LeafRefYangSyntaxErrorException {
+        final File resourceFile = new File(getClass().getResource(
+                "/leafref-context-test/incorrect-modules/leafref-test.yang")
+                .toURI());
+        final File resourceDir = resourceFile.getParentFile();
+
+        final YangParserImpl parser = YangParserImpl.getInstance();
+        final SchemaContext context = parser.parseFile(resourceFile, resourceDir);
+
+        LeafRefContext.create(context);
+
+    }
+
+}
diff --git a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/InstanceIdToNodesTest.java b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/InstanceIdToNodesTest.java
new file mode 100644 (file)
index 0000000..5735ea0
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * 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.impl.schema;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.io.ByteSource;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+public class InstanceIdToNodesTest {
+
+    private static final String NS = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:normalization:test";
+    private static final String REVISION = "2014-03-13";
+    private static final QName ID = QName.create(NS, REVISION, "id");
+    private SchemaContext ctx;
+
+    private final YangInstanceIdentifier.NodeIdentifier rootContainer = new YangInstanceIdentifier.NodeIdentifier(QName.create(NS, REVISION, "test"));
+    private final YangInstanceIdentifier.NodeIdentifier outerContainer = new YangInstanceIdentifier.NodeIdentifier(QName.create(NS, REVISION, "outer-container"));
+    private final YangInstanceIdentifier.NodeIdentifier augmentedLeaf = new YangInstanceIdentifier.NodeIdentifier(QName.create(NS, REVISION, "augmented-leaf"));
+    private final YangInstanceIdentifier.AugmentationIdentifier augmentation = new YangInstanceIdentifier.AugmentationIdentifier(Collections.singleton(augmentedLeaf.getNodeType()));
+
+    private final YangInstanceIdentifier.NodeIdentifier outerList = new YangInstanceIdentifier.NodeIdentifier(QName.create(NS, REVISION, "outer-list"));
+    private final YangInstanceIdentifier.NodeIdentifierWithPredicates outerListWithKey = new YangInstanceIdentifier.NodeIdentifierWithPredicates(QName.create(NS, REVISION, "outer-list"), ID, 1);
+    private final YangInstanceIdentifier.NodeIdentifier choice = new YangInstanceIdentifier.NodeIdentifier(QName.create(NS, REVISION, "outer-choice"));
+    private final YangInstanceIdentifier.NodeIdentifier leafFromCase = new YangInstanceIdentifier.NodeIdentifier(QName.create(NS, REVISION, "one"));
+
+    private final YangInstanceIdentifier.NodeIdentifier leafList = new YangInstanceIdentifier.NodeIdentifier(QName.create(NS, REVISION, "ordered-leaf-list"));
+    private final YangInstanceIdentifier.NodeWithValue leafListWithValue = new YangInstanceIdentifier.NodeWithValue(leafList.getNodeType(), "abcd");
+
+    static SchemaContext createTestContext() throws IOException, YangSyntaxErrorException {
+        final YangParserImpl parser = new YangParserImpl();
+        return parser.parseSources(Collections2.transform(Collections.singletonList("/filter-test.yang"), new Function<String, ByteSource>() {
+            @Override
+            public ByteSource apply(final String input) {
+                return new ByteSource() {
+                    @Override
+                    public InputStream openStream() throws IOException {
+                        return InstanceIdToNodesTest.class.getResourceAsStream(input);
+                    }
+                };
+            }
+        }));
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        ctx = createTestContext();
+
+    }
+
+    @Test
+    public void testInAugment() throws Exception {
+        final ContainerNode expectedFilter = Builders.containerBuilder().withNodeIdentifier(rootContainer).withChild(
+                Builders.containerBuilder().withNodeIdentifier(outerContainer).withChild(
+                        Builders.augmentationBuilder().withNodeIdentifier(augmentation).withChild(
+                                Builders.leafBuilder().withNodeIdentifier(augmentedLeaf).build()
+                        ).build()
+                ).build()
+        ).build();
+
+        final NormalizedNode<?, ?> filter = ImmutableNodes.fromInstanceId(ctx, YangInstanceIdentifier.create(rootContainer, outerContainer, augmentation, augmentedLeaf));
+        assertEquals(expectedFilter, filter);
+    }
+
+    @Test
+    public void testInAugmentLeafOverride() throws Exception {
+        final LeafNode<Object> lastLeaf = Builders.leafBuilder().withNodeIdentifier(augmentedLeaf).withValue("randomValue").build();
+
+        final ContainerNode expectedFilter = Builders.containerBuilder().withNodeIdentifier(rootContainer).withChild(
+                Builders.containerBuilder().withNodeIdentifier(outerContainer).withChild(
+                        Builders.augmentationBuilder().withNodeIdentifier(augmentation).withChild(
+                                lastLeaf
+                        ).build()
+                ).build()
+        ).build();
+
+        final NormalizedNode<?, ?> filter = ImmutableNodes.fromInstanceId(ctx, YangInstanceIdentifier.create(rootContainer, outerContainer, augmentation, augmentedLeaf), lastLeaf);
+        assertEquals(expectedFilter, filter);
+    }
+
+    @Test
+    public void testListChoice() throws Exception {
+        final ContainerNode expectedFilter = Builders.containerBuilder().withNodeIdentifier(rootContainer).withChild(
+                Builders.mapBuilder().withNodeIdentifier(outerList).withChild(
+                        Builders.mapEntryBuilder().withNodeIdentifier(outerListWithKey).withChild(
+                                Builders.leafBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(ID)).withValue(1).build()
+                        ).withChild(
+                                Builders.choiceBuilder().withNodeIdentifier(choice).withChild(
+                                        Builders.leafBuilder().withNodeIdentifier(leafFromCase).build()
+                                ).build()
+                        ).build()
+                ).build()
+        ).build();
+
+        final NormalizedNode<?, ?> filter = ImmutableNodes.fromInstanceId(ctx, YangInstanceIdentifier.create(rootContainer, outerList, outerListWithKey, choice, leafFromCase));
+        assertEquals(expectedFilter, filter);
+    }
+
+    @Test
+    public void testTopContainerLastChildOverride() throws Exception {
+        final ContainerNode expectedStructure = Builders.containerBuilder().withNodeIdentifier(rootContainer).withChild(
+                Builders.mapBuilder().withNodeIdentifier(outerList).withChild(
+                        Builders.mapEntryBuilder().withNodeIdentifier(outerListWithKey).withChild(
+                                Builders.leafBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(ID)).withValue(1).build()
+                        ).withChild(
+                                Builders.choiceBuilder().withNodeIdentifier(choice).withChild(
+                                        Builders.leafBuilder().withNodeIdentifier(leafFromCase).build()
+                                ).build()
+                        ).build()
+                ).build()
+        ).build();
+
+        final NormalizedNode<?, ?> filter = ImmutableNodes.fromInstanceId(ctx, YangInstanceIdentifier.create(rootContainer), expectedStructure);
+        assertEquals(expectedStructure, filter);
+    }
+
+    @Test
+    public void testListLastChildOverride() throws Exception {
+        final MapEntryNode outerListEntry = Builders.mapEntryBuilder().withNodeIdentifier(outerListWithKey).withChild(
+                Builders.leafBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(ID)).withValue(1).build()
+        ).build();
+        final MapNode lastChild = Builders.mapBuilder().withNodeIdentifier(this.outerList).withChild(
+                outerListEntry
+        ).build();
+        final ContainerNode expectedStructure = Builders.containerBuilder().withNodeIdentifier(rootContainer).withChild(
+                lastChild
+        ).build();
+
+        NormalizedNode<?, ?> filter = ImmutableNodes.fromInstanceId(ctx, YangInstanceIdentifier.create(rootContainer, outerList, outerListWithKey), outerListEntry);
+        assertEquals(expectedStructure, filter);
+        filter = ImmutableNodes.fromInstanceId(ctx, YangInstanceIdentifier.create(rootContainer, outerList, outerListWithKey));
+        assertEquals(expectedStructure, filter);
+    }
+
+    @Test
+    public void testLeafList() throws Exception {
+        final ContainerNode expectedFilter = Builders.containerBuilder().withNodeIdentifier(rootContainer).withChild(
+                Builders.orderedLeafSetBuilder().withNodeIdentifier(leafList).withChild(
+                        Builders.leafSetEntryBuilder().withNodeIdentifier(leafListWithValue).withValue(leafListWithValue.getValue()).build()
+                ).build()
+        ).build();
+
+        final NormalizedNode<?, ?> filter = ImmutableNodes.fromInstanceId(ctx, YangInstanceIdentifier.create(rootContainer, leafList, leafListWithValue));
+        assertEquals(expectedFilter, filter);
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-data-impl/src/test/resources/filter-test.yang b/yang/yang-data-impl/src/test/resources/filter-test.yang
new file mode 100644 (file)
index 0000000..6df5306
--- /dev/null
@@ -0,0 +1,74 @@
+module normalization-test {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:normalization:test";
+    prefix "norm-test";
+
+    revision "2014-03-13" {
+        description "Initial revision.";
+    }
+
+    grouping outer-grouping {
+    }
+
+    container test {
+        list outer-list {
+            key id;
+            leaf id {
+                type uint16;
+            }
+            choice outer-choice {
+                case one {
+                    leaf one {
+                        type string;
+                    }
+                }
+                case two-three {
+                    leaf two {
+                        type string;
+                    }
+                    leaf three {
+                        type string;
+                    }
+               }
+           }
+           list inner-list {
+                key name;
+                ordered-by user;
+
+                leaf name {
+                    type string;
+                }
+                leaf value {
+                    type string;
+                }
+            }
+        }
+
+        list unkeyed-list {
+            leaf name {
+                type string;
+            }
+        }
+
+        leaf-list unordered-leaf-list {
+            type string;
+        }
+
+        leaf-list ordered-leaf-list {
+            ordered-by user;
+            type string;
+        }
+
+        container outer-container {
+        }
+
+        anyxml any-xml-data;
+    }
+
+    augment /norm-test:test/norm-test:outer-container {
+
+        leaf augmented-leaf {
+           type string;
+        }
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-data-impl/src/test/resources/leafref-context-test/correct-modules/import-mod.yang b/yang/yang-data-impl/src/test/resources/leafref-context-test/correct-modules/import-mod.yang
new file mode 100644 (file)
index 0000000..826a339
--- /dev/null
@@ -0,0 +1,10 @@
+module import-mod {
+    namespace "pk.import";
+    prefix imp;
+
+    revision 2014-10-07 {
+        description
+                "Yang initial revision";
+    }
+
+}
diff --git a/yang/yang-data-impl/src/test/resources/leafref-context-test/correct-modules/leafref-test.yang b/yang/yang-data-impl/src/test/resources/leafref-context-test/correct-modules/leafref-test.yang
new file mode 100644 (file)
index 0000000..1bf8f42
--- /dev/null
@@ -0,0 +1,152 @@
+module leafref-test {
+    namespace "pk.test";
+    prefix tst;
+
+    import import-mod { prefix imp; revision-date 2014-10-07; }
+
+    revision 1999-09-09 {
+        description
+                "Yang initial revision";
+    }
+
+    container odl-contributor {
+        list contributor {
+            key "login";
+            leaf login {
+                type string;
+            }
+            leaf contributor-name {
+                type string;
+            }
+            leaf odl-project-name {
+                type leafref {
+                    path "/odl-project/project/name";
+                }
+            }
+        }
+        list noleafref-contributor {
+            leaf foo {
+                type string;
+            }
+        }
+    }
+
+    container odl-project {
+        list project {
+            key "name";
+            leaf name {
+                type string;
+            }
+            leaf project-lead {
+                type leafref {
+                    path "../../../tst:odl-contributor[imp:foo=current()/bar]/contributor[tst:odl-project-name
+                                        = current()/../imp:name][odl-project-name2 = current()/../../imp:name/tst:name2][imp:odl-project-name3
+                                        = current()/../../imp:name/imp:name2]/tst:login";
+                }
+            }
+            leaf project-lead2 {
+                type leafref {
+                    path "/odl-contributor[foo=current()/bar]/contributor[odl-project-name
+                                        = current()/../name][odl-project-name2 = current()/../../name/name2][odl-project-name3
+                                        = current()/../../name/name2]/login";
+                }
+            }
+
+            choice ch1 {
+                case c1 {
+                    choice ch2 {
+                        case c1 {
+                            leaf l1 {
+                                type leafref {
+                                    path "../../con1/l1";
+                                }
+                            }
+                        }
+                        case c2 {
+                        }
+                    }
+                }
+                case c2 {
+                }
+            }
+        }
+        list noleafref-project {
+            leaf foo {
+                type string;
+            }
+        }
+        container con1 {
+            leaf l1 {
+                type empty;
+            }
+        }
+    }
+
+    container con1 {
+        container con2 {
+            container con3 {
+                leaf l1 {
+                    type leafref {
+                        path "/odl-project/project/name";
+                    }
+                }
+                leaf l2 {
+                    type leafref {
+                        path "/odl-project/project/name";
+                    }
+                }
+                leaf l3-noleafref {
+                    type int16;
+                }
+            }
+            leaf l4 {
+                type leafref {
+                    path "/odl-project/project/name";
+                }
+            }
+            leaf l5-noleafref {
+                type int16;
+            }
+        }
+        leaf l6 {
+            type leafref {
+                path "/odl-project/project/name";
+            }
+        }
+        leaf l7-noleafref {
+            type int16;
+        }
+    }
+
+    leaf l8 {
+        type leafref {
+            path "/odl-project/project/name";
+        }
+    }
+
+    container no-leafrefcontainer {
+        list no-leafreflist {
+            leaf bar {
+                type string;
+            }
+        }
+        container no-leafrefcontainer2 {
+            leaf baz {
+                type string;
+            }
+        }
+    }
+
+    container no-leafrefcontainer2 {
+        list no-leafreflist {
+            leaf bar {
+                type string;
+            }
+        }
+        container no-leafrefcontainer2 {
+            leaf baz {
+                type string;
+            }
+        }
+    }
+}
diff --git a/yang/yang-data-impl/src/test/resources/leafref-context-test/correct-modules/leafref-test2.yang b/yang/yang-data-impl/src/test/resources/leafref-context-test/correct-modules/leafref-test2.yang
new file mode 100644 (file)
index 0000000..b707a70
--- /dev/null
@@ -0,0 +1,83 @@
+module leafref-test2 {
+    namespace "gz.test";
+    prefix "main";
+
+    revision 2015-02-13 {
+        description "Initial revision";
+    }
+
+    leaf leaf1 {
+        type int16;
+    }
+
+    leaf ref1 {
+        type leafref {
+            path "../leaf1";
+        }
+    }
+
+    typedef low_int {
+        type int8 {
+            range 1..100;
+        }
+    }
+
+    container cont1 {
+
+        list list1 {
+            leaf name {
+                type string;
+            }
+            leaf id {
+                type int32;
+            }
+            leaf value {
+                type low_int;
+            }
+            leaf external {
+                type leafref {
+                    path "../../../cont2/value";
+                }
+            }
+        }
+    }
+
+    container cont2 {
+        leaf value {
+            type decimal64 {
+                fraction-digits 4;
+            }
+        }
+    }
+
+    container cont3 {
+        container cont4 {
+            leaf l1 {
+                type leafref {
+                    path "/cont1/list1/name";
+                }
+            }
+            leaf l2 {
+                type leafref {
+                    path "../../../cont1/list1/name";
+                }
+            }
+        }
+        leaf l3 {
+            type leafref {
+                path "/cont1/list1/name";
+            }
+        }
+        leaf l4 {
+            type int32;
+        }
+    }
+
+    container cont5 {
+        leaf l5 {
+            type leafref {
+                path "/cont1/list1/name";
+            }
+        }
+    }
+}
diff --git a/yang/yang-data-impl/src/test/resources/leafref-context-test/incorrect-modules/leafref-test.yang b/yang/yang-data-impl/src/test/resources/leafref-context-test/incorrect-modules/leafref-test.yang
new file mode 100644 (file)
index 0000000..ae33ffb
--- /dev/null
@@ -0,0 +1,114 @@
+module leafref-test {
+    namespace "test";
+    prefix test;
+
+    container odl-contributor {
+        list contributor {
+            key "login";
+            leaf login {
+                type string;
+            }
+            leaf contributor-name {
+                type string;
+            }
+            leaf odl-project-name {
+                type leafref {
+                    path ".../odl-project/project/name";
+                }
+            }
+        }
+        list noleafref-contributor {
+            leaf foo {
+                type string;
+            }
+        }
+    }
+
+    container odl-project {
+        list project {
+            key "name";
+            leaf name {
+                type string;
+            }
+            leaf project-lead {
+                type leafref {
+                    path "/odl-contributor/contributor/login";
+                }
+            }
+        }
+        list noleafref-project {
+            leaf foo {
+                type string;
+            }
+        }
+    }
+
+    container con1 {
+        container con2 {
+            container con3 {
+                leaf l1 {
+                    type leafref {
+                        path "/odl-project/project/name";
+                    }
+                }
+                leaf l2 {
+                    type leafref {
+                        path "/odl-project/project/name";
+                    }
+                }
+                leaf l3-noleafref {
+                    type int16;
+                }
+            }
+            leaf l4 {
+                type leafref {
+                    path "/odl-project/project/name";
+                }
+            }
+            leaf l5-noleafref {
+                type int16;
+            }
+        }
+        leaf l6 {
+            type leafref {
+                path "/odl-project/project/name";
+            }
+        }
+        leaf l7-noleafref {
+            type int16;
+        }
+    }
+
+    leaf l8 {
+        type leafref {
+            path "/odl-project/project/name";
+        }
+    }
+
+    container no-leafrefcontainer {
+        list no-leafreflist {
+            leaf bar {
+                type string;
+            }
+        }
+        container no-leafrefcontainer2 {
+            leaf baz {
+                type string;
+            }
+        }
+    }
+
+    container no-leafrefcontainer2 {
+        list no-leafreflist {
+            leaf bar {
+                type string;
+            }
+        }
+        container no-leafrefcontainer2 {
+            leaf baz {
+                type string;
+            }
+        }
+    }
+
+}
diff --git a/yang/yang-data-impl/src/test/resources/leafref-validation/leafref-validation.yang b/yang/yang-data-impl/src/test/resources/leafref-validation/leafref-validation.yang
new file mode 100644 (file)
index 0000000..60e2df8
--- /dev/null
@@ -0,0 +1,150 @@
+module leafref-validation {
+    namespace "leafref.validation";
+    prefix val;
+
+    leaf l1 {
+        type leafref {
+            path "../l2";
+        }
+    }
+
+    leaf l2 {
+        type string;
+    }
+
+    container odl-contributor {
+        list contributor {
+            key "login";
+            leaf login {
+                type string;
+            }
+            leaf contributor-name {
+                type string;
+            }
+            leaf odl-group-id {
+                type string;
+            }
+            leaf odl-project-name {
+                type leafref {
+                    path "../../../odl-project/project/name";
+                }
+            }
+            leaf odl-project-desc {
+                type leafref {
+                    path "/odl-project/project[name = current()/../odl-project-name]/desc";
+                }
+                // type string;                                    
+            }
+        }
+        list noleafref-contributor {
+            leaf foo {
+                type string;
+            }
+        }
+    }
+
+    container odl-project {
+        list project {
+            key "name";
+            leaf name {
+                type string;
+            }
+            leaf desc {
+                type string;
+            }
+            leaf project-lead {
+                type leafref {
+                    path "../../../odl-contributor/contributor/login";
+                }
+            }
+            leaf project-owner {
+                type leafref {
+                    path "/odl-contributor/contributor/login";
+                }
+            }
+        }
+
+        choice ch1 {
+            case c1 {
+                choice ch2 {
+                    case c1 {
+                        list list-in-choice {
+                            key "list-in-choice-key";
+                            leaf list-in-choice-key {
+                                type string;
+                            }
+                            leaf leafref-in-choice {
+                                type leafref {
+                                    path "../../con1/l1";
+                                }
+                            }
+                            leaf leafref-in-choice-to-choice {
+                                type leafref {
+                                    path "../../con3/list3-in-choice/l3";
+                                }
+                            }
+                        }
+                    }
+                    case c2 {
+                    }
+                }
+            }
+            case c2 {
+            }
+        }
+
+        list noleafref-project {
+            leaf foo {
+                type string;
+            }
+        }
+        container con1 {
+            leaf l1 {
+                type string;
+            }
+        }
+
+        container con3 {
+            choice choice-in-con3 {
+                case one {
+                    list list3-in-choice {
+                        key "k";
+                        leaf k {
+                            type string;
+                        }
+                        leaf-list l3 {
+                            type string;
+                        }
+                    }
+                }
+                case two {
+                    list list3-in-choice-2 {
+                        key "l3-2";
+                        leaf l3-2 {
+                            type string;
+                        }
+                    }
+                }
+            }
+        }
+
+        leaf-list leafref-leaf-list {
+            type leafref {
+                path "../con3/list3-in-choice/k";
+            }
+        }
+    }
+
+    container no-leafrefcontainer {
+        list no-leafreflist {
+            leaf bar {
+                type string;
+            }
+        }
+        container no-leafrefcontainer2 {
+            leaf baz {
+                type string;
+            }
+        }
+    }
+}
diff --git a/yang/yang-data-impl/src/test/resources/leafref-validation/leafref-validation2.yang b/yang/yang-data-impl/src/test/resources/leafref-validation/leafref-validation2.yang
new file mode 100644 (file)
index 0000000..0a103e3
--- /dev/null
@@ -0,0 +1,52 @@
+module leafref-validation2 {
+    namespace "leafref.validation2";
+    prefix val2;
+
+    container device_types {
+        list device_type {
+            key "type";
+            leaf type {
+                type string;
+            }
+            leaf desc {
+                type string;
+            }
+        }
+    }
+
+    container devices {
+        list device {
+            key "type_text sn";
+            leaf type_text {
+                type leafref {
+                    path "/device_types/device_type/type";
+                }
+            }
+            leaf dev_desc {
+                type leafref {
+                    path "/device_types/device_type[type = current()/../type_text]/desc";
+                }
+            }
+            leaf sn {
+                type int32;
+            }
+            leaf default_ip {
+                type string;
+            }
+        }
+    }
+
+    container chips {
+        list chip {
+            key "dev_type";
+            leaf dev_type {
+                type leafref {
+                    path "/devices/device/type_text";
+                }
+            }
+            leaf chip_desc {
+                type string;
+            }
+        }
+    }
+}
diff --git a/yang/yang-data-impl/src/test/resources/leafref-validation/leafref-validation3.yang b/yang/yang-data-impl/src/test/resources/leafref-validation/leafref-validation3.yang
new file mode 100644 (file)
index 0000000..6823e10
--- /dev/null
@@ -0,0 +1,70 @@
+module leafref-validation3 {
+    namespace "leafref.validation3";
+    prefix val3;
+
+    container device_types {
+        list device_type {
+            key "type1 type2 type3";
+            leaf type1 {
+                type string;
+            }
+            leaf type2 {
+                type string;
+            }
+            leaf type3 {
+                type string;
+            }
+            leaf desc {
+                type string;
+            }
+        }
+    }
+
+    container devices {
+        list device {
+            key "type_text1 sn";
+            unique "sn";
+            leaf type_text1 {
+                type leafref {
+                    path "/device_types/device_type/type1";
+                }
+            }
+            leaf type_text2 {
+                type leafref {
+                    path "/device_types/device_type/type2";
+                }
+            }
+            leaf type_text3 {
+                type leafref {
+                    path "/device_types/device_type/type3";
+                }
+            }
+            leaf dev_desc {
+                type leafref {
+                    path "/device_types/device_type[type1 = current()/../type_text1][type2
+                                        = current()/../type_text2][type3 = current()/../type_text3]/desc";
+                }
+            }
+            leaf sn {
+                type int32;
+            }
+            leaf default_ip {
+                type string;
+            }
+        }
+    }
+
+    container chips {
+        list chip {
+            key "dev_type";
+            leaf dev_type {
+                type leafref {
+                    path "/devices/device/type_text";
+                }
+            }
+            leaf chip_desc {
+                type string;
+            }
+        }
+    }
+}
index dec5406e42c133f1a19af14fc386e67a5ab2abaa..a11ebf851083d2007f77f37110e16260f49017cd 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 85d904a2698534df081c0e47ec91e626edb5d78a..fc0d94592c266beb3ee15f89ed9f0081be8a74af 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 29048f106d844ff46212fc71bad37b1e9e2dbb5c..c3e8eea65abb7492d277d96fead54b5dcf6f159e 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 3c88fe63fc49a502ff1e75ae114b4e658293027f..6cbbd6051b8d61f25b28020e82ae70671220acd0 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index ab9085398894e628fd1c76d2062229c8c9c7d163..35b6f770d8967f1560239a9b26487bc08d655d23 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 10361ba20ccb79768a550382f7e058819dcd576f..ca4d5540dde7d2e7c2f25a2dc3f8270ca3ded124 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 985a7cdd7d61184e10e6e7825a87acd3628b933b..cc8f6feebd684e317a80085ad86822a431b97d8b 100644 (file)
@@ -24,6 +24,7 @@ import org.opendaylight.yangtools.yang.common.QName;
  * Represents unique path to the every node inside the module.
  */
 public abstract class SchemaPath implements Immutable {
+
     /**
      * An absolute SchemaPath.
      */
@@ -97,6 +98,18 @@ public abstract class SchemaPath implements Immutable {
      */
     private volatile ImmutableList<QName> legacyPath;
 
+    protected SchemaPath(final SchemaPath 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;
+    }
+
     private ImmutableList<QName> getLegacyPath() {
         ImmutableList<QName> ret = legacyPath;
         if (ret == null) {
@@ -120,18 +133,6 @@ public abstract class SchemaPath implements Immutable {
         return getLegacyPath();
     }
 
-    protected SchemaPath(final SchemaPath 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.
      *
@@ -185,12 +186,12 @@ public abstract class SchemaPath implements Immutable {
             return this;
         }
 
-        SchemaPath parent = this;
+        SchemaPath parentPath = this;
         for (QName qname : relative) {
-            parent = parent.createInstance(parent, qname);
+            parentPath = parentPath.createInstance(parentPath, qname);
         }
 
-        return parent;
+        return parentPath;
     }
 
     /**
@@ -202,12 +203,12 @@ public abstract class SchemaPath implements Immutable {
     public SchemaPath createChild(final SchemaPath relative) {
         Preconditions.checkArgument(!relative.isAbsolute(), "Child creation requires relative path");
 
-        SchemaPath parent = this;
+        SchemaPath parentPath = this;
         for (QName qname : relative.getPathFromRoot()) {
-            parent = parent.createInstance(parent, qname);
+            parentPath = parentPath.createInstance(parentPath, qname);
         }
 
-        return parent;
+        return parentPath;
     }
 
     /**
index 00ec9408d4e63d00688e00ec57a083c62cd024fc..6308381916a01a400b0602194a9a8b77f7cac0d8 100644 (file)
@@ -8,10 +8,12 @@
 package org.opendaylight.yangtools.yang.model.api.stmt;
 
 import javax.annotation.Nonnull;
+
+import org.opendaylight.yangtools.yang.model.api.Deviation;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 
-public interface DeviateStatement extends DeclaredStatement<String> {
+public interface DeviateStatement extends DeclaredStatement<Deviation.Deviate> {
 
-    @Nonnull String getValue();
+    @Nonnull
+    Deviation.Deviate getValue();
 }
-
index bacf0c41cccf85070460ae24994160a4cea0497f..77c36f1b8e6f4ef28084fa9b54db9090a99375e1 100644 (file)
@@ -26,6 +26,7 @@ import org.opendaylight.yangtools.yang.common.QName;
  *
  */
 public abstract class SchemaNodeIdentifier implements Immutable {
+
     /**
      * An absolute schema node identifier.
      */
@@ -99,6 +100,18 @@ public abstract class SchemaNodeIdentifier implements Immutable {
      */
     private volatile ImmutableList<QName> legacyPath;
 
+    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;
+    }
+
     private ImmutableList<QName> getLegacyPath() {
         ImmutableList<QName> ret = legacyPath;
         if (ret == null) {
@@ -122,18 +135,6 @@ public abstract class SchemaNodeIdentifier implements Immutable {
         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.
      *
@@ -187,12 +188,12 @@ public abstract class SchemaNodeIdentifier implements Immutable {
             return this;
         }
 
-        SchemaNodeIdentifier parent = this;
+        SchemaNodeIdentifier parentNode = this;
         for (QName qname : relative) {
-            parent = parent.createInstance(parent, qname);
+            parentNode = parentNode.createInstance(parentNode, qname);
         }
 
-        return parent;
+        return parentNode;
     }
 
     /**
@@ -204,12 +205,12 @@ public abstract class SchemaNodeIdentifier implements Immutable {
     public SchemaNodeIdentifier createChild(final SchemaNodeIdentifier relative) {
         Preconditions.checkArgument(!relative.isAbsolute(), "Child creation requires relative path");
 
-        SchemaNodeIdentifier parent = this;
+        SchemaNodeIdentifier parentNode = this;
         for (QName qname : relative.getPathFromRoot()) {
-            parent = parent.createInstance(parent, qname);
+            parentNode = parentNode.createInstance(parentNode, qname);
         }
 
-        return parent;
+        return parentNode;
     }
 
     /**
index 0070cab71fe3d7bcf734060e9bfc4d6e63351d50..9f5e22bc9f9e22c827e51924ff8ae1a00f7de54b 100644 (file)
@@ -23,6 +23,9 @@ import org.opendaylight.yangtools.yang.model.api.ModuleImport;
  */
 @Beta
 public class SchemaResolutionException extends SchemaSourceException {
+
+    private static final String MESSAGE_BLUEPRINT = "%s, resolved sources: %s, unsatisfied imports: %s";
+
     private static final long serialVersionUID = 1L;
     private final Multimap<SourceIdentifier, ModuleImport> unsatisfiedImports;
     private final Collection<SourceIdentifier> resolvedSources;
@@ -48,7 +51,6 @@ public class SchemaResolutionException extends SchemaSourceException {
         this.resolvedSources = ImmutableList.copyOf(resolvedSources);
     }
 
-    private static final String MESSAGE_BLUEPRINT = "%s, resolved sources: %s, unsatisfied imports: %s";
     private static String formatMessage(final String message, final Collection<SourceIdentifier> resolvedSources, final Multimap<SourceIdentifier, ModuleImport> unsatisfiedImports) {
         return String.format(MESSAGE_BLUEPRINT, message, resolvedSources, unsatisfiedImports);
     }
index 6da4ee301263ffbcb72c5200fdea0b54ee87c3da..85b26a52d4ba4b3bc334971a406914d15d673767 100644 (file)
@@ -24,12 +24,12 @@ public interface SchemaSourceFilter {
      * A {@link SchemaSourceFilter} which accepts any schema source it is presented with.
      */
     public static final SchemaSourceFilter ALWAYS_ACCEPT = new SchemaSourceFilter() {
-        private final Iterable<Class<? extends SchemaSourceRepresentation>> REPRESENTATIONS =
+        private final Iterable<Class<? extends SchemaSourceRepresentation>> Representations =
                 Collections.<Class<? extends SchemaSourceRepresentation>>singletonList(SchemaSourceRepresentation.class);
 
         @Override
         public Iterable<Class<? extends SchemaSourceRepresentation>> supportedRepresentations() {
-            return REPRESENTATIONS;
+            return Representations;
         }
 
         @Override
index f46ed3f426553be6f37a5a94e72b7d96b965c24c..0b74d4b63fbbe0549136c1e51ac805186457479f 100644 (file)
@@ -56,12 +56,22 @@ public final class SourceIdentifier implements Identifier, Immutable {
      */
     public static final Pattern REVISION_PATTERN = Pattern.compile("\\d\\d\\d\\d-\\d\\d-\\d\\d");
 
-
     private static final ObjectCache CACHE = ObjectCacheFactory.getObjectCache(SourceIdentifier.class);
     private static final long serialVersionUID = 1L;
     private final String revision;
     private final String name;
 
+    /**
+     *
+     * Creates new YANG Schema source identifier for sources without revision.
+     * {@link SourceIdentifier#NOT_PRESENT_FORMATTED_REVISION} as default revision.
+     *
+     * @param name Name of schema
+     */
+    public SourceIdentifier(final String name) {
+        this(name, NOT_PRESENT_FORMATTED_REVISION);
+    }
+
     /**
      * Creates new YANG Schema source identifier.
      *
@@ -93,17 +103,6 @@ public final class SourceIdentifier implements Identifier, Immutable {
         return CACHE.getReference(this);
     }
 
-    /**
-     *
-     * Creates new YANG Schema source identifier for sources without revision.
-     * {@link SourceIdentifier#NOT_PRESENT_FORMATTED_REVISION} as default revision.
-     *
-     * @param name Name of schema
-     */
-    public SourceIdentifier(final String name) {
-        this(name, NOT_PRESENT_FORMATTED_REVISION);
-    }
-
     /**
      * Returns model name
      *
index 31f82961be842eefee343fc264153854b0db4223..81699215b7bade14eaf610123f5a1feaa005c310 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 50e2a926fd477971698d26091e4f5fb93046b68a..64284634adbc14c128d9bdbafd11c80cb4655fe0 100644 (file)
@@ -13,7 +13,7 @@
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
         <artifactId>bundle-parent</artifactId>
-        <version>1.5.0-SNAPSHOT</version>
+        <version>1.6.0-SNAPSHOT</version>
         <relativePath/>
     </parent>
 
     <groupId>org.opendaylight.yangtools</groupId>
     <artifactId>yang-model-parent</artifactId>
     <packaging>pom</packaging>
-    <version>0.7.0-SNAPSHOT</version>
+    <version>0.8.0-SNAPSHOT</version>
 
     <properties>
-        <yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
+        <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
     </properties>
 
     <dependencyManagement>
index f484e09d3a54d878eebbef8a4a74c4dff36d26ce..06c1b73089a3253792f4c75c76e910da515766be 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index ee32cd90d54d5d17887485c376a8c4f2e0f1f830..448ef2f664cf9b1f4bcf0660587c3fc23f4c7990 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 6115c83b578108ce4dc9e219c481516708a140bc..5cb407ed8da222d82d70eaaae65436e082aae5c0 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yangtools-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
+        <version>0.8.0-SNAPSHOT</version>
         <relativePath>/../../common/parent/pom.xml</relativePath>
     </parent>
 
index 975b683dd64e93e6aa962069a9c4c2eeb0838747..e98553e8009013e5b4f5c2bc2c60123fdd147630 100644 (file)
@@ -29,6 +29,7 @@ import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.NavigableMap;
 import java.util.Set;
 import java.util.TreeMap;
 import org.antlr.v4.runtime.tree.ParseTree;
@@ -83,6 +84,7 @@ public final class BuilderUtils {
     private static final Date NULL_DATE = new Date(0L);
     private static final String INPUT = "input";
     private static final String OUTPUT = "output";
+    private static final String CHILD_NOT_FOUND_IN_NODE_STR = "Child {} not found in node {}";
 
     private BuilderUtils() {
     }
@@ -148,7 +150,7 @@ public final class BuilderUtils {
      *            current line in yang model
      * @return module builder if found, null otherwise
      */
-    public static ModuleBuilder findModuleFromBuilders(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+    public static ModuleBuilder findModuleFromBuilders(final Map<String, NavigableMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module, final String prefix, final int line) {
         ModuleBuilder dependentModule;
         Date dependentModuleRevision;
@@ -165,7 +167,7 @@ public final class BuilderUtils {
             String dependentModuleName = dependentModuleImport.getModuleName();
             dependentModuleRevision = dependentModuleImport.getRevision();
 
-            TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules.get(dependentModuleName);
+            NavigableMap<Date, ModuleBuilder> moduleBuildersByRevision = modules.get(dependentModuleName);
             if (moduleBuildersByRevision == null) {
                 return null;
             }
@@ -181,12 +183,10 @@ public final class BuilderUtils {
     public static ModuleBuilder findModuleFromBuilders(ModuleImport imp, Iterable<ModuleBuilder> modules) {
         String name = imp.getModuleName();
         Date revision = imp.getRevision();
-        TreeMap<Date, ModuleBuilder> map = new TreeMap<>();
+        NavigableMap<Date, ModuleBuilder> map = new TreeMap<>();
         for (ModuleBuilder module : modules) {
-            if (module != null) {
-                if (module.getName().equals(name)) {
-                    map.put(module.getRevision(), module);
-                }
+            if (module != null && module.getName().equals(name)) {
+                map.put(module.getRevision(), module);
             }
         }
         if (map.isEmpty()) {
@@ -216,7 +216,7 @@ public final class BuilderUtils {
      */
     public static Module findModuleFromContext(final SchemaContext context, final ModuleBuilder currentModule,
             final String prefix, final int line) {
-        TreeMap<Date, Module> modulesByRevision = new TreeMap<>();
+        NavigableMap<Date, Module> modulesByRevision = new TreeMap<>();
 
         ModuleImport dependentModuleImport = currentModule.getImport(prefix);
         if (dependentModuleImport == null) {
@@ -378,9 +378,9 @@ public final class BuilderUtils {
                     node = findUnknownNode(name, parent);
                 }
             } else if (parent instanceof RpcDefinitionBuilder) {
-                if ("input".equals(name)) {
+                if (INPUT.equals(name)) {
                     node = ((RpcDefinitionBuilder) parent).getInput();
-                } else if ("output".equals(name)) {
+                } else if (OUTPUT.equals(name)) {
                     node = ((RpcDefinitionBuilder) parent).getOutput();
                 } else {
                     if (node == null) {
@@ -457,9 +457,8 @@ public final class BuilderUtils {
             return castOptional(SchemaNodeBuilder.class, findCaseInChoice((ChoiceBuilder) parent, child));
         } else if (parent instanceof RpcDefinitionBuilder) {
             return castOptional(SchemaNodeBuilder.class, findContainerInRpc((RpcDefinitionBuilder) parent, child));
-
         } else {
-            LOG.trace("Child {} not found in node {}", child, parent);
+            LOG.trace(CHILD_NOT_FOUND_IN_NODE_STR, child, parent);
             return Optional.absent();
         }
     }
@@ -504,7 +503,7 @@ public final class BuilderUtils {
             final QName child) {
         if (INPUT.equals(child.getLocalName())) {
             if (parent.getInput() == null) {
-                QName qname = QName.create(parent.getQName().getModule(), "input");
+                QName qname = QName.create(parent.getQName().getModule(), INPUT);
                 final ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(parent.getModuleName(),
                         parent.getLine(), qname, parent.getPath().createChild(qname));
                 inputBuilder.setParent(parent);
@@ -514,7 +513,7 @@ public final class BuilderUtils {
             return Optional.of(parent.getInput());
         } else if (OUTPUT.equals(child.getLocalName())) {
             if (parent.getOutput() == null) {
-                QName qname = QName.create(parent.getQName().getModule(), "output");
+                QName qname = QName.create(parent.getQName().getModule(), OUTPUT);
                 final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(parent.getModuleName(),
                         parent.getLine(), qname, parent.getPath().createChild(qname));
                 outputBuilder.setParent(parent);
@@ -523,7 +522,7 @@ public final class BuilderUtils {
             }
             return Optional.of(parent.getOutput());
         }
-        LOG.trace("Child {} not found in node {}", child, parent);
+        LOG.trace(CHILD_NOT_FOUND_IN_NODE_STR, child, parent);
         return Optional.absent();
     }
 
@@ -544,7 +543,7 @@ public final class BuilderUtils {
                 return Optional.of(caze);
             }
         }
-        LOG.trace("Child {} not found in node {}", child, parent);
+        LOG.trace(CHILD_NOT_FOUND_IN_NODE_STR, child, parent);
         return Optional.absent();
     }
 
@@ -565,7 +564,7 @@ public final class BuilderUtils {
                 return Optional.of(childNode);
             }
         }
-        LOG.trace("Child {} not found in node {}", child, parent);
+        LOG.trace(CHILD_NOT_FOUND_IN_NODE_STR, child, parent);
         return Optional.absent();
     }
 
@@ -625,7 +624,7 @@ public final class BuilderUtils {
                 return Optional.<SchemaNodeBuilder> of(childNode);
             }
         }
-        LOG.trace("Child {} not found in node {}", child, builder);
+        LOG.trace(CHILD_NOT_FOUND_IN_NODE_STR, child, builder);
         return Optional.absent();
     }
 
@@ -730,19 +729,19 @@ public final class BuilderUtils {
         final SchemaPath schemaPath = parentPath.createChild(qname);
 
         if (node instanceof AnyXmlSchemaNode) {
-            return new AnyXmlBuilder(moduleName, line, qname, schemaPath, ((AnyXmlSchemaNode) node));
+            return new AnyXmlBuilder(moduleName, line, qname, schemaPath, (AnyXmlSchemaNode) node);
         } else if (node instanceof ChoiceSchemaNode) {
-            return new ChoiceBuilder(moduleName, line, qname, schemaPath, ((ChoiceSchemaNode) node));
+            return new ChoiceBuilder(moduleName, line, qname, schemaPath, (ChoiceSchemaNode) node);
         } else if (node instanceof ContainerSchemaNode) {
-            return new ContainerSchemaNodeBuilder(moduleName, line, qname, schemaPath, ((ContainerSchemaNode) node));
+            return new ContainerSchemaNodeBuilder(moduleName, line, qname, schemaPath, (ContainerSchemaNode) node);
         } else if (node instanceof LeafSchemaNode) {
-            return new LeafSchemaNodeBuilder(moduleName, line, qname, schemaPath, ((LeafSchemaNode) node));
+            return new LeafSchemaNodeBuilder(moduleName, line, qname, schemaPath, (LeafSchemaNode) node);
         } else if (node instanceof LeafListSchemaNode) {
-            return new LeafListSchemaNodeBuilder(moduleName, line, qname, schemaPath, ((LeafListSchemaNode) node));
+            return new LeafListSchemaNodeBuilder(moduleName, line, qname, schemaPath, (LeafListSchemaNode) node);
         } else if (node instanceof ListSchemaNode) {
-            return new ListSchemaNodeBuilder(moduleName, line, qname, schemaPath, ((ListSchemaNode) node));
+            return new ListSchemaNodeBuilder(moduleName, line, qname, schemaPath, (ListSchemaNode) node);
         } else if (node instanceof ChoiceCaseNode) {
-            return new ChoiceCaseBuilder(moduleName, line, qname, schemaPath, ((ChoiceCaseNode) node));
+            return new ChoiceCaseBuilder(moduleName, line, qname, schemaPath, (ChoiceCaseNode) node);
         } else {
             throw new YangParseException(moduleName, line, "Failed to copy node: Unknown type of DataSchemaNode: "
                     + node);
@@ -767,7 +766,7 @@ public final class BuilderUtils {
         for (TypeDefinition<?> node : nodes) {
             QName qname = QName.create(parentQName, node.getQName().getLocalName());
             SchemaPath schemaPath = parentPath.createChild(qname);
-            result.add(new TypeDefinitionBuilderImpl(moduleName, line, qname, schemaPath, ((ExtendedType) node)));
+            result.add(new TypeDefinitionBuilderImpl(moduleName, line, qname, schemaPath, (ExtendedType) node));
         }
         return result;
     }
@@ -806,8 +805,8 @@ public final class BuilderUtils {
         }
     }
 
-    public static ModuleBuilder findModule(final QName qname, final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
-        TreeMap<Date, ModuleBuilder> map = modules.get(qname.getNamespace());
+    public static ModuleBuilder findModule(final QName qname, final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
+        NavigableMap<Date, ModuleBuilder> map = modules.get(qname.getNamespace());
         if (map == null) {
             return null;
         }
@@ -817,9 +816,9 @@ public final class BuilderUtils {
         return map.get(qname.getRevision());
     }
 
-    public static Map<String, TreeMap<Date, URI>> createYangNamespaceContext(
+    public static Map<String, NavigableMap<Date, URI>> createYangNamespaceContext(
             final Collection<? extends ParseTree> modules, final Optional<SchemaContext> context) {
-        Map<String, TreeMap<Date, URI>> namespaceContext = new HashMap<>();
+        Map<String, NavigableMap<Date, URI>> namespaceContext = new HashMap<>();
         Set<Submodule_stmtContext> submodules = new HashSet<>();
         // first read ParseTree collection and separate modules and submodules
         for (ParseTree module : modules) {
@@ -858,7 +857,7 @@ public final class BuilderUtils {
                         }
                     }
                     // update namespaceContext
-                    TreeMap<Date, URI> revToNs = namespaceContext.get(moduleName);
+                    NavigableMap<Date, URI> revToNs = namespaceContext.get(moduleName);
                     if (revToNs == null) {
                         revToNs = new TreeMap<>();
                         revToNs.put(rev, namespace);
@@ -872,7 +871,7 @@ public final class BuilderUtils {
         // from SchemaContext
         if (context.isPresent()) {
             for (Module module : context.get().getModules()) {
-                TreeMap<Date, URI> revToNs = namespaceContext.get(module.getName());
+                NavigableMap<Date, URI> revToNs = namespaceContext.get(module.getName());
                 if (revToNs == null) {
                     revToNs = new TreeMap<>();
                     revToNs.put(module.getRevision(), module.getNamespace());
@@ -892,13 +891,13 @@ public final class BuilderUtils {
                         ParseTree belongsCtx = subHeaderCtx.getChild(j);
                         if (belongsCtx instanceof Belongs_to_stmtContext) {
                             final String belongsTo = ParserListenerUtils.stringFromNode(belongsCtx);
-                            TreeMap<Date, URI> ns = namespaceContext.get(belongsTo);
+                            NavigableMap<Date, URI> ns = namespaceContext.get(belongsTo);
                             if (ns == null) {
                                 throw new YangParseException(moduleName, submodule.getStart().getLine(), String.format(
                                         "Unresolved belongs-to statement: %s", belongsTo));
                             }
                             // submodule get namespace and revision from module
-                            TreeMap<Date, URI> subNs = new TreeMap<>();
+                            NavigableMap<Date, URI> subNs = new TreeMap<>();
                             subNs.put(ns.firstKey(), ns.firstEntry().getValue());
                             namespaceContext.put(moduleName, subNs);
                         }
index 55cf82726d8d104a4d9c32facff1bcf6d77bc6ab..8f9ffa98b48a3e35ec4348d1074e34cc114f7824 100644 (file)
@@ -77,7 +77,7 @@ public final class CopyUtils {
         copy.setAddedByUses(old.isAddedByUses());
         copy.setConfiguration(old.isConfiguration());
         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
-            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
+            copy.addUnknownNodeBuilder(copy(un, copy, updateQName));
         }
 
         return copy;
@@ -105,7 +105,7 @@ public final class CopyUtils {
             copy.addAugmentation(copyAugment(augment, copy));
         }
         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
-            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
+            copy.addUnknownNodeBuilder(copy(un, copy, updateQName));
         }
 
         return copy;
@@ -133,7 +133,7 @@ public final class CopyUtils {
             copy.addUsesNode(copyUses(oldUses, copy));
         }
         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
-            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
+            copy.addUnknownNodeBuilder(copy(un, copy, updateQName));
         }
 
         return copy;
@@ -174,7 +174,7 @@ public final class CopyUtils {
             copy.addAugmentation(copyAugment(augment, copy));
         }
         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
-            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
+            copy.addUnknownNodeBuilder(copy(un, copy, updateQName));
         }
 
         return copy;
@@ -198,7 +198,7 @@ public final class CopyUtils {
         copy.setAddedByUses(old.isAddedByUses());
         copy.setConfiguration(old.isConfiguration());
         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
-            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
+            copy.addUnknownNodeBuilder(copy(un, copy, updateQName));
         }
 
         if (old.getType() == null) {
@@ -231,7 +231,7 @@ public final class CopyUtils {
         copy.setAddedByUses(old.isAddedByUses());
         copy.setConfiguration(old.isConfiguration());
         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
-            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
+            copy.addUnknownNodeBuilder(copy(un, copy, updateQName));
         }
 
         if (old.getType() == null) {
@@ -279,7 +279,7 @@ public final class CopyUtils {
             copy.addAugmentation(copyAugment(augment, copy));
         }
         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
-            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
+            copy.addUnknownNodeBuilder(copy(un, copy, updateQName));
         }
 
         copy.setUserOrdered(old.isUserOrdered());
@@ -314,7 +314,7 @@ public final class CopyUtils {
             copy.addUsesNode(copyUses(oldUses, copy));
         }
         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
-            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
+            copy.addUnknownNodeBuilder(copy(un, copy, updateQName));
         }
 
         return copy;
@@ -352,7 +352,7 @@ public final class CopyUtils {
             }
 
             for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
-                type.addUnknownNodeBuilder((copy(un, type, updateQName)));
+                type.addUnknownNodeBuilder(copy(un, type, updateQName));
             }
 
             type.setRanges(old.getRanges());
@@ -410,7 +410,7 @@ public final class CopyUtils {
             copy.addUsesNode(copyUses(oldUses, copy));
         }
         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
-            copy.addUnknownNodeBuilder((copy(un, copy, false)));
+            copy.addUnknownNodeBuilder(copy(un, copy, false));
         }
 
         return copy;
@@ -433,7 +433,7 @@ public final class CopyUtils {
         c.setStatus(old.getStatus());
         c.setAddedByUses(old.isAddedByUses());
         for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
-            c.addUnknownNodeBuilder((copy(un, c, updateQName)));
+            c.addUnknownNodeBuilder(copy(un, c, updateQName));
         }
         c.setExtensionBuilder(old.getExtensionBuilder());
         c.setExtensionDefinition(old.getExtensionDefinition());
index e1792c899f7fc1af26caf0c5f4559a3864cd94f3..eb06329eaab9ddd3ab3bbc1c62bf695d284e7ad1 100644 (file)
@@ -12,8 +12,8 @@ import java.net.URI;
 import java.util.Comparator;
 import java.util.Date;
 import java.util.Map;
+import java.util.NavigableMap;
 import java.util.Set;
-import java.util.TreeMap;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
@@ -29,7 +29,6 @@ import org.slf4j.LoggerFactory;
 public final class GroupingUtils {
     private static final Logger LOG = LoggerFactory.getLogger(GroupingUtils.class);
 
-    private static final Splitter COLON_SPLITTER = Splitter.on(':');
     private static final Splitter SLASH_SPLITTER = Splitter.on('/');
 
     private GroupingUtils() {
@@ -49,7 +48,7 @@ public final class GroupingUtils {
      *             if no grouping found
      */
     public static GroupingBuilder getTargetGroupingFromModules(final UsesNodeBuilder usesBuilder,
-            final Map<URI, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
+            final Map<URI, NavigableMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         final int line = usesBuilder.getLine();
 
         SchemaPath groupingPath = usesBuilder.getTargetGroupingPath();
index 7cac743689c5b8f8e51e66525fbe1ac593a06d56..120ebad9575f78081406eaa581fc3b203931042b 100644 (file)
@@ -61,6 +61,8 @@ import org.opendaylight.yangtools.yang.parser.util.YangParseException;
  */
 public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder implements DocumentedNodeBuilder {
 
+    private static final String GROUPING_STR = "Grouping";
+    private static final String TYPEDEF_STR = "typedef";
     private ModuleImpl instance;
     private final String name;
     private final String sourcePath;
@@ -443,8 +445,8 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
 
     public ExtensionBuilder addExtension(final QName qname, final int line, final SchemaPath path) {
         checkNotSealed();
-        Builder parent = getActualNode();
-        if (!(parent.equals(this))) {
+        Builder parentBuilder = getActualNode();
+        if (!(parentBuilder.equals(this))) {
             throw new YangParseException(name, line, "extension can be defined only in module or submodule");
         }
 
@@ -455,7 +457,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
             }
         }
         final ExtensionBuilder builder = new ExtensionBuilderImpl(name, line, qname, path);
-        builder.setParent(parent);
+        builder.setParent(parentBuilder);
         addedExtensions.add(builder);
         return builder;
     }
@@ -464,9 +466,9 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         checkNotSealed();
         final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath);
 
-        Builder parent = getActualNode();
-        builder.setParent(parent);
-        addChildToParent(parent, builder, qname.getLocalName());
+        Builder parentBuilder = getActualNode();
+        builder.setParent(parentBuilder);
+        addChildToParent(parentBuilder, builder, qname.getLocalName());
 
         return builder;
     }
@@ -475,9 +477,9 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         checkNotSealed();
         final ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(name, line, qname, schemaPath);
 
-        Builder parent = getActualNode();
-        builder.setParent(parent);
-        addChildToParent(parent, builder, qname.getLocalName());
+        Builder parentBuilder = getActualNode();
+        builder.setParent(parentBuilder);
+        addChildToParent(parentBuilder, builder, qname.getLocalName());
         allLists.add(builder);
 
         return builder;
@@ -487,9 +489,9 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         checkNotSealed();
         final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(name, line, qname, schemaPath);
 
-        Builder parent = getActualNode();
-        builder.setParent(parent);
-        addChildToParent(parent, builder, qname.getLocalName());
+        Builder parentBuilder = getActualNode();
+        builder.setParent(parentBuilder);
+        addChildToParent(parentBuilder, builder, qname.getLocalName());
 
         return builder;
     }
@@ -498,9 +500,9 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         checkNotSealed();
         final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(name, line, qname, schemaPath);
 
-        Builder parent = getActualNode();
-        builder.setParent(parent);
-        addChildToParent(parent, builder, qname.getLocalName());
+        Builder parentBuilder = getActualNode();
+        builder.setParent(parentBuilder);
+        addChildToParent(parentBuilder, builder, qname.getLocalName());
 
         return builder;
     }
@@ -509,31 +511,31 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         checkNotSealed();
         final GroupingBuilder builder = new GroupingBuilderImpl(name, line, qname, path);
 
-        Builder parent = getActualNode();
-        builder.setParent(parent);
+        Builder parentBuilder = getActualNode();
+        builder.setParent(parentBuilder);
 
         String groupingName = qname.getLocalName();
-        if (parent.equals(this)) {
+        if (parentBuilder.equals(this)) {
             for (GroupingBuilder addedGrouping : getGroupingBuilders()) {
                 if (addedGrouping.getQName().getLocalName().equals(groupingName)) {
-                    raiseYangParserException("", "Grouping", groupingName, line, addedGrouping.getLine());
+                    raiseYangParserException("", GROUPING_STR, groupingName, line, addedGrouping.getLine());
                 }
             }
             addGrouping(builder);
         } else {
-            if (parent instanceof DataNodeContainerBuilder) {
-                DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent;
+            if (parentBuilder instanceof DataNodeContainerBuilder) {
+                DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parentBuilder;
                 for (GroupingBuilder addedGrouping : parentNode.getGroupingBuilders()) {
                     if (addedGrouping.getQName().getLocalName().equals(groupingName)) {
-                        raiseYangParserException("", "Grouping", groupingName, line, addedGrouping.getLine());
+                        raiseYangParserException("", GROUPING_STR, groupingName, line, addedGrouping.getLine());
                     }
                 }
                 parentNode.addGrouping(builder);
-            } else if (parent instanceof RpcDefinitionBuilder) {
-                RpcDefinitionBuilder parentNode = (RpcDefinitionBuilder) parent;
+            } else if (parentBuilder instanceof RpcDefinitionBuilder) {
+                RpcDefinitionBuilder parentNode = (RpcDefinitionBuilder) parentBuilder;
                 for (GroupingBuilder child : parentNode.getGroupings()) {
                     if (child.getQName().getLocalName().equals(groupingName)) {
-                        raiseYangParserException("", "Grouping", groupingName, line, child.getLine());
+                        raiseYangParserException("", GROUPING_STR, groupingName, line, child.getLine());
                     }
                 }
                 parentNode.addGrouping(builder);
@@ -552,10 +554,10 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(name, line, augmentTargetStr,
                 targetPath, order);
 
-        Builder parent = getActualNode();
-        builder.setParent(parent);
+        Builder parentBuilder = getActualNode();
+        builder.setParent(parentBuilder);
 
-        if (parent.equals(this)) {
+        if (parentBuilder.equals(this)) {
             // augment can be declared only under 'module' ...
             if (!(augmentTargetStr.startsWith("/"))) {
                 throw new YangParseException(
@@ -566,13 +568,13 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
             augmentBuilders.add(builder);
         } else {
             // ... or 'uses' statement
-            if (parent instanceof UsesNodeBuilder) {
+            if (parentBuilder instanceof UsesNodeBuilder) {
                 if (augmentTargetStr.startsWith("/")) {
                     throw new YangParseException(name, line,
                             "If 'augment' statement is a substatement to the 'uses' statement, it cannot contain absolute path ("
                                     + augmentTargetStr + ")");
                 }
-                ((UsesNodeBuilder) parent).addAugment(builder);
+                ((UsesNodeBuilder) parentBuilder).addAugment(builder);
             } else {
                 throw new YangParseException(name, line, "Augment can be declared only under module or uses statement.");
             }
@@ -586,18 +588,18 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         checkNotSealed();
         final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(name, line, grouping);
 
-        Builder parent = getActualNode();
-        usesBuilder.setParent(parent);
+        Builder parentBuilder = getActualNode();
+        usesBuilder.setParent(parentBuilder);
 
-        if (parent.equals(this)) {
+        if (parentBuilder.equals(this)) {
             addUsesNode(usesBuilder);
         } else {
-            if (!(parent instanceof DataNodeContainerBuilder)) {
+            if (!(parentBuilder instanceof DataNodeContainerBuilder)) {
                 throw new YangParseException(name, line, "Unresolved parent of uses '" + grouping + "'.");
             }
-            ((DataNodeContainerBuilder) parent).addUsesNode(usesBuilder);
+            ((DataNodeContainerBuilder) parentBuilder).addUsesNode(usesBuilder);
         }
-        if (parent instanceof AugmentationSchemaBuilder) {
+        if (parentBuilder instanceof AugmentationSchemaBuilder) {
             usesBuilder.setAugmenting(true);
         }
 
@@ -607,23 +609,23 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
 
     public void addRefine(final RefineHolderImpl refine) {
         checkNotSealed();
-        final Builder parent = getActualNode();
-        if (!(parent instanceof UsesNodeBuilder)) {
+        final Builder parentBuilder = getActualNode();
+        if (!(parentBuilder instanceof UsesNodeBuilder)) {
             throw new YangParseException(name, refine.getLine(), "refine can be defined only in uses statement");
         }
-        ((UsesNodeBuilder) parent).addRefine(refine);
-        refine.setParent(parent);
+        ((UsesNodeBuilder) parentBuilder).addRefine(refine);
+        refine.setParent(parentBuilder);
     }
 
     public RpcDefinitionBuilder addRpc(final int line, final QName qname, final SchemaPath path) {
         checkNotSealed();
-        Builder parent = getActualNode();
-        if (!(parent.equals(this))) {
+        Builder parentBuilder = getActualNode();
+        if (!(parentBuilder.equals(this))) {
             throw new YangParseException(name, line, "rpc can be defined only in module or submodule");
         }
 
         final RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(name, line, qname, path);
-        rpcBuilder.setParent(parent);
+        rpcBuilder.setParent(parentBuilder);
 
         String rpcName = qname.getLocalName();
         checkNotConflictingInDataNamespace(rpcName, line);
@@ -651,11 +653,11 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
 
     public ContainerSchemaNodeBuilder addRpcInput(final int line, final QName qname, final SchemaPath schemaPath) {
         checkNotSealed();
-        final Builder parent = getActualNode();
-        if (!(parent instanceof RpcDefinitionBuilder)) {
+        final Builder parentBuilder = getActualNode();
+        if (!(parentBuilder instanceof RpcDefinitionBuilder)) {
             throw new YangParseException(name, line, "input can be defined only in rpc statement");
         }
-        final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent;
+        final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parentBuilder;
 
         final ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath);
         inputBuilder.setParent(rpc);
@@ -666,11 +668,11 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
 
     public ContainerSchemaNodeBuilder addRpcOutput(final SchemaPath schemaPath, final QName qname, final int line) {
         checkNotSealed();
-        final Builder parent = getActualNode();
-        if (!(parent instanceof RpcDefinitionBuilder)) {
+        final Builder parentBuilder = getActualNode();
+        if (!(parentBuilder instanceof RpcDefinitionBuilder)) {
             throw new YangParseException(name, line, "output can be defined only in rpc statement");
         }
-        final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent;
+        final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parentBuilder;
 
         final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath);
         outputBuilder.setParent(rpc);
@@ -686,8 +688,8 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
 
     public NotificationBuilder addNotification(final int line, final QName qname, final SchemaPath path) {
         checkNotSealed();
-        final Builder parent = getActualNode();
-        if (!(parent.equals(this))) {
+        final Builder parentBuilder = getActualNode();
+        if (!(parentBuilder.equals(this))) {
             throw new YangParseException(name, line, "notification can be defined only in module or submodule");
         }
 
@@ -695,20 +697,20 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         checkNotConflictingInDataNamespace(notificationName, line);
 
         final NotificationBuilder builder = new NotificationBuilder(name, line, qname, path);
-        builder.setParent(parent);
+        builder.setParent(parentBuilder);
         addedNotifications.add(builder);
 
         return builder;
     }
 
     public FeatureBuilder addFeature(final int line, final QName qname, final SchemaPath path) {
-        Builder parent = getActualNode();
-        if (!(parent.equals(this))) {
+        Builder parentBuilder = getActualNode();
+        if (!(parentBuilder.equals(this))) {
             throw new YangParseException(name, line, "feature can be defined only in module or submodule");
         }
 
         final FeatureBuilder builder = new FeatureBuilder(name, line, qname, path);
-        builder.setParent(parent);
+        builder.setParent(parentBuilder);
 
         String featureName = qname.getLocalName();
         for (FeatureBuilder addedFeature : addedFeatures) {
@@ -723,26 +725,26 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     public ChoiceBuilder addChoice(final int line, final QName qname, final SchemaPath path) {
         final ChoiceBuilder builder = new ChoiceBuilder(name, line, qname, path);
 
-        Builder parent = getActualNode();
-        builder.setParent(parent);
-        addChildToParent(parent, builder, qname.getLocalName());
+        Builder parentBuilder = getActualNode();
+        builder.setParent(parentBuilder);
+        addChildToParent(parentBuilder, builder, qname.getLocalName());
 
         return builder;
     }
 
     public ChoiceCaseBuilder addCase(final int line, final QName qname, final SchemaPath path) {
-        Builder parent = getActualNode();
-        if (parent == null || parent.equals(this)) {
+        Builder parentBuilder = getActualNode();
+        if (parentBuilder == null || parentBuilder.equals(this)) {
             throw new YangParseException(name, line, "'case' parent not found");
         }
 
         final ChoiceCaseBuilder builder = new ChoiceCaseBuilder(name, line, qname, path);
-        builder.setParent(parent);
+        builder.setParent(parentBuilder);
 
-        if (parent instanceof ChoiceBuilder) {
-            ((ChoiceBuilder) parent).addCase(builder);
-        } else if (parent instanceof AugmentationSchemaBuilder) {
-            ((AugmentationSchemaBuilder) parent).addChildNode(builder);
+        if (parentBuilder instanceof ChoiceBuilder) {
+            ((ChoiceBuilder) parentBuilder).addCase(builder);
+        } else if (parentBuilder instanceof AugmentationSchemaBuilder) {
+            ((AugmentationSchemaBuilder) parentBuilder).addChildNode(builder);
         } else {
             throw new YangParseException(name, line, "Unresolved parent of 'case' " + qname.getLocalName());
         }
@@ -753,9 +755,9 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     public AnyXmlBuilder addAnyXml(final int line, final QName qname, final SchemaPath schemaPath) {
         final AnyXmlBuilder builder = new AnyXmlBuilder(name, line, qname, schemaPath);
 
-        Builder parent = getActualNode();
-        builder.setParent(parent);
-        addChildToParent(parent, builder, qname.getLocalName());
+        Builder parentBuilder = getActualNode();
+        builder.setParent(parentBuilder);
+        addChildToParent(parentBuilder, builder, qname.getLocalName());
 
         return builder;
     }
@@ -765,7 +767,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         String nodeName = typedefBuilder.getQName().getLocalName();
         for (TypeDefinitionBuilder tdb : getTypeDefinitionBuilders()) {
             if (tdb.getQName().getLocalName().equals(nodeName)) {
-                raiseYangParserException("", "typedef", nodeName, typedefBuilder.getLine(), tdb.getLine());
+                raiseYangParserException("", TYPEDEF_STR, nodeName, typedefBuilder.getLine(), tdb.getLine());
             }
         }
         super.addTypedef(typedefBuilder);
@@ -774,26 +776,26 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     public TypeDefinitionBuilderImpl addTypedef(final int line, final QName qname, final SchemaPath path) {
         final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(name, line, qname, path);
 
-        Builder parent = getActualNode();
-        builder.setParent(parent);
+        Builder parentBuilder = getActualNode();
+        builder.setParent(parentBuilder);
 
         String typedefName = qname.getLocalName();
-        if (parent.equals(this)) {
+        if (parentBuilder.equals(this)) {
             addTypedef(builder);
         } else {
-            if (parent instanceof DataNodeContainerBuilder) {
-                DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent;
+            if (parentBuilder instanceof DataNodeContainerBuilder) {
+                DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parentBuilder;
                 for (TypeDefinitionBuilder child : parentNode.getTypeDefinitionBuilders()) {
                     if (child.getQName().getLocalName().equals(typedefName)) {
-                        raiseYangParserException("", "typedef", typedefName, line, child.getLine());
+                        raiseYangParserException("", TYPEDEF_STR, typedefName, line, child.getLine());
                     }
                 }
                 parentNode.addTypedef(builder);
-            } else if (parent instanceof RpcDefinitionBuilder) {
-                RpcDefinitionBuilder rpcParent = (RpcDefinitionBuilder) parent;
+            } else if (parentBuilder instanceof RpcDefinitionBuilder) {
+                RpcDefinitionBuilder rpcParent = (RpcDefinitionBuilder) parentBuilder;
                 for (TypeDefinitionBuilder tdb : rpcParent.getTypeDefinitions()) {
                     if (tdb.getQName().getLocalName().equals(builder.getQName().getLocalName())) {
-                        raiseYangParserException("", "typedef", typedefName, line, tdb.getLine());
+                        raiseYangParserException("", TYPEDEF_STR, typedefName, line, tdb.getLine());
                     }
                 }
                 rpcParent.addTypedef(builder);
@@ -806,22 +808,22 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public void setType(final TypeDefinition<?> type) {
-        Builder parent = getActualNode();
-        if (!(parent instanceof TypeAwareBuilder)) {
+        Builder parentBuilder = getActualNode();
+        if (!(parentBuilder instanceof TypeAwareBuilder)) {
             throw new YangParseException("Failed to set type '" + type.getQName().getLocalName()
-                    + "'. Invalid parent node: " + parent);
+                    + "'. Invalid parent node: " + parentBuilder);
         }
-        ((TypeAwareBuilder) parent).setType(type);
+        ((TypeAwareBuilder) parentBuilder).setType(type);
     }
 
     public UnionTypeBuilder addUnionType(final int line, final QNameModule module) {
-        final Builder parent = getActualNode();
-        if (parent == null) {
+        final Builder parentBuilder = getActualNode();
+        if (parentBuilder == null) {
             throw new YangParseException(name, line, "Unresolved parent of union type");
         } else {
             final UnionTypeBuilder union = new UnionTypeBuilder(name, line);
-            if (parent instanceof TypeAwareBuilder) {
-                ((TypeAwareBuilder) parent).setTypedef(union);
+            if (parentBuilder instanceof TypeAwareBuilder) {
+                ((TypeAwareBuilder) parentBuilder).setTypedef(union);
                 return union;
             } else {
                 throw new YangParseException(name, line, "Invalid parent of union type.");
@@ -832,12 +834,12 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     public void addIdentityrefType(final int line, final SchemaPath schemaPath, final String baseString) {
         final IdentityrefTypeBuilder identityref = new IdentityrefTypeBuilder(name, line, baseString, schemaPath);
 
-        final Builder parent = getActualNode();
-        if (parent == null) {
+        final Builder parentBuilder = getActualNode();
+        if (parentBuilder == null) {
             throw new YangParseException(name, line, "Unresolved parent of identityref type.");
         } else {
-            if (parent instanceof TypeAwareBuilder) {
-                final TypeAwareBuilder typeParent = (TypeAwareBuilder) parent;
+            if (parentBuilder instanceof TypeAwareBuilder) {
+                final TypeAwareBuilder typeParent = (TypeAwareBuilder) parentBuilder;
                 typeParent.setTypedef(identityref);
                 dirtyNodes.add(typeParent);
             } else {
@@ -847,20 +849,20 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public DeviationBuilder addDeviation(final int line, final SchemaPath targetPath) {
-        Builder parent = getActualNode();
-        if (!(parent.equals(this))) {
+        Builder parentBuilder = getActualNode();
+        if (!(parentBuilder.equals(this))) {
             throw new YangParseException(name, line, "deviation can be defined only in module or submodule");
         }
 
         final DeviationBuilder builder = new DeviationBuilder(name, line, targetPath);
-        builder.setParent(parent);
+        builder.setParent(parentBuilder);
         deviationBuilders.add(builder);
         return builder;
     }
 
     public IdentitySchemaNodeBuilder addIdentity(final QName qname, final int line, final SchemaPath path) {
-        Builder parent = getActualNode();
-        if (!(parent.equals(this))) {
+        Builder parentBuilder = getActualNode();
+        if (!(parentBuilder.equals(this))) {
             throw new YangParseException(name, line, "identity can be defined only in module or submodule");
         }
         String identityName = qname.getLocalName();
@@ -871,7 +873,7 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         }
 
         final IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder(name, line, qname, path);
-        builder.setParent(parent);
+        builder.setParent(parentBuilder);
         addedIdentities.add(builder);
         return builder;
     }
@@ -883,20 +885,20 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     }
 
     public UnknownSchemaNodeBuilderImpl addUnknownSchemaNode(final int line, final QName qname, final SchemaPath path) {
-        final Builder parent = getActualNode();
+        final Builder parentBuilder = getActualNode();
         final UnknownSchemaNodeBuilderImpl builder = new UnknownSchemaNodeBuilderImpl(name, line, qname, path);
-        builder.setParent(parent);
+        builder.setParent(parentBuilder);
         allUnknownNodes.add(builder);
 
-        if (parent.equals(this)) {
+        if (parentBuilder.equals(this)) {
             addedUnknownNodes.add(builder);
         } else {
-            if (parent instanceof SchemaNodeBuilder) {
-                parent.addUnknownNodeBuilder(builder);
-            } else if (parent instanceof DataNodeContainerBuilder) {
-                parent.addUnknownNodeBuilder(builder);
-            } else if (parent instanceof RefineHolderImpl) {
-                parent.addUnknownNodeBuilder(builder);
+            if (parentBuilder instanceof SchemaNodeBuilder) {
+                parentBuilder.addUnknownNodeBuilder(builder);
+            } else if (parentBuilder instanceof DataNodeContainerBuilder) {
+                parentBuilder.addUnknownNodeBuilder(builder);
+            } else if (parentBuilder instanceof RefineHolderImpl) {
+                parentBuilder.addUnknownNodeBuilder(builder);
             } else {
                 throw new YangParseException(name, line, "Unresolved parent of unknown node '" + qname.getLocalName()
                         + "'");
index 00018b8dda1128e20704ac15f5b89d9fff0859e4..f6f152fd35b2dbe441e73d9d01bed6085063b9e2 100644 (file)
@@ -8,6 +8,7 @@ import java.net.URI;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
+import java.util.NavigableSet;
 import java.util.Set;
 import java.util.TreeSet;
 import org.opendaylight.yangtools.concepts.Immutable;
@@ -220,7 +221,7 @@ public final class ModuleImpl extends AbstractDocumentedDataNodeContainer implem
     }
 
     private static <T extends SchemaNode> Set<T> toImmutableSortedSet(final Set<T> original) {
-        TreeSet<T> sorted = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
+        NavigableSet<T> sorted = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
         sorted.addAll(original);
         return Collections.unmodifiableSet(sorted);
     }
index 25ad30e2dbb121cedc5040afbfe0c806cc11f5c5..1d035a125d64c6f6334bba179dae3a593ae21c8b 100644 (file)
@@ -32,6 +32,11 @@ public final class RpcDefinitionBuilder extends AbstractSchemaNodeBuilder {
     private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<>();
     private final Set<GroupingBuilder> addedGroupings = new HashSet<>();
 
+    RpcDefinitionBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path) {
+        super(moduleName, line, qname);
+        this.schemaPath = Preconditions.checkNotNull(path, "Schema Path must not be null");
+    }
+
     public ContainerSchemaNodeBuilder getInput() {
         return inputBuilder;
     }
@@ -40,11 +45,6 @@ public final class RpcDefinitionBuilder extends AbstractSchemaNodeBuilder {
         return outputBuilder;
     }
 
-    RpcDefinitionBuilder(final String moduleName, final int line, final QName qname, final SchemaPath path) {
-        super(moduleName, line, qname);
-        this.schemaPath = Preconditions.checkNotNull(path, "Schema Path must not be null");
-    }
-
     @Override
     public RpcDefinition build() {
         if (instance != null) {
index ad1afc255bebd9177cfef8d885532124c7ab0719..a02baead8db8fb394e9d6514d84fdec4f66c3abb 100644 (file)
@@ -12,8 +12,8 @@ import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.f
 import java.net.URI;
 import java.util.Date;
 import java.util.Map;
+import java.util.NavigableMap;
 import java.util.Set;
-import java.util.TreeMap;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
@@ -49,7 +49,7 @@ public final class TypeUtils {
      *            current module
      */
     public static void resolveType(final TypeAwareBuilder nodeToResolve,
-            final Map<URI, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
+            final Map<URI, NavigableMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         QName unknownTypeQName = nodeToResolve.getTypeQName();
         final ModuleBuilder dependentModuleBuilder = BuilderUtils.findModule(unknownTypeQName, modules);
         if (dependentModuleBuilder == null) {
@@ -72,7 +72,7 @@ public final class TypeUtils {
      *            current module
      */
     public static void resolveTypeUnion(final UnionTypeBuilder union,
-            final Map<URI, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
+            final Map<URI, NavigableMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         // special handling for identityref types under union
         for (TypeDefinitionBuilder unionType : union.getTypedefs()) {
             if (unionType instanceof IdentityrefTypeBuilder) {
@@ -111,7 +111,7 @@ public final class TypeUtils {
      * @return TypeDefinitionBuilder of node type
      */
     private static TypeDefinitionBuilder findUnknownTypeDefinition(final TypeAwareBuilder nodeToResolve,
-            final ModuleBuilder dependentModuleBuilder, final Map<URI, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder dependentModuleBuilder, final Map<URI, NavigableMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module) {
         final int line = nodeToResolve.getLine();
         final QName unknownTypeQName = nodeToResolve.getTypeQName();
@@ -175,7 +175,7 @@ public final class TypeUtils {
     }
 
     private static TypeConstraints findConstraintsFromTypeBuilder(final TypeAwareBuilder nodeToResolve,
-            final TypeConstraints constraints, final Map<URI, TreeMap<Date, ModuleBuilder>> modules,
+            final TypeConstraints constraints, final Map<URI, NavigableMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder builder) {
 
         // union and identityref types cannot be restricted
index 5c79161116084e13f402067b4ed17ce2dee78c20..8ee273e8172a42974d7cdf2b65fa9a1249ef3956 100644 (file)
@@ -261,7 +261,7 @@ final class BasicValidations {
         Iterable<String> keyList = ValidationUtil.listKeysFromId(key);
         Set<String> duplicates = ValidationUtil.getDuplicates(keyList);
 
-        if (duplicates.size() != 0) {
+        if (!duplicates.isEmpty()) {
             ValidationUtil.ex(ValidationUtil.f("(In (sub)module:%s) %s:%s, %s:%s contains duplicates:%s",
                     rootParentName, ValidationUtil.getSimpleStatementName(parent.getClass()),
                     ValidationUtil.getName(parent), ValidationUtil.getSimpleStatementName(ctx.getClass()), key,
index 5684c045d5a08d1412b48bfdf3db5a28f2b7e21d..fdc8369f4ada260763c4fc4f2a88f906aa1f5d79 100644 (file)
@@ -141,7 +141,7 @@ public final class YangParserImpl implements YangContextParser {
 
         // module builders sorted by dependencies
         List<ModuleBuilder> sortedBuilders = ModuleDependencySort.sort(resolved);
-        Map<URI, TreeMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sortedBuilders, null);
+        Map<URI, NavigableMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sortedBuilders, null);
         Collection<Module> unsorted = build(modules).values();
         Set<Module> result = new LinkedHashSet<>(
                 ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()])));
@@ -218,7 +218,7 @@ public final class YangParserImpl implements YangContextParser {
         }
 
         final List<ModuleBuilder> sorted = resolveModuleBuilders(sources, context);
-        final Map<URI, TreeMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, context);
+        final Map<URI, NavigableMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, context);
 
         final Set<Module> unsorted = new LinkedHashSet<>(build(modules).values());
         if (context != null) {
@@ -233,9 +233,9 @@ public final class YangParserImpl implements YangContextParser {
         return resolveSchemaContext(result);
     }
 
-    private static Map<URI, TreeMap<Date, ModuleBuilder>> resolveModulesWithImports(final List<ModuleBuilder> sorted,
+    private static Map<URI, NavigableMap<Date, ModuleBuilder>> resolveModulesWithImports(final List<ModuleBuilder> sorted,
             final SchemaContext context) {
-        final Map<URI, TreeMap<Date, ModuleBuilder>> modules = orderModules(sorted);
+        final Map<URI, NavigableMap<Date, ModuleBuilder>> modules = orderModules(sorted);
         for (ModuleBuilder module : sorted) {
             if (module != null) {
                 for (ModuleImport imp : module.getImports().values()) {
@@ -244,7 +244,7 @@ public final class YangParserImpl implements YangContextParser {
                     if (targetModule == null) {
                         Module result = findModuleFromContext(context, module, prefix, 0);
                         targetModule = new ModuleBuilder(result);
-                        TreeMap<Date, ModuleBuilder> map = modules.get(targetModule.getNamespace());
+                        NavigableMap<Date, ModuleBuilder> map = modules.get(targetModule.getNamespace());
                         if (map == null) {
                             map = new TreeMap<>();
                             map.put(targetModule.getRevision(), targetModule);
@@ -335,7 +335,7 @@ public final class YangParserImpl implements YangContextParser {
     public Collection<Module> buildModules(final Collection<ModuleBuilder> builders) {
         Collection<ModuleBuilder> unsorted = resolveSubmodules(builders);
         List<ModuleBuilder> sorted = ModuleDependencySort.sort(unsorted);
-        Map<URI, TreeMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, null);
+        Map<URI, NavigableMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, null);
         Map<ModuleBuilder, Module> builderToModule = build(modules);
         return builderToModule.values();
     }
@@ -354,7 +354,7 @@ public final class YangParserImpl implements YangContextParser {
         Map<ByteSource, ModuleBuilder> sourceToBuilder = resolveSources(sources, context);
         // sort and check for duplicates
         List<ModuleBuilder> sorted = ModuleDependencySort.sort(sourceToBuilder.values());
-        Map<URI, TreeMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, null);
+        Map<URI, NavigableMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, null);
         Map<ModuleBuilder, Module> builderToModule = build(modules);
         Map<ModuleBuilder, ByteSource> builderToSource = HashBiMap.create(sourceToBuilder).inverse();
         sorted = ModuleDependencySort.sort(builderToModule.keySet());
@@ -392,7 +392,7 @@ public final class YangParserImpl implements YangContextParser {
         // validate yang
         new YangModelBasicValidator(walker).validate(sourceToTree.values());
 
-        Map<String, TreeMap<Date, URI>> namespaceContext = BuilderUtils.createYangNamespaceContext(
+        Map<String, NavigableMap<Date, URI>> namespaceContext = BuilderUtils.createYangNamespaceContext(
                 sourceToTree.values(), Optional.fromNullable(context));
         YangParserListenerImpl yangModelParser;
         for (Map.Entry<ByteSource, ParseTree> entry : sourceToTree.entrySet()) {
@@ -416,12 +416,12 @@ public final class YangParserImpl implements YangContextParser {
 
     private Map<ByteSource, ModuleBuilder> resolveSubmodules(final Map<ByteSource, ModuleBuilder> builders) {
         Map<ByteSource, ModuleBuilder> modules = new HashMap<>();
-        Map<String, TreeMap<Date, ModuleBuilder>> submodules = new HashMap<>();
+        Map<String, NavigableMap<Date, ModuleBuilder>> submodules = new HashMap<>();
         for (Map.Entry<ByteSource, ModuleBuilder> entry : builders.entrySet()) {
             ModuleBuilder builder = entry.getValue();
             if (builder.isSubmodule()) {
                 String submoduleName = builder.getName();
-                TreeMap<Date, ModuleBuilder> map = submodules.get(submoduleName);
+                NavigableMap<Date, ModuleBuilder> map = submodules.get(submoduleName);
                 if (map == null) {
                     map = new TreeMap<>();
                     map.put(builder.getRevision(), builder);
@@ -443,11 +443,11 @@ public final class YangParserImpl implements YangContextParser {
 
     private Collection<ModuleBuilder> resolveSubmodules(final Collection<ModuleBuilder> builders) {
         Collection<ModuleBuilder> modules = new HashSet<>();
-        Map<String, TreeMap<Date, ModuleBuilder>> submodules = new HashMap<>();
+        Map<String, NavigableMap<Date, ModuleBuilder>> submodules = new HashMap<>();
         for (ModuleBuilder builder : builders) {
             if (builder.isSubmodule()) {
                 String submoduleName = builder.getName();
-                TreeMap<Date, ModuleBuilder> map = submodules.get(submoduleName);
+                NavigableMap<Date, ModuleBuilder> map = submodules.get(submoduleName);
                 if (map == null) {
                     map = new TreeMap<>();
                     map.put(builder.getRevision(), builder);
@@ -478,7 +478,7 @@ public final class YangParserImpl implements YangContextParser {
      * @return collection of module builders with resolved submodules
      */
     private void resolveSubmodules(final ModuleBuilder module,
-            final Map<String, TreeMap<Date, ModuleBuilder>> submodules) {
+            final Map<String, NavigableMap<Date, ModuleBuilder>> submodules) {
         Map<String, Date> includes = module.getIncludedModules();
         for (Map.Entry<String, Date> entry : includes.entrySet()) {
             NavigableMap<Date, ModuleBuilder> subs = submodules.get(entry.getKey());
@@ -499,7 +499,7 @@ public final class YangParserImpl implements YangContextParser {
                 }
             }
 
-            if (submodule.getIncludedModules().size() > 0) {
+            if (!submodule.getIncludedModules().isEmpty()) {
                 resolveSubmodules(submodule, submodules);
             }
             addSubmoduleToModule(submodule, module);
@@ -563,8 +563,8 @@ public final class YangParserImpl implements YangContextParser {
      *            topologically sorted modules
      * @return modules ordered by namespace and revision
      */
-    private static Map<URI, TreeMap<Date, ModuleBuilder>> orderModules(final List<ModuleBuilder> modules) {
-        final Map<URI, TreeMap<Date, ModuleBuilder>> result = new LinkedHashMap<>();
+    private static Map<URI, NavigableMap<Date, ModuleBuilder>> orderModules(final List<ModuleBuilder> modules) {
+        final Map<URI, NavigableMap<Date, ModuleBuilder>> result = new LinkedHashMap<>();
         for (final ModuleBuilder builder : modules) {
             if (builder == null) {
                 continue;
@@ -576,7 +576,7 @@ public final class YangParserImpl implements YangContextParser {
                 rev = new Date(0);
             }
 
-            TreeMap<Date, ModuleBuilder> builderByRevision = result.get(ns);
+            NavigableMap<Date, ModuleBuilder> builderByRevision = result.get(ns);
             if (builderByRevision == null) {
                 builderByRevision = new TreeMap<>();
                 builderByRevision.put(rev, builder);
@@ -606,7 +606,7 @@ public final class YangParserImpl implements YangContextParser {
 
         // if this is submodule, add parent to filtered and pick its imports
         if (main.isSubmodule()) {
-            TreeMap<Date, ModuleBuilder> dependencies = new TreeMap<>();
+            NavigableMap<Date, ModuleBuilder> dependencies = new TreeMap<>();
             for (ModuleBuilder mb : other) {
                 if (mb.getName().equals(main.getBelongsTo())) {
                     dependencies.put(mb.getRevision(), mb);
@@ -626,11 +626,9 @@ public final class YangParserImpl implements YangContextParser {
                             filterImports(builder, other, filtered);
                         }
                     } else {
-                        if (mi.getRevision().equals(builder.getRevision())) {
-                            if (!filtered.contains(builder)) {
-                                filtered.add(builder);
-                                filterImports(builder, other, filtered);
-                            }
+                        if (!filtered.contains(builder) && mi.getRevision().equals(builder.getRevision())) {
+                            filtered.add(builder);
+                            filterImports(builder, other, filtered);
                         }
                     }
                 }
@@ -705,7 +703,7 @@ public final class YangParserImpl implements YangContextParser {
      *            all loaded modules
      * @return modules mapped on their builders
      */
-    private Map<ModuleBuilder, Module> build(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+    private Map<ModuleBuilder, Module> build(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         resolveDirtyNodes(modules);
         resolveAugmentsTargetPath(modules);
         resolveUsesTargetGrouping(modules);
@@ -717,7 +715,7 @@ public final class YangParserImpl implements YangContextParser {
 
         // build
         final Map<ModuleBuilder, Module> result = new LinkedHashMap<>();
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
                 final ModuleBuilder moduleBuilder = childEntry.getValue();
                 final Module module = moduleBuilder.build();
@@ -733,8 +731,8 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void resolveDirtyNodes(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+    private void resolveDirtyNodes(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
                 final ModuleBuilder module = childEntry.getValue();
                 resolveUnknownNodes(modules, module);
@@ -752,7 +750,7 @@ public final class YangParserImpl implements YangContextParser {
      * @param module
      *            current module
      */
-    private void resolveDirtyNodes(final Map<URI, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
+    private void resolveDirtyNodes(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         final Set<TypeAwareBuilder> dirtyNodes = module.getDirtyNodes();
         if (!dirtyNodes.isEmpty()) {
             for (TypeAwareBuilder nodeToResolve : dirtyNodes) {
@@ -783,10 +781,10 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void resolveAugmentsTargetPath(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+    private void resolveAugmentsTargetPath(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         // collect augments from all loaded modules
         final List<AugmentationSchemaBuilder> allAugments = new ArrayList<>();
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
                 allAugments.addAll(inner.getValue().getAllAugments());
             }
@@ -896,9 +894,9 @@ public final class YangParserImpl implements YangContextParser {
      *            all loaded modules topologically sorted (based on dependencies
      *            between each other)
      */
-    private void resolveAugments(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+    private void resolveAugments(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         List<ModuleBuilder> all = new ArrayList<>();
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
                 all.add(inner.getValue());
             }
@@ -934,7 +932,7 @@ public final class YangParserImpl implements YangContextParser {
      * @return true if augment process succeed
      */
     private boolean resolveUsesAugment(final AugmentationSchemaBuilder augment, final ModuleBuilder module,
-            final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+            final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         if (augment.isResolved()) {
             return true;
         }
@@ -994,7 +992,7 @@ public final class YangParserImpl implements YangContextParser {
      * @return true if augment process succeed
      */
     private boolean resolveAugment(final AugmentationSchemaBuilder augment, final ModuleBuilder module,
-            final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+            final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         if (augment.isResolved()) {
             return true;
         }
@@ -1016,8 +1014,8 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void resolveIdentities(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+    private void resolveIdentities(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
                 ModuleBuilder module = inner.getValue();
                 final Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
@@ -1076,9 +1074,9 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void resolveUsesTargetGrouping(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+    private void resolveUsesTargetGrouping(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         final List<UsesNodeBuilder> allUses = new ArrayList<>();
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
                 allUses.addAll(inner.getValue().getAllUsesNodes());
             }
@@ -1097,9 +1095,9 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void resolveUsesForGroupings(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+    private void resolveUsesForGroupings(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         final Set<GroupingBuilder> allGroupings = new HashSet<>();
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
                 ModuleBuilder module = inner.getValue();
                 allGroupings.addAll(module.getAllGroupings());
@@ -1121,8 +1119,8 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void resolveUsesForNodes(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+    private void resolveUsesForNodes(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
                 ModuleBuilder module = inner.getValue();
                 List<UsesNodeBuilder> usesNodes = module.getAllUsesNodes();
@@ -1143,7 +1141,7 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void resolveUses(final UsesNodeBuilder usesNode, final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+    private void resolveUses(final UsesNodeBuilder usesNode, final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         if (!usesNode.isResolved()) {
             DataNodeContainerBuilder parent = usesNode.getParent();
             ModuleBuilder module = BuilderUtils.getParentModule(parent);
@@ -1177,11 +1175,9 @@ public final class YangParserImpl implements YangContextParser {
 
         DataSchemaNodeBuilder nextNodeAfterUses = null;
         for (DataSchemaNodeBuilder childNode : childNodes) {
-            if (!(childNode.isAddedByUses()) && !(childNode.isAugmenting())) {
-                if (childNode.getLine() > usesLine) {
-                    nextNodeAfterUses = childNode;
-                    break;
-                }
+            if (!childNode.isAddedByUses() && !childNode.isAugmenting() && childNode.getLine() > usesLine) {
+                nextNodeAfterUses = childNode;
+                break;
             }
         }
 
@@ -1202,7 +1198,7 @@ public final class YangParserImpl implements YangContextParser {
      * @param module
      *            current module
      */
-    private void resolveUnknownNodes(final Map<URI, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
+    private void resolveUnknownNodes(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) {
             QName nodeType = usnb.getNodeType();
             String localName = usnb.getNodeType().getLocalName();
@@ -1257,8 +1253,8 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void checkChoiceCasesForDuplicityQNames(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+    private void checkChoiceCasesForDuplicityQNames(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
                 final ModuleBuilder moduleBuilder = childEntry.getValue();
                 final Module module = moduleBuilder.build();
@@ -1272,8 +1268,8 @@ public final class YangParserImpl implements YangContextParser {
     }
 
     private void findDuplicityNodesIn(final ChoiceSchemaNode choiceNode, final Module module, final ModuleBuilder moduleBuilder,
-            final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
-        final Set<QName> duplicityTestSet = new HashSet<QName>();
+            final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
+        final Set<QName> duplicityTestSet = new HashSet<>();
 
         for (ChoiceCaseNode choiceCaseNode : choiceNode.getCases()) {
 
@@ -1294,7 +1290,7 @@ public final class YangParserImpl implements YangContextParser {
     }
 
     private List<ChoiceSchemaNode> getChoicesFrom(final Module module) {
-        final List<ChoiceSchemaNode> allChoices = new ArrayList<ChoiceSchemaNode>();
+        final List<ChoiceSchemaNode> allChoices = new ArrayList<>();
 
         for (DataSchemaNode dataSchemaNode : module.getChildNodes()) {
             findChoicesIn(dataSchemaNode, allChoices);
index 77a0a354dfa341e69805bdf0769eaa46358cb3f0..1e71e4d2c58a454ee610d62eb4bdf63d5abaa25c 100644 (file)
@@ -34,8 +34,8 @@ import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.NavigableMap;
 import java.util.Set;
-import java.util.TreeMap;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.ParseTreeWalker;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser;
@@ -103,16 +103,22 @@ import org.opendaylight.yangtools.yang.parser.util.YangParseException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
 public final class YangParserListenerImpl extends YangParserBaseListener {
     private static final Logger LOG = LoggerFactory.getLogger(YangParserListenerImpl.class);
     private static final Splitter SLASH_SPLITTER = Splitter.on('/').omitEmptyStrings();
     private static final Splitter COLON_SPLITTER = Splitter.on(':');
     private static final String AUGMENT_STR = "augment";
 
-    private final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
+    private static final String IMPORT_STR = "import";
+    private static final String UNION_STR = "union";
+    private static final String UNKNOWN_NODE_STR = "unknown-node";
+
+    /**
+     * Date Format is not thread-safe so we cannot make constant from it.
+     */
+    private final DateFormat revisionFormat = new SimpleDateFormat("yyyy-MM-dd");
     private final SchemaPathStack stack = new SchemaPathStack();
-    private final Map<String, TreeMap<Date, URI>> namespaceContext;
+    private final Map<String, NavigableMap<Date, URI>> namespaceContext;
     private final String sourcePath;
     private QName moduleQName = QName.create(null, new Date(0L), "dummy");
     private ModuleBuilder moduleBuilder;
@@ -120,7 +126,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     private int augmentOrder;
     private String yangModelPrefix;
 
-    public YangParserListenerImpl(final Map<String, TreeMap<Date, URI>> namespaceContext, final String sourcePath) {
+    public YangParserListenerImpl(final Map<String, NavigableMap<Date, URI>> namespaceContext, final String sourcePath) {
         this.namespaceContext = namespaceContext;
         this.sourcePath = sourcePath;
     }
@@ -138,15 +144,13 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
      * @param tree
      * @return new instance of YangParserListenerImpl
      */
-    public static YangParserListenerImpl create(final Map<String, TreeMap<Date, URI>> namespaceContext,
+    public static YangParserListenerImpl create(final Map<String, NavigableMap<Date, URI>> namespaceContext,
             final String sourcePath, final ParseTreeWalker walker, final ParseTree tree) {
         final YangParserListenerImpl ret = new YangParserListenerImpl(namespaceContext, sourcePath);
         walker.walk(ret, tree);
         return ret;
     }
 
-
-
     @Override
     public void enterModule_stmt(final YangParser.Module_stmtContext ctx) {
         moduleName = stringFromNode(ctx);
@@ -159,7 +163,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         String description = null;
         String reference = null;
         for (int i = 0; i < ctx.getChildCount(); i++) {
-            ParseTree child = ctx.getChild(i);
+            final ParseTree child = ctx.getChild(i);
             if (child instanceof Description_stmtContext) {
                 description = stringFromNode(child);
             } else if (child instanceof Reference_stmtContext) {
@@ -192,7 +196,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         String description = null;
         String reference = null;
         for (int i = 0; i < ctx.getChildCount(); i++) {
-            ParseTree child = ctx.getChild(i);
+            final ParseTree child = ctx.getChild(i);
             if (child instanceof Description_stmtContext) {
                 description = stringFromNode(child);
             } else if (child instanceof Reference_stmtContext) {
@@ -216,7 +220,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void enterBelongs_to_stmt(final YangParser.Belongs_to_stmtContext ctx) {
         final String belongsTo = stringFromNode(ctx);
-        TreeMap<Date, URI> context = namespaceContext.get(belongsTo);
+        final NavigableMap<Date, URI> context = namespaceContext.get(belongsTo);
         final Map.Entry<Date, URI> entry = context.firstEntry();
         // TODO
         // Submodule will contain namespace and revision from module to which it
@@ -318,19 +322,19 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     private void updateRevisionForRevisionStatement(final ParseTree treeNode) {
         final String revisionDateStr = stringFromNode(treeNode);
         try {
-            final Date revisionDate = SIMPLE_DATE_FORMAT.parse(revisionDateStr);
+            final Date revisionDate = revisionFormat.parse(revisionDateStr);
             if ((revisionDate != null) && (this.moduleQName.getRevision().compareTo(revisionDate) < 0)) {
                 this.moduleQName = QName.create(moduleQName.getNamespace(), revisionDate, moduleQName.getLocalName());
                 moduleBuilder.setQNameModule(moduleQName.getModule());
                 setLog("revision", revisionDate.toString());
                 for (int i = 0; i < treeNode.getChildCount(); ++i) {
-                    ParseTree child = treeNode.getChild(i);
+                    final ParseTree child = treeNode.getChild(i);
                     if (child instanceof Reference_stmtContext) {
                         moduleBuilder.setReference(stringFromNode(child));
                     }
                 }
             }
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             LOG.warn("Failed to parse revision string: {}", revisionDateStr, e);
         }
     }
@@ -339,7 +343,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void enterImport_stmt(final Import_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String importName = stringFromNode(ctx);
-        enterLog("import", importName, line);
+        enterLog(IMPORT_STR, importName, line);
 
         String importPrefix = null;
         Date importRevision = null;
@@ -349,10 +353,10 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             if (treeNode instanceof Prefix_stmtContext) {
                 importPrefix = stringFromNode(treeNode);
             } else if (treeNode instanceof Revision_date_stmtContext) {
-                String importRevisionStr = stringFromNode(treeNode);
+                final String importRevisionStr = stringFromNode(treeNode);
                 try {
-                    importRevision = SIMPLE_DATE_FORMAT.parse(importRevisionStr);
-                } catch (ParseException e) {
+                    importRevision = revisionFormat.parse(importRevisionStr);
+                } catch (final ParseException e) {
                     LOG.warn("Failed to parse import revision-date at line {}: {}", line, importRevisionStr, e);
                 }
             }
@@ -363,14 +367,14 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitImport_stmt(final Import_stmtContext ctx) {
-        exitLog("import");
+        exitLog(IMPORT_STR);
     }
 
     @Override
-    public void enterInclude_stmt(YangParser.Include_stmtContext ctx) {
+    public void enterInclude_stmt(final YangParser.Include_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String includeName = stringFromNode(ctx);
-        enterLog("import", includeName, line);
+        enterLog(IMPORT_STR, includeName, line);
 
         Date includeRevision = null;
         for (int i = 0; i < ctx.getChildCount(); i++) {
@@ -378,8 +382,8 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             if (treeNode instanceof Revision_date_stmtContext) {
                 final String importRevisionStr = stringFromNode(treeNode);
                 try {
-                    includeRevision = SIMPLE_DATE_FORMAT.parse(importRevisionStr);
-                } catch (ParseException e) {
+                    includeRevision = revisionFormat.parse(importRevisionStr);
+                } catch (final ParseException e) {
                     LOG.warn("Failed to parse import revision-date at line {}: {}", line, importRevisionStr, e);
                 }
             }
@@ -387,7 +391,8 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         moduleBuilder.addInclude(includeName, includeRevision);
     }
 
-    @Override public void exitInclude_stmt(YangParser.Include_stmtContext ctx) {
+    @Override
+    public void exitInclude_stmt(final YangParser.Include_stmtContext ctx) {
         exitLog("include");
     }
 
@@ -399,10 +404,11 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         stack.push();
 
         final SchemaPath targetPath = parseXPathString(augmentPath, line);
-        final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath, augmentOrder++);
+        final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath,
+                augmentOrder++);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
-            ParseTree child = ctx.getChild(i);
+            final ParseTree child = ctx.getChild(i);
             if (child instanceof Description_stmtContext) {
                 builder.setDescription(stringFromNode(child));
             } else if (child instanceof Reference_stmtContext) {
@@ -508,12 +514,11 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             } else {
                 QName qname;
                 switch (typeName) {
-                case "union":
-                    qname = BaseTypes.UNION_QNAME;
-                    stack.addNodeToPath(qname);
+                case UNION_STR:
+                    stack.addNodeToPath(BaseTypes.UNION_QNAME);
                     final UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, moduleQName.getModule());
-                    final Builder parent = moduleBuilder.getActualNode();
-                    unionBuilder.setParent(parent);
+                    final Builder parentBuilder = moduleBuilder.getActualNode();
+                    unionBuilder.setParent(parentBuilder);
                     moduleBuilder.enterNode(unionBuilder);
                     break;
                 case "identityref":
@@ -534,23 +539,28 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 parent.setTypeQName(typeQName);
                 moduleBuilder.markActualNodeDirty();
             } else {
-                ParserListenerUtils.parseUnknownTypeWithBody(typeBody, parent, typeQName, moduleBuilder,
-                        moduleQName, stack.currentSchemaPath());
+                ParserListenerUtils.parseUnknownTypeWithBody(typeBody, parent, typeQName, moduleBuilder, moduleQName,
+                        stack.currentSchemaPath());
             }
             stack.addNodeToPath(QName.create(moduleQName.getModule(), typeQName.getLocalName()));
         }
     }
 
     /**
-     * Method transforms string representation of yang element (i.e. leaf name, container name etc.) into QName.
-     * The namespace of QName is assigned from parent module same as revision date of module. If String qname parameter
-     * contains ":" the string is evaluated as prefix:name of element. In this case method will look into import map
-     * and extract correct ModuleImport. If such import is not present in import map the method will throw {@link YangParseException}
-     * <br>
-     * If ModuleImport is present but the value of namespace in ModuleImport is <code>null</code> the method will throw {@link YangParseException}
+     * Method transforms string representation of yang element (i.e. leaf name,
+     * container name etc.) into QName. The namespace of QName is assigned from
+     * parent module same as revision date of module. If String qname parameter
+     * contains ":" the string is evaluated as prefix:name of element. In this
+     * case method will look into import map and extract correct ModuleImport.
+     * If such import is not present in import map the method will throw
+     * {@link YangParseException} <br>
+     * If ModuleImport is present but the value of namespace in ModuleImport is
+     * <code>null</code> the method will throw {@link YangParseException}
      *
-     * @param qnameString QName value as String
-     * @param line line in Yang model document where QName occur.
+     * @param qnameString
+     *            QName value as String
+     * @param line
+     *            line in Yang model document where QName occur.
      * @return transformed string qname parameter as QName structure.
      *
      * @throws YangParseException
@@ -570,10 +580,10 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 if (imp == null) {
                     LOG.debug("Error in module {} at line {}: No import found with prefix {}", moduleName, line, prefix);
                     throw new YangParseException(moduleName, line, "Error in module " + moduleName
-                        + " No import found with prefix " + prefix + " not found.");
+                            + " No import found with prefix " + prefix + " not found.");
                 }
                 Date revision = imp.getRevision();
-                TreeMap<Date, URI> namespaces = namespaceContext.get(imp.getModuleName());
+                final NavigableMap<Date, URI> namespaces = namespaceContext.get(imp.getModuleName());
                 if (namespaces == null) {
                     throw new YangParseException(moduleName, line, String.format("Imported module %s not found",
                             imp.getModuleName()));
@@ -583,9 +593,10 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                     revision = namespaces.lastEntry().getKey();
                     namespace = namespaces.lastEntry().getValue();
                 } else {
-                    // FIXME: this lookup does not look right, as we will end up with
-                    //        a qname which does not have a namespace. At any rate we
-                    //        should arrive at a QNameModule!
+                    // FIXME: this lookup does not look right, as we will end up
+                    // with
+                    // a qname which does not have a namespace. At any rate we
+                    // should arrive at a QNameModule!
                     namespace = namespaces.get(revision);
                 }
 
@@ -599,7 +610,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitType_stmt(final YangParser.Type_stmtContext ctx) {
         final String typeName = stringFromNode(ctx);
-        if ("union".equals(typeName)) {
+        if (UNION_STR.equals(typeName)) {
             moduleBuilder.exitNode();
         }
         exitLog("type", stack.removeNodeFromPath());
@@ -718,7 +729,8 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         stack.push();
 
         final SchemaPath targetPath = parseXPathString(augmentPath, line);
-        final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath, augmentOrder++);
+        final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath,
+                augmentOrder++);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
             final ParseTree child = ctx.getChild(i);
@@ -816,10 +828,9 @@ 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");
-                }
+            } else if (childNode instanceof YangParser.Identifier_stmtContext
+                    && UNION_STR.equals(childNode.getChild(0).toString())) {
+                throw new YangParseException(moduleName, line, "Union statement is not allowed inside a list statement");
             }
         }
     }
@@ -938,16 +949,18 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitIdentifier_stmt(final YangParser.Identifier_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("unknown-node", stack.removeNodeFromPath());
+        exitLog(UNKNOWN_NODE_STR, stack.removeNodeFromPath());
     }
 
-    @Override public void enterUnknown_statement(final YangParser.Unknown_statementContext ctx) {
+    @Override
+    public void enterUnknown_statement(final YangParser.Unknown_statementContext ctx) {
         handleUnknownNode(ctx.getStart().getLine(), ctx);
     }
 
-    @Override public void exitUnknown_statement(final YangParser.Unknown_statementContext ctx) {
+    @Override
+    public void exitUnknown_statement(final YangParser.Unknown_statementContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("unknown-node", stack.removeNodeFromPath());
+        exitLog(UNKNOWN_NODE_STR, stack.removeNodeFromPath());
     }
 
     @Override
@@ -1056,7 +1069,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         moduleBuilder.enterNode(builder);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
-            ParseTree child = ctx.getChild(i);
+            final ParseTree child = ctx.getChild(i);
             if (child instanceof Reference_stmtContext) {
                 reference = stringFromNode(child);
             } else if (child instanceof Deviate_not_supported_stmtContext) {
@@ -1077,7 +1090,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final boolean absolute = !xpathString.isEmpty() && xpathString.charAt(0) == '/';
 
         final List<QName> path = new ArrayList<>();
-        for (String pathElement : SLASH_SPLITTER.split(xpathString)) {
+        for (final String pathElement : SLASH_SPLITTER.split(xpathString)) {
             final Iterator<String> it = COLON_SPLITTER.split(pathElement).iterator();
             final String s = it.next();
             if (it.hasNext()) {
@@ -1112,7 +1125,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         for (int i = 0; i < ctx.getChildCount(); i++) {
             final ParseTree child = ctx.getChild(i);
             if (child instanceof Base_stmtContext) {
-                String baseIdentityName = stringFromNode(child);
+                final String baseIdentityName = stringFromNode(child);
                 builder.setBaseIdentityName(baseIdentityName);
             }
         }
@@ -1146,16 +1159,19 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     private void handleUnknownNode(final int line, final ParseTree ctx) {
         final String nodeParameter = stringFromNode(ctx);
-        enterLog("unknown-node", nodeParameter, line);
+        enterLog(UNKNOWN_NODE_STR, nodeParameter, line);
 
         final String nodeTypeStr = ctx.getChild(0).getText();
         final QName nodeType = parseQName(nodeTypeStr, line);
 
         QName qname = null;
         try {
-            //FIXME: rewrite whole method to handle unknown nodes properly.
-            // This should be bugfix for bug https://bugs.opendaylight.org/show_bug.cgi?id=1539
-            // After this fix bug https://bugs.opendaylight.org/show_bug.cgi?id=1538 MUST be fixed since
+            // FIXME: rewrite whole method to handle unknown nodes properly.
+            // This should be bugfix for bug
+            // https://bugs.opendaylight.org/show_bug.cgi?id=1539
+            // After this fix bug
+            // https://bugs.opendaylight.org/show_bug.cgi?id=1538 MUST be fixed
+            // since
             // they are dependent!!!
             if (Strings.isNullOrEmpty(nodeParameter)) {
                 qname = nodeType;
index 6a0d38e2441384cd049bb8c4fe69855c8213879b..b5b3cf02915647a449fb6b25d3086f9fcb7ed44b 100644 (file)
@@ -24,6 +24,9 @@ import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReferenc
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
 
+import javax.annotation.concurrent.Immutable;
+
+@Immutable
 public class YangStatementParserListenerImpl extends YangStatementParserBaseListener {
 
     private StatementWriter writer;
@@ -57,7 +60,7 @@ public class YangStatementParserListenerImpl extends YangStatementParserBaseList
                 try {
                     QName identifier = new QName(YangConstants.RFC6020_YIN_NAMESPACE,
                             ((YangStatementParser.KeywordContext) child).children.get(0).getText());
-                    if (stmtDef != null && stmtDef.get(identifier) != null && toBeSkipped.isEmpty()) {
+                    if (stmtDef != null && Utils.isValidStatementDefinition(prefixes, stmtDef, identifier) && toBeSkipped.isEmpty()) {
                         writer.startStatement(identifier, ref);
                     } else {
                         action = false;
@@ -68,11 +71,12 @@ public class YangStatementParserListenerImpl extends YangStatementParserBaseList
                 }
             } else if (child instanceof YangStatementParser.ArgumentContext) {
                 try {
-                    if (action)
+                    if (action) {
                         writer.argumentValue(
                                 Utils.stringFromStringContext((YangStatementParser.ArgumentContext) child), ref);
-                    else
+                    } else {
                         action = true;
+                    }
                 } catch (SourceException e) {
                     LOG.warn(e.getMessage(), e);
                 }
@@ -89,7 +93,7 @@ public class YangStatementParserListenerImpl extends YangStatementParserBaseList
                 try {
                     String statementName = ((YangStatementParser.KeywordContext) child).children.get(0).getText();
                     QName identifier = new QName(YangConstants.RFC6020_YIN_NAMESPACE, statementName);
-                    if (stmtDef != null && stmtDef.get(identifier) != null && toBeSkipped.isEmpty()) {
+                    if (stmtDef != null && Utils.isValidStatementDefinition(prefixes, stmtDef, identifier) && toBeSkipped.isEmpty()) {
                         writer.endStatement(ref);
                     }
 
index 252a782e1567eea80aad6ed7365df494decb9bd4..91c5c18028ffd58f9d232006868055c6b96d8ab1 100644 (file)
@@ -95,7 +95,7 @@ public class URLSchemaContextResolver implements AdvancedSchemaSourceProvider<In
         return stream;
     }
 
-    private final class SourceContext extends AbstractObjectRegistration<URL> //
+    private final class SourceContext extends AbstractObjectRegistration<URL>
             implements Identifiable<SourceIdentifier> {
 
         final SourceIdentifier identifier;
@@ -146,7 +146,7 @@ public class URLSchemaContextResolver implements AdvancedSchemaSourceProvider<In
         YangSourceContext yangSourceContext = YangSourceContext.createFrom(sourcesMap, this);
         LOG.debug("Trying to create schema context from {}", sourcesMap.keySet());
 
-        if (yangSourceContext.getMissingDependencies().size() != 0) {
+        if (!yangSourceContext.getMissingDependencies().isEmpty()) {
             LOG.debug("Omitting {} because of unresolved dependencies", yangSourceContext.getMissingDependencies().keySet());
             LOG.debug("Missing model sources for {}", yangSourceContext.getMissingSources());
         }
index bbe69e0410b701c924ef3972b81ca1400fb9df64..fcb2c1835f83f996caafea819f825f84c6eaa3d2 100644 (file)
@@ -62,9 +62,9 @@ public abstract class YangModelDependencyInfo {
         this.revision = formattedRevision == null ? null : QName.parseRevision(formattedRevision);
         this.moduleImports = imports;
         this.submoduleIncludes = includes;
-        this.dependencies = ImmutableSet.<ModuleImport> builder() //
-                .addAll(moduleImports) //
-                .addAll(submoduleIncludes) //
+        this.dependencies = ImmutableSet.<ModuleImport> builder()
+                .addAll(moduleImports)
+                .addAll(submoduleIncludes)
                 .build();
     }
 
@@ -214,8 +214,8 @@ public abstract class YangModelDependencyInfo {
         return builder.build();
     }
 
-    public static String getLatestRevision(final Revision_stmtsContext revision_stmts) {
-        List<Revision_stmtContext> revisions = revision_stmts.getRuleContexts(Revision_stmtContext.class);
+    public static String getLatestRevision(final Revision_stmtsContext revisionStmts) {
+        List<Revision_stmtContext> revisions = revisionStmts.getRuleContexts(Revision_stmtContext.class);
         String latestRevision = null;
         for (Revision_stmtContext revisionStmt : revisions) {
             String currentRevision = getArgumentString(revisionStmt);
@@ -248,11 +248,11 @@ public abstract class YangModelDependencyInfo {
         return builder.build();
     }
 
-    private static Date getRevision(final Revision_date_stmtContext revision_date_stmt) {
-        if (revision_date_stmt == null) {
+    private static Date getRevision(final Revision_date_stmtContext revisionDateStmt) {
+        if (revisionDateStmt == null) {
             return null;
         }
-        String formatedDate = getArgumentString(revision_date_stmt);
+        String formatedDate = getArgumentString(revisionDateStmt);
         return QName.parseRevision(formatedDate);
     }
 
@@ -285,6 +285,12 @@ public abstract class YangModelDependencyInfo {
 
         private final String belongsTo;
 
+        private SubmoduleDependencyInfo(final String name, final String latestRevision, final String belongsTo,
+                                        final ImmutableSet<ModuleImport> imports, final ImmutableSet<ModuleImport> includes) {
+            super(name, latestRevision, imports, includes);
+            this.belongsTo = belongsTo;
+        }
+
         /**
          * Returns name of parent module.
          *
@@ -293,12 +299,6 @@ public abstract class YangModelDependencyInfo {
             return belongsTo;
         }
 
-        private SubmoduleDependencyInfo(final String name, final String latestRevision, final String belongsTo,
-                final ImmutableSet<ModuleImport> imports, final ImmutableSet<ModuleImport> includes) {
-            super(name, latestRevision, imports, includes);
-            this.belongsTo = belongsTo;
-        }
-
         @Override
         public String toString() {
             return "Submodule [name=" + getName() + ", revision=" + getRevision() + ", dependencies="
index ebe602d5a72c42a06fec63899b8d63a0d8b9d2ce..f8fc1770b827327621ddd370451dd71bac370204 100644 (file)
@@ -7,22 +7,6 @@
  */
 package org.opendaylight.yangtools.yang.parser.repo;
 
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.AsyncFunction;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import java.net.URI;
 import java.util.Collection;
 import java.util.Collections;
@@ -31,9 +15,11 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.NavigableMap;
 import java.util.Set;
-import java.util.TreeMap;
+
 import javax.annotation.Nullable;
+
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.tree.ParseTreeWalker;
 import org.opendaylight.yangtools.util.concurrent.ExceptionMapper;
@@ -53,6 +39,23 @@ import org.opendaylight.yangtools.yang.parser.util.ASTSchemaSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
 final class SharedSchemaContextFactory implements SchemaContextFactory {
     private static final ExceptionMapper<SchemaResolutionException> MAPPER = ReflectiveExceptionMapper.create("resolve sources", SchemaResolutionException.class);
     private static final Logger LOG = LoggerFactory.getLogger(SharedSchemaContextFactory.class);
@@ -87,7 +90,7 @@ final class SharedSchemaContextFactory implements SchemaContextFactory {
 
             final Map<SourceIdentifier, ParserRuleContext> asts =
                     Maps.transformValues(srcs, ASTSchemaSource.GET_AST);
-            final Map<String, TreeMap<Date, URI>> namespaceContext = BuilderUtils.createYangNamespaceContext(
+            final Map<String, NavigableMap<Date, URI>> namespaceContext = BuilderUtils.createYangNamespaceContext(
                     asts.values(), Optional.<SchemaContext>absent());
 
             final ParseTreeWalker walker = new ParseTreeWalker();
index b0c23ea3c5ea83c4dd1463285279089da4df460d..583c0d821e67b6689934c4174ee4d44d4d8e3b27 100644 (file)
@@ -81,7 +81,7 @@ public abstract class AbstractStatementSupport<A, D extends DeclaredStatement<A>
      *
      */
     @Override
-    public void onLinkageDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException, SourceException {
+    public void onLinkageDeclared(StmtContext.Mutable<A, D, E> stmt) throws SourceException {
         // NOOP for most implementations
     }
 
@@ -95,8 +95,7 @@ public abstract class AbstractStatementSupport<A, D extends DeclaredStatement<A>
      *
      */
     @Override
-    public void onStatementDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException,
-            SourceException {
+    public void onStatementDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws SourceException {
         // NOOP for most implementations
     }
 
@@ -110,7 +109,7 @@ public abstract class AbstractStatementSupport<A, D extends DeclaredStatement<A>
      *
      */
     @Override
-    public void onFullDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException, SourceException {
+    public void onFullDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws SourceException {
         // NOOP for most implementations
     }
 
index 129110d8537491c41716a7db9f59d40bcdcb7042..6522af9227cb35e465ba6b5b315a962ab68f8c38 100644 (file)
@@ -46,8 +46,6 @@ public abstract class NamespaceBehaviour<K,V, N extends IdentifierNamespace<K, V
 
         @Nullable  <K, V, N extends IdentifierNamespace<K, V>> V getFromLocalStorage(Class<N> type, K key);
 
-        //<K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAllFromLocalStorage(Class<N> type);
-
         @Nullable  <K, V, N extends IdentifierNamespace<K, V>> void addToLocalStorage(Class<N> type, K key, V value);
 
     }
@@ -103,8 +101,6 @@ public abstract class NamespaceBehaviour<K,V, N extends IdentifierNamespace<K, V
 
     public abstract V getFrom(NamespaceStorageNode storage, K key);
 
-    //public abstract Map<K, V> getAllFrom(NamespaceStorageNode storage);
-
     public abstract void addTo(NamespaceStorageNode storage,K key,V value);
 
     @Override
@@ -116,10 +112,6 @@ public abstract class NamespaceBehaviour<K,V, N extends IdentifierNamespace<K, V
         return storage.getFromLocalStorage(getIdentifier(), key);
     }
 
-//    protected final Map<K, V> getAllFromLocalStorage(NamespaceStorageNode storage) {
-//        return storage.getAllFromLocalStorage(getIdentifier());
-//    }
-
     protected final void addToStorage(NamespaceStorageNode storage,K key,V value) {
         storage.addToLocalStorage(getIdentifier(),key,value);
     }
@@ -142,15 +134,6 @@ public abstract class NamespaceBehaviour<K,V, N extends IdentifierNamespace<K, V
             return getFromLocalStorage(current,key);
         }
 
-//        @Override
-//        public Map<K, V> getAllFrom(final NamespaceStorageNode storage) {
-//            NamespaceStorageNode current = storage;
-//            while(current.getStorageNodeType() != storageType) {
-//                current = current.getParentNamespaceStorage();
-//            }
-//            return getAllFromLocalStorage(current);
-//        }
-
         @Override
         public void addTo(NamespaceBehaviour.NamespaceStorageNode storage, K key, V value) {
             NamespaceStorageNode current = storage;
index e270f806a91f93812d13dab32d8cd4c36c10732a..f240105a0998758a117321d47eadbd0b913bee9b 100644 (file)
@@ -69,8 +69,7 @@ public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends E
      * @param stmt
      *            Context of added statement.
      */
-     void onLinkageDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException,
-            SourceException;
+     void onLinkageDeclared(StmtContext.Mutable<A, D, E> stmt) throws SourceException;
 
     /**
      *
@@ -89,8 +88,7 @@ public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends E
      *            Context of added statement. Argument and statement parent is
      *            accessible.
      */
-     void onStatementDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException,
-            SourceException;
+     void onStatementDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws SourceException;
 
     /**
      *
@@ -110,7 +108,6 @@ public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends E
      *            Context of added statement. Argument and statement parent is
      *            accessible.
      */
-     void onFullDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException,
-            SourceException;
+     void onFullDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws SourceException;
 
 }
\ No newline at end of file
index 01435600334c555d263c69ded77d1dff597b2452..f137faf6677280f75afacad1e806728e9fc935cd 100644 (file)
@@ -23,18 +23,18 @@ public final class StatementSupportBundle implements Immutable,NamespaceBehaviou
     private final ImmutableMap<QName, StatementSupport<?,?,?>> definitions;
     private final ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaceDefinitions;
 
-    public ImmutableMap<QName, StatementSupport<?, ?, ?>> getDefinitions() {
-        return definitions;
-    }
-
     private StatementSupportBundle(StatementSupportBundle parent,
-            ImmutableMap<QName, StatementSupport<?, ?, ?>> statements,
-            ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces) {
+                                   ImmutableMap<QName, StatementSupport<?, ?, ?>> statements,
+                                   ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces) {
         this.parent = parent;
         this.definitions = statements;
         this.namespaceDefinitions = namespaces;
     }
 
+    public ImmutableMap<QName, StatementSupport<?, ?, ?>> getDefinitions() {
+        return definitions;
+    }
+
     public static Builder builder() {
         return new Builder(EMPTY);
     }
@@ -54,9 +54,7 @@ public final class StatementSupportBundle implements Immutable,NamespaceBehaviou
              * 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;
+            return (NamespaceBehaviour<K, V, N>) potential;
         }
         if (parent != null) {
             return parent.getNamespaceBehaviour(namespace);
index 43e2014e32164c5a48bdb4b24e3009eae6646d16..5b85dc637720f4570ca90d7bf56cf2236c788906 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.yangtools.yang.parser.spi.meta;
 
 import java.util.List;
-
 import java.util.Map;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
@@ -23,32 +22,44 @@ 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>> {
 
-public interface StmtContext<A,D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> {
-
-    @Nonnull StatementSource getStatementSource();
+    @Nonnull
+    StatementSource getStatementSource();
 
-    @Nonnull StatementSourceReference getStatementSourceReference();
+    @Nonnull
+    StatementSourceReference getStatementSourceReference();
 
-    @Nonnull StatementDefinition getPublicDefinition();
+    @Nonnull
+    StatementDefinition getPublicDefinition();
 
-    @Nullable StmtContext<?,?,?> getParentContext();
+    @Nullable
+    StmtContext<?, ?, ?> getParentContext();
 
-    @Nullable String rawStatementArgument();
+    @Nullable
+    String rawStatementArgument();
 
-    @Nullable A getStatementArgument();
+    @Nullable
+    A getStatementArgument();
 
-    @Nullable List<Object> getArgumentsFromRoot();
+    @Nullable
+    List<Object> getArgumentsFromRoot();
 
-    //<K,VT, V extends VT,N extends IdentifierNamespace<K, V>>
-    //       <K, VT, V extends VT ,N extends IdentifierNamespace<K, V>> VT getFromNamespace(Class<N> type, K key)
-    @Nonnull <K,V,N extends IdentifierNamespace<K, V>> V getFromNamespace(Class<N> type, K key) throws NamespaceNotAvailableException;
+    // <K,VT, V extends VT,N extends IdentifierNamespace<K, V>>
+    // <K, VT, V extends VT ,N extends IdentifierNamespace<K, V>> VT
+    // getFromNamespace(Class<N> type, K key)
+    @Nonnull
+    <K, V, N extends IdentifierNamespace<K, V>> V getFromNamespace(
+            Class<N> type, K key) throws NamespaceNotAvailableException;
 
-    <K, V, N extends IdentifierNamespace<K, V>> Map<?, ?> getAllFromNamespace(Class<N> type);
+    <K, V, N extends IdentifierNamespace<K, V>> Map<?, ?> getAllFromNamespace(
+            Class<N> type);
 
-    @Nonnull StmtContext<?,?,?> getRoot();
+    @Nonnull
+    StmtContext<?, ?, ?> getRoot();
 
-    @Nonnull Collection<StatementContextBase<?,?,?>> declaredSubstatements();
+    @Nonnull
+    Collection<StatementContextBase<?, ?, ?>> declaredSubstatements();
 
     public Collection<StatementContextBase<?, ?, ?>> effectiveSubstatements();
 
@@ -56,26 +67,48 @@ public interface StmtContext<A,D extends DeclaredStatement<A>, E extends Effecti
 
     E buildEffective();
 
-    public StatementContextBase<?, ?, ?>  createCopy(QNameModule newQNameModule,StatementContextBase<?, ?, ?> newParent) throws SourceException;
+    public StatementContextBase<?, ?, ?> createCopy(QNameModule newQNameModule,
+            StatementContextBase<?, ?, ?> newParent, TypeOfCopy typeOfCopy)
+            throws SourceException;
+
+    public static enum TypeOfCopy {
+        ORIGINAL, ADDED_BY_USES, ADDED_BY_AUGMENTATION
+    }
+
+    public TypeOfCopy getTypeOfCopy();
+
+    public void setTypeOfCopy(TypeOfCopy typeOfCopy);
+
+    public StatementContextBase<?, ?, ?> getOriginalCtx();
 
-    interface Mutable<A,D extends DeclaredStatement<A>,E extends EffectiveStatement<A, D>> extends StmtContext<A,D,E> {
+    public void setOriginalCtx(StatementContextBase<?, ?, ?> originalCtx);
+
+    public boolean isRootContext();
+
+    public void setCompletedPhase(ModelProcessingPhase completedPhase);
+
+    public ModelProcessingPhase getCompletedPhase();
+
+    interface Mutable<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
+            extends StmtContext<A, D, E> {
 
         @Override
-        StmtContext.Mutable<?,?,?> getParentContext();
+        StmtContext.Mutable<?, ?, ?> getParentContext();
 
-        //<K,V,VT extends V,N extends IdentifierNamespace<K, V>> void addToNs(Class<N> type, K key, VT value)
-        <K,V,VT extends V,N extends IdentifierNamespace<K, V>> void addToNs(Class<N> type, K key, VT value) throws NamespaceNotAvailableException;
+        // <K,V,VT extends V,N extends IdentifierNamespace<K, V>> void
+        // addToNs(Class<N> type, K key, VT value)
+        <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();
+        StmtContext.Mutable<?, ?, ?> getRoot();
 
         ModelActionBuilder newInferenceAction(ModelProcessingPhase phase);
 
-        <K,KT extends K, N extends StatementNamespace<K, ?, ?>> void addContext(Class<N> namespace, KT key,
-                StmtContext<?, ?, ?> stmt);
+        <K, KT extends K, N extends StatementNamespace<K, ?, ?>> void addContext(
+                Class<N> namespace, KT key, StmtContext<?, ?, ?> stmt);
 
     }
 
-
-
 }
index fa2e78bddb21689f1b33376e572be8ceea10b0d0..1388ef161dcdb120dc79ba7e3590d016da21e4f8 100644 (file)
@@ -38,7 +38,6 @@ public final class StmtContextUtils {
     }
 
     @SuppressWarnings("unchecked")
-
     public static final <E extends EffectiveStatement<?, ?>> Function<StmtContext<?, ?, ? extends E>, E> buildEffective() {
         return Function.class.cast(BUILD_EFFECTIVE);
     }
@@ -81,18 +80,20 @@ public final class StmtContextUtils {
     public static final StmtContext<?, ?, ?> findFirstDeclaredSubstatement(
             StmtContext<?, ?, ?> stmtContext, int startIndex, Class<? extends DeclaredStatement<?>>... types) {
 
-        if (startIndex >= types.length)
+        if (startIndex >= types.length) {
             return null;
+        }
 
         Collection<? extends StmtContext<?, ?, ?>> declaredSubstatements = stmtContext
                 .declaredSubstatements();
         for (StmtContext<?, ?, ?> subStmtContext : declaredSubstatements) {
             if (producesDeclared(subStmtContext,types[startIndex])) {
-                if (startIndex + 1 == types.length)
+                if (startIndex + 1 == types.length) {
                     return subStmtContext;
-                else
+                } else {
                     return findFirstDeclaredSubstatement(subStmtContext,
                             ++startIndex, types);
+                }
             }
         }
         return null;
@@ -110,8 +111,9 @@ public final class StmtContextUtils {
                 if (sublevel > 1) {
                     StmtContext<?, ?, ?> result = findFirstDeclaredSubstatementOnSublevel(
                             subStmtContext, declaredType, --sublevel);
-                    if (result != null)
+                    if (result != null) {
                         return result;
+                    }
                 }
             }
         }
@@ -130,8 +132,9 @@ public final class StmtContextUtils {
             } else {
                 StmtContext<?, ?, ?> result = findDeepFirstDeclaredSubstatement(
                         subStmtContext, declaredType);
-                if (result != null)
+                if (result != null) {
                     return result;
+                }
 
             }
         }
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/PrefixToModuleMap.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/PrefixToModuleMap.java
new file mode 100644 (file)
index 0000000..e01e5ae
--- /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.parser.spi.source;
+
+import org.opendaylight.yangtools.yang.common.QNameModule;
+
+import javax.annotation.Nullable;
+import java.util.HashMap;
+import java.util.Map;
+
+public class PrefixToModuleMap implements PrefixToModule {
+
+    private Map<String, QNameModule> prefixToModuleMap = new HashMap<>();
+
+    public void put(String prefix, QNameModule qNameModule) {
+        prefixToModuleMap.put(prefix, qNameModule);
+    }
+
+    @Nullable
+    @Override
+    public QNameModule get(String prefix) {
+        return prefixToModuleMap.get(prefix);
+    }
+
+    @Nullable
+    @Override
+    public QNameModule getByNamespace(String namespace) {
+        return null;
+    }
+}
index f0767c7f3acd151f88258a2c153b147958c310b4..091360e04c6debc8e3f9807dd7ad3d4e05c137ef 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * 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;
@@ -8,15 +15,16 @@ import javax.annotation.Nullable;
 import java.util.HashMap;
 import java.util.Map;
 
-public class QNameToStatementDefinitionMap implements QNameToStatementDefinition{
+public class QNameToStatementDefinitionMap implements QNameToStatementDefinition {
 
     private Map<QName, StatementDefinition> qNameToStmtDefMap = new HashMap<>();
 
-    public void put(QName qName, StatementDefinition stDef ) {
+    public void put(QName qName, StatementDefinition stDef) {
         qNameToStmtDefMap.put(qName, stDef);
     }
 
-    @Nullable @Override
+    @Nullable
+    @Override
     public StatementDefinition get(@Nonnull QName identifier) {
         return qNameToStmtDefMap.get(identifier);
     }
index cb0dd2c3437cf505d86b9ad120de14603bd7be09..90b41b99120af501050a5b1a8d2ec0b43f46f8d9 100644 (file)
@@ -103,11 +103,9 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh
              * Safe cast, previous checkState checks equivalence of key from
              * which type argument are derived
              */
-            @SuppressWarnings("unchecked")
-            NamespaceBehaviourWithListeners<K, V, N> casted = (NamespaceBehaviourWithListeners<K, V, N>) potential;
-            return casted;
+            return (NamespaceBehaviourWithListeners<K, V, N>) potential;
         }
-        throw new NamespaceNotAvailableException("Namespace " + type + "is not available in phase " + currentPhase);
+        throw new NamespaceNotAvailableException("Namespace " + type + " is not available in phase " + currentPhase);
     }
 
     public StatementDefinitionContext<?, ?, ?> getStatementDefinition(QName name) {
@@ -185,7 +183,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh
 
     private  void completePhaseActions() throws ReactorException {
         Preconditions.checkState(currentPhase != null);
-        ArrayList<SourceSpecificContext> sourcesToProgress = Lists.newArrayList(sources);
+        List<SourceSpecificContext> sourcesToProgress = Lists.newArrayList(sources);
         try {
             boolean progressing = true;
             while(progressing) {
@@ -197,10 +195,15 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh
                     switch (sourceProgress) {
                         case FINISHED:
                             currentSource.remove();
+                            // Fallback to progress, since we were able to make progress in computation
                         case PROGRESS:
                             progressing = true;
+                            break;
                         case NO_PROGRESS:
-                            // Noop;
+                            // Noop
+                            break;
+                        default:
+                           throw new IllegalStateException("Unsupported phase progress " + sourceProgress);
                     }
                 }
             }
index 638952cf3dc44241d0479ede263f6dc16569e693..75879a54a059e3662b8ae965b35eadcc09cf3eb7 100644 (file)
@@ -64,8 +64,9 @@ class ModifierImpl implements ModelActionBuilder {
     }
 
     private void tryToResolve() throws InferenceException {
-        if(action == null) {
-            return; // Action was not yet defined
+        if(action == null || isApplied()) {
+            // Action was not yet defined
+            return;
         }
         if(removeSatisfied()) {
             applyAction();
@@ -77,7 +78,8 @@ class ModifierImpl implements ModelActionBuilder {
         boolean allSatisfied = true;
         while(prereq.hasNext()) {
             if(prereq.next().isDone()) {
-                prereq.remove(); // We are removing current prerequisite from list.
+                // We are removing current prerequisite from list.
+                prereq.remove();
             } else {
                 allSatisfied  = false;
             }
@@ -102,8 +104,13 @@ class ModifierImpl implements ModelActionBuilder {
 
     private void applyAction() throws InferenceException {
 
-        action.apply();
-        // Mark all mutations as performed, so context node could move to next.
+        try {
+            action.apply();
+        } catch (InferenceException e) {
+            actionApplied = false;
+            return;
+        }
+        // Â Mark all mutations as performed, so context node could move to next.
         actionApplied = true;
     }
 
@@ -253,11 +260,11 @@ class ModifierImpl implements ModelActionBuilder {
             return done;
         }
 
-        protected void resolvePrereq(T value) throws InferenceException {
-            Preconditions.checkState(!isDone());
+        protected boolean resolvePrereq(T value) throws InferenceException {
             this.value = value;
             this.done = true;
             tryToResolve();
+            return isApplied();
         }
 
         protected <O> Prerequisite<O> transform(final Function<? super T,O> transformation) {
@@ -298,8 +305,8 @@ class ModifierImpl implements ModelActionBuilder {
 
         @SuppressWarnings("unchecked")
         @Override
-        public void phaseFinished(StatementContextBase<?, ?, ?> context, ModelProcessingPhase phase) throws SourceException {
-            resolvePrereq((C) (context));
+        public boolean phaseFinished(StatementContextBase<?, ?, ?> context, ModelProcessingPhase phase) throws SourceException {
+            return resolvePrereq((C) (context));
         }
     }
 
@@ -328,8 +335,8 @@ class ModifierImpl implements ModelActionBuilder {
 
         @SuppressWarnings("unchecked")
         @Override
-        public void phaseFinished(StatementContextBase<?, ?, ?> context, ModelProcessingPhase phase) throws SourceException {
-            resolvePrereq((C) context);
+        public boolean phaseFinished(StatementContextBase<?, ?, ?> context, ModelProcessingPhase phase) throws SourceException {
+            return resolvePrereq((C) context);
         }
 
     }
index 2fe7f01138a3bdc72e3f7b136faea0a3bf55d8fe..d32b8cdee123346d0b072c69ee56ed515ab61348 100644 (file)
@@ -34,35 +34,38 @@ class RootStatementContext<A, D extends DeclaredStatement<A>, E extends Effectiv
     }
 
     RootStatementContext(RootStatementContext<A, D, E> original,
-            QNameModule newQNameModule) throws SourceException {
+            QNameModule newQNameModule, TypeOfCopy typeOfCopy)
+            throws SourceException {
         super(original);
 
         sourceContext = original.sourceContext;
         this.argument = original.argument;
 
-        copyDeclaredStmts(original, newQNameModule);
+        copyDeclaredStmts(original, newQNameModule, typeOfCopy);
 
-        copyEffectiveStmts(original, newQNameModule);
+        copyEffectiveStmts(original, newQNameModule, typeOfCopy);
 
     }
 
     private void copyDeclaredStmts(RootStatementContext<A, D, E> original,
-            QNameModule newQNameModule) throws SourceException {
+            QNameModule newQNameModule, TypeOfCopy typeOfCopy)
+            throws SourceException {
         Collection<? extends StmtContext<?, ?, ?>> originalDeclaredSubstatements = original
                 .declaredSubstatements();
         for (StmtContext<?, ?, ?> stmtContext : originalDeclaredSubstatements) {
-            this.addEffectiveSubstatement(stmtContext
-                    .createCopy(newQNameModule,this));
+            this.addEffectiveSubstatement(stmtContext.createCopy(
+                    newQNameModule, this, typeOfCopy));
         }
     }
 
     private void copyEffectiveStmts(RootStatementContext<A, D, E> original,
-            QNameModule newQNameModule) throws SourceException {
+            QNameModule newQNameModule, TypeOfCopy typeOfCopy)
+            throws SourceException {
         Collection<? extends StmtContext<?, ?, ?>> originalEffectiveSubstatements = original
                 .effectiveSubstatements();
         for (StmtContext<?, ?, ?> stmtContext : originalEffectiveSubstatements) {
-            this.addEffectiveSubstatement(stmtContext
-                    .createCopy(newQNameModule,this));
+            this.addEffectiveSubstatement(stmtContext.createCopy(
+                    newQNameModule, this, typeOfCopy));
         }
     }
 
@@ -96,11 +99,13 @@ class RootStatementContext<A, D extends DeclaredStatement<A>, E extends Effectiv
     }
 
     @Override
-    public StatementContextBase<A, D, E> createCopy(QNameModule newQNameModule, StatementContextBase<?, ?, ?> newParent)
+    public StatementContextBase<A, D, E> createCopy(QNameModule newQNameModule,
+            StatementContextBase<?, ?, ?> newParent, TypeOfCopy typeOfCopy)
             throws SourceException {
-
-        StatementContextBase<A, D, E> copy = new RootStatementContext<A, D, E>(
-                this, newQNameModule);
+        RootStatementContext<A, D, E> copy = new RootStatementContext<>(this,
+                newQNameModule, typeOfCopy);
+        copy.setTypeOfCopy(typeOfCopy);
+        copy.setOriginalCtx(this);
         return copy;
     }
 
@@ -111,4 +116,8 @@ class RootStatementContext<A, D extends DeclaredStatement<A>, E extends Effectiv
         return argumentList;
     }
 
+    @Override
+    public boolean isRootContext() {
+        return true;
+    }
 }
index d6ddc551c228760036f7d965113169993ce672f6..4f2be08a4df5a9b255c776381b4571a0fbccfbe4 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.YangConstants;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 
 import com.google.common.base.Preconditions;
@@ -23,6 +25,8 @@ import org.opendaylight.yangtools.concepts.Mutable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ImportedNamespaceContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder;
@@ -32,12 +36,15 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Namesp
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
+import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModuleMap;
 import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
 import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinitionMap;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase.ContextBuilder;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.UnknownStatementImpl;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
 
 public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBehaviour.Registry, Mutable {
 
@@ -57,6 +64,7 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh
     private ModelProcessingPhase inProgressPhase;
     private ModelProcessingPhase finishedPhase;
     private QNameToStatementDefinitionMap qNameToStmtDefMap = new QNameToStatementDefinitionMap();
+    private PrefixToModuleMap prefixToModuleMap = new PrefixToModuleMap();
 
 
     SourceSpecificContext(BuildGlobalContext currentContext,StatementStreamSource source) {
@@ -70,7 +78,15 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh
 
     ContextBuilder<?, ?, ?> createDeclaredChild(StatementContextBase<?, ?, ?> current, QName name, StatementSourceReference ref) {
         StatementDefinitionContext<?,?,?> def = getDefinition(name);
-        Preconditions.checkArgument(def != null, "Statement %s does not have type mapping defined.",name);
+
+        //extensions
+        if (def == null) {
+            if (Utils.isValidStatementDefinition(prefixToModuleMap, qNameToStmtDefMap, name)) {
+                def = new StatementDefinitionContext<>(new UnknownStatementImpl.Definition(qNameToStmtDefMap.get(Utils.trimPrefix(name))));
+            }
+        }
+
+        Preconditions.checkArgument(def != null, "Statement %s does not have type mapping defined.", name);
         if(current == null) {
             return createDeclaredRoot(def,ref);
         }
@@ -159,7 +175,7 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh
 
         boolean phaseCompleted = root.tryToCompletePhase(phase);
 
-        hasProgressed = hasProgress(currentPhaseModifiers);
+        hasProgressed = (hasProgress(currentPhaseModifiers) | hasProgressed);
 
         if(phaseCompleted && (currentPhaseModifiers.isEmpty())) {
             finishedPhase = phase;
@@ -216,13 +232,13 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh
 
     void loadStatements() throws SourceException {
         switch (inProgressPhase) {
-        case SOURCE_LINKAGE:
+            case SOURCE_LINKAGE:
             source.writeLinkage(new StatementContextWriter(this, inProgressPhase),stmtDef());
             break;
-        case STATEMENT_DEFINITION:
+            case STATEMENT_DEFINITION:
             source.writeLinkageAndStatementDefinitions(new StatementContextWriter(this, inProgressPhase), stmtDef(), prefixes());
             break;
-        case FULL_DECLARATION:
+            case FULL_DECLARATION:
             source.writeFull(new StatementContextWriter(this, inProgressPhase), stmtDef(), prefixes());
             break;
         default:
@@ -231,16 +247,30 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh
     }
 
     private PrefixToModule prefixes() {
-        // TODO Auto-generated method stub
-        return null;
+        Map<String, QNameModule> prefixes = (Map<String, QNameModule>) currentContext.getAllFromNamespace(PrefixToModule.class);
+        for (Map.Entry<String, QNameModule> prefix : prefixes.entrySet()) {
+            prefixToModuleMap.put(prefix.getKey(), prefix.getValue());
+        }
+        return prefixToModuleMap;
     }
 
     private QNameToStatementDefinition stmtDef() {
+        //regular YANG statements added
         ImmutableMap<QName, StatementSupport<?, ?, ?>> definitions = currentContext.getSupportsForPhase(
                 inProgressPhase).getDefinitions();
         for (Map.Entry<QName, StatementSupport<?,?,?>> entry : definitions.entrySet()) {
             qNameToStmtDefMap.put(entry.getKey(), entry.getValue());
         }
+
+        //extensions added
+        if (inProgressPhase.equals(ModelProcessingPhase.FULL_DECLARATION)) {
+            Map<QName, SubstatementContext<?, ?, ?>> extensions = (Map<QName, SubstatementContext<?, ?, ?>>) currentContext.getAllFromNamespace(ExtensionNamespace.class);
+            if (extensions != null) {
+                for (Map.Entry<QName, SubstatementContext<?, ?, ?>> extension : extensions.entrySet()) {
+                    qNameToStmtDefMap.put(new QName(YangConstants.RFC6020_YIN_NAMESPACE, extension.getKey().getLocalName()), (StatementDefinition) extension.getValue().definition().getFactory());
+                }
+            }
+        }
         return qNameToStmtDefMap;
     }
 }
index 94f29a3cca5af98f830cc9697f2af775d6a662cd..4ce2f5b9f3bf3a2175eb5a086b63b31fd357864b 100644 (file)
@@ -17,6 +17,7 @@ import java.util.Collections;
 import java.util.EventListener;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
+import java.util.Map;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
@@ -34,18 +35,22 @@ import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.NamespaceBehaviourWithListeners.ValueAddedListener;
 
-public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> extends
-        NamespaceStorageSupport implements StmtContext.Mutable<A, D, E>, Identifiable<StatementIdentifier> {
+public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
+        extends NamespaceStorageSupport implements
+        StmtContext.Mutable<A, D, E>, Identifiable<StatementIdentifier> {
 
-    interface OnNamespaceItemAdded extends EventListener{
+    interface OnNamespaceItemAdded extends EventListener {
 
-        void namespaceItemAdded(StatementContextBase<?,?,?> context, Class<?> namespace, Object key, Object value) throws SourceException;
+        void namespaceItemAdded(StatementContextBase<?, ?, ?> context,
+                Class<?> namespace, Object key, Object value)
+                throws SourceException;
 
     }
 
-    interface OnPhaseFinished extends EventListener{
+    interface OnPhaseFinished extends EventListener {
 
-        void phaseFinished(StatementContextBase<?,?,?> context, ModelProcessingPhase phase) throws SourceException;
+        boolean phaseFinished(StatementContextBase<?, ?, ?> context,
+                ModelProcessingPhase phase) throws SourceException;
 
     }
 
@@ -62,13 +67,16 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
         private String rawArg;
         private StatementSourceReference argRef;
 
-        public ContextBuilder(StatementDefinitionContext<A, D, E> def, StatementSourceReference sourceRef) {
+        public ContextBuilder(StatementDefinitionContext<A, D, E> def,
+                StatementSourceReference sourceRef) {
             this.definition = def;
             this.stmtRef = sourceRef;
         }
 
-        public void setArgument(@Nonnull String argument, @Nonnull StatementSourceReference argumentSource) {
-            Preconditions.checkArgument(definition.hasArgument(), "Statement does not take argument.");
+        public void setArgument(@Nonnull String argument,
+                @Nonnull StatementSourceReference argumentSource) {
+            Preconditions.checkArgument(definition.hasArgument(),
+                    "Statement does not take argument.");
             this.rawArg = Preconditions.checkNotNull(argument);
             this.argRef = Preconditions.checkNotNull(argumentSource);
         }
@@ -90,10 +98,12 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
         }
 
         public StatementIdentifier getIdentifier() {
-            return new StatementIdentifier(definition.getStatementName(), rawArg);
+            return new StatementIdentifier(definition.getStatementName(),
+                    rawArg);
         }
 
-        public abstract StatementContextBase<A, D, E> build() throws SourceException;
+        public abstract StatementContextBase<A, D, E> build()
+                throws SourceException;
 
     }
 
@@ -101,28 +111,63 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     private final StatementIdentifier identifier;
     private final StatementSourceReference statementDeclSource;
 
-    private LinkedHashMap<StatementIdentifier, StatementContextBase<?, ?, ?> > substatements = new LinkedHashMap<>();
+    private Map<StatementIdentifier, StatementContextBase<?, ?, ?>> substatements = new LinkedHashMap<>();
 
     private Collection<StatementContextBase<?, ?, ?>> declared = new ArrayList<>();
     private Collection<StatementContextBase<?, ?, ?>> effective = new ArrayList<>();
 
     private ModelProcessingPhase completedPhase;
 
-    private Multimap<ModelProcessingPhase,OnPhaseFinished> phaseListeners = HashMultimap.create();
-    private Multimap<ModelProcessingPhase, ContextMutation> phaseMutation = HashMultimap.create();
+    private Multimap<ModelProcessingPhase, OnPhaseFinished> phaseListeners = HashMultimap
+            .create();
+    private Multimap<ModelProcessingPhase, ContextMutation> phaseMutation = HashMultimap
+            .create();
 
     private D declaredInstance;
     private E effectiveInstance;
 
+    private StatementContextBase<?, ?, ?> originalCtx;
+    private TypeOfCopy typeOfCopy = TypeOfCopy.ORIGINAL;
 
-    StatementContextBase(@Nonnull ContextBuilder<A, D, E> builder) throws SourceException {
+    @Override
+    public TypeOfCopy getTypeOfCopy() {
+        return typeOfCopy;
+    }
+
+    @Override
+    public void setTypeOfCopy(TypeOfCopy typeOfCopy) {
+        this.typeOfCopy = typeOfCopy;
+    }
+
+    @Override
+    public StatementContextBase<?, ?, ?> getOriginalCtx() {
+        return originalCtx;
+    }
+
+    @Override
+    public void setOriginalCtx(StatementContextBase<?, ?, ?> originalCtx) {
+        this.originalCtx = originalCtx;
+    }
+
+    @Override
+    public ModelProcessingPhase getCompletedPhase() {
+        return completedPhase;
+    }
+
+    @Override
+    public void setCompletedPhase(ModelProcessingPhase completedPhase) {
+        this.completedPhase = completedPhase;
+    }
+
+    StatementContextBase(@Nonnull ContextBuilder<A, D, E> builder)
+            throws SourceException {
         this.definition = builder.getDefinition();
         this.identifier = builder.getIdentifier();
         this.statementDeclSource = builder.getStamementSource();
         this.completedPhase = null;
     }
 
-    StatementContextBase(StatementContextBase<A,D,E> original) {
+    StatementContextBase(StatementContextBase<A, D, E> original) {
         this.definition = original.definition;
         this.identifier = original.identifier;
         this.statementDeclSource = original.statementDeclSource;
@@ -135,7 +180,6 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     @Override
     public abstract RootStatementContext<?, ?, ?> getRoot();
 
-
     @Override
     public StatementIdentifier getIdentifier() {
         return identifier;
@@ -166,42 +210,45 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
         return Collections.unmodifiableCollection(effective);
     }
 
-    public void addEffectiveSubstatement(StatementContextBase<?, ?, ?> substatement){
+    public void addEffectiveSubstatement(
+            StatementContextBase<?, ?, ?> substatement) {
         effective.add(substatement);
     }
 
-    public void addDeclaredSubstatement(StatementContextBase<?, ?, ?> substatement){
+    public void addDeclaredSubstatement(
+            StatementContextBase<?, ?, ?> substatement) {
         declared.add(substatement);
     }
 
     @SuppressWarnings({ "rawtypes", "unchecked" })
-    public ContextBuilder<?, ?, ?> substatementBuilder(StatementDefinitionContext<?, ?, ?> def,
+    public ContextBuilder<?, ?, ?> substatementBuilder(
+            StatementDefinitionContext<?, ?, ?> def,
             StatementSourceReference ref) {
         return new ContextBuilder(def, ref) {
 
             @Override
             public StatementContextBase build() throws SourceException {
-                StatementContextBase<?, ?, ?> potential = substatements.get(getIdentifier());
-                if(potential == null) {
-                    potential = new SubstatementContext(StatementContextBase.this, this);
+                StatementContextBase<?, ?, ?> potential = substatements
+                        .get(getIdentifier());
+                if (potential == null) {
+                    potential = new SubstatementContext(
+                            StatementContextBase.this, this);
                     substatements.put(getIdentifier(), potential);
                 }
                 potential.resetLists();
                 switch (this.getStamementSource().getStatementSource()) {
-                    case DECLARATION:
-                        declared.add(potential);
-                        break;
-                    case CONTEXT:
-                        effective.add(potential);
-                        break;
+                case DECLARATION:
+                    declared.add(potential);
+                    break;
+                case CONTEXT:
+                    effective.add(potential);
+                    break;
                 }
                 return potential;
             }
         };
     }
 
-
-
     @Override
     public StorageNodeType getStorageNodeType() {
         return StorageNodeType.STATEMENT_LOCAL;
@@ -209,7 +256,9 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
 
     @Override
     public D buildDeclared() {
-        Preconditions.checkArgument(completedPhase == ModelProcessingPhase.FULL_DECLARATION || completedPhase == ModelProcessingPhase.EFFECTIVE_MODEL);
+        Preconditions
+                .checkArgument(completedPhase == ModelProcessingPhase.FULL_DECLARATION
+                        || completedPhase == ModelProcessingPhase.EFFECTIVE_MODEL);
         if (declaredInstance == null) {
             declaredInstance = definition().getFactory().createDeclared(this);
         }
@@ -218,52 +267,53 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
 
     @Override
     public E buildEffective() {
-        Preconditions.checkArgument(completedPhase == ModelProcessingPhase.EFFECTIVE_MODEL);
         if (effectiveInstance == null) {
             effectiveInstance = definition().getFactory().createEffective(this);
         }
         return effectiveInstance;
     }
 
-
     void resetLists() {
         declared.clear();
     }
 
-    boolean tryToCompletePhase(ModelProcessingPhase phase) throws SourceException {
-        if(phase.equals(completedPhase)) {
-            return true;
-        }
-        Iterator<ContextMutation> openMutations = phaseMutation.get(phase).iterator();
+    boolean tryToCompletePhase(ModelProcessingPhase phase)
+            throws SourceException {
+        Iterator<ContextMutation> openMutations = phaseMutation.get(phase)
+                .iterator();
         boolean finished = true;
-        while(openMutations.hasNext()) {
+        while (openMutations.hasNext()) {
             ContextMutation current = openMutations.next();
-            if(current.isFinished()) {
+            if (current.isFinished()) {
                 openMutations.remove();
             } else {
                 finished = false;
             }
         }
-        for(StatementContextBase<?, ?, ?> child: declared) {
+        for (StatementContextBase<?, ?, ?> child : declared) {
             finished &= child.tryToCompletePhase(phase);
         }
-        for(StatementContextBase<?, ?, ?> child: effective) {
+        for (StatementContextBase<?, ?, ?> child : effective) {
             finished &= child.tryToCompletePhase(phase);
         }
-        if(finished) {
+
+        if (finished) {
             onPhaseCompleted(phase);
             return true;
         }
         return false;
     }
 
-
-    private void onPhaseCompleted(ModelProcessingPhase phase) throws SourceException {
+    private void onPhaseCompleted(ModelProcessingPhase phase)
+            throws SourceException {
         completedPhase = phase;
-        Iterator<OnPhaseFinished> listener = phaseListeners.get(completedPhase).iterator();
-        while(listener.hasNext()) {
-            listener.next().phaseFinished(this, phase);
-            listener.remove();
+        Iterator<OnPhaseFinished> listener = phaseListeners.get(completedPhase)
+                .iterator();
+        while (listener.hasNext()) {
+            OnPhaseFinished next = listener.next();
+            if(next.phaseFinished(this, phase)) {
+             listener.remove();
+            }
         }
     }
 
@@ -275,8 +325,9 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
      * @throws SourceException
      *
      */
-    void endDeclared(StatementSourceReference ref,ModelProcessingPhase phase) throws SourceException {
-        definition().onDeclarationFinished(this,phase);
+    void endDeclared(StatementSourceReference ref, ModelProcessingPhase phase)
+            throws SourceException {
+        definition().onDeclarationFinished(this, phase);
     }
 
     protected final StatementDefinitionContext<A, D, E> definition() {
@@ -284,29 +335,35 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     }
 
     @Override
-    protected void checkLocalNamespaceAllowed(Class<? extends IdentifierNamespace<?, ?>> type) {
+    protected void checkLocalNamespaceAllowed(
+            Class<? extends IdentifierNamespace<?, ?>> type) {
         definition().checkNamespaceAllowed(type);
     }
 
     @Override
-    protected <K, V, N extends IdentifierNamespace<K, V>> void onNamespaceElementAdded(Class<N> type, K key, V value) {
-        //definition().onNamespaceElementAdded(this, type, key, value);
+    protected <K, V, N extends IdentifierNamespace<K, V>> void onNamespaceElementAdded(
+            Class<N> type, K key, V value) {
+        // definition().onNamespaceElementAdded(this, type, key, value);
     }
 
-    <K, V, N extends IdentifierNamespace<K, V>> void onNamespaceItemAddedAction(final Class<N> type, K key, final OnNamespaceItemAdded listener) throws SourceException {
+    <K, V, N extends IdentifierNamespace<K, V>> void onNamespaceItemAddedAction(
+            final Class<N> type, K key, final OnNamespaceItemAdded listener)
+            throws SourceException {
         Object potential = getFromNamespace(type, key);
-        if(potential != null) {
+        if (potential != null) {
             listener.namespaceItemAdded(this, type, key, potential);
             return;
         }
-        NamespaceBehaviour<K,V,N> behaviour = getBehaviourRegistry().getNamespaceBehaviour(type);
-        if(behaviour instanceof NamespaceBehaviourWithListeners) {
-            NamespaceBehaviourWithListeners<K, V, N> casted = (NamespaceBehaviourWithListeners<K,V,N>) behaviour;
+        NamespaceBehaviour<K, V, N> behaviour = getBehaviourRegistry()
+                .getNamespaceBehaviour(type);
+        if (behaviour instanceof NamespaceBehaviourWithListeners) {
+            NamespaceBehaviourWithListeners<K, V, N> casted = (NamespaceBehaviourWithListeners<K, V, N>) behaviour;
             casted.addValueListener(key, new ValueAddedListener(this) {
                 @Override
                 void onValueAdded(Object key, Object value) {
                     try {
-                        listener.namespaceItemAdded(StatementContextBase.this, type, key, value);
+                        listener.namespaceItemAdded(StatementContextBase.this,
+                                type, key, value);
                     } catch (SourceException e) {
                         throw Throwables.propagate(e);
                     }
@@ -325,10 +382,11 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
         return getRoot().getSourceContext().newInferenceAction(phase);
     }
 
-    void addPhaseCompletedListener(ModelProcessingPhase phase, OnPhaseFinished listener) throws SourceException {
+    void addPhaseCompletedListener(ModelProcessingPhase phase,
+            OnPhaseFinished listener) throws SourceException {
         ModelProcessingPhase finishedPhase = completedPhase;
         while (finishedPhase != null) {
-            if(phase.equals(finishedPhase)) {
+            if (phase.equals(finishedPhase)) {
                 listener.phaseFinished(this, finishedPhase);
                 return;
             }
@@ -340,8 +398,9 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     void addMutation(ModelProcessingPhase phase, ContextMutation mutation) {
         ModelProcessingPhase finishedPhase = completedPhase;
         while (finishedPhase != null) {
-            if(phase.equals(finishedPhase)) {
-                throw new IllegalStateException("Mutation registered after phase was completed.");
+            if (phase.equals(finishedPhase)) {
+                throw new IllegalStateException(
+                        "Mutation registered after phase was completed.");
             }
             finishedPhase = finishedPhase.getPreviousPhase();
         }
@@ -349,8 +408,8 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     }
 
     @Override
-    public <K,KT extends K, N extends StatementNamespace<K, ?, ?>> void addContext(
+    public <K, KT extends K, N extends StatementNamespace<K, ?, ?>> void addContext(
             Class<N> namespace, KT key, StmtContext<?, ?, ?> stmt) {
-        addContextToNamespace(namespace,(K) key, stmt);
+        addContextToNamespace(namespace, (K) key, stmt);
     }
 }
index 2e78e75ed28b8b5188df2364c3e8c392ec918496..7fd1442691ffb4ee9b412c664381372a495bc5d4 100644 (file)
@@ -13,7 +13,6 @@ 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.parser.spi.meta.ModelProcessingPhase;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceNotAvailableException;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementFactory;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
@@ -36,7 +35,7 @@ public class StatementDefinitionContext<A,D extends DeclaredStatement<A>,E exten
     }
 
 
-    public void checkNamespaceAllowed(Class<? extends IdentifierNamespace<?,?>> namespace) throws NamespaceNotAvailableException {
+    public void checkNamespaceAllowed(Class<? extends IdentifierNamespace<?,?>> namespace) {
         // Noop
     }
 
index 29cac6ead5da3f4ab38db09a453b014ec8c5d547..f921e13b2adb0cae97135ab46aec2e91488d1cbe 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 
 import java.util.List;
-
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.GroupingUtils;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import java.util.Collection;
@@ -20,43 +19,50 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Namesp
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 
-class SubstatementContext<A,D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
-    extends StatementContextBase<A,D,E> {
+class SubstatementContext<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
+        extends StatementContextBase<A, D, E> {
 
-    private final StatementContextBase<?,?,?> parent;
+    private final StatementContextBase<?, ?, ?> parent;
     private final A argument;
 
-    SubstatementContext(StatementContextBase<?,?,?> parent,ContextBuilder<A,D,E> builder) throws SourceException {
-        //super(builder,  builder.getDefinition().parseArgumentValue(parent, builder.getRawArgument()));
+    SubstatementContext(StatementContextBase<?, ?, ?> parent,
+            ContextBuilder<A, D, E> builder) throws SourceException {
         super(builder);
-        this.parent = Preconditions.checkNotNull(parent, "Parent must not be null");
-        this.argument =   builder.getDefinition().parseArgumentValue(this, builder.getRawArgument());
+        this.parent = Preconditions.checkNotNull(parent,
+                "Parent must not be null");
+        this.argument = builder.getDefinition().parseArgumentValue(this,
+                builder.getRawArgument());
     }
 
-    SubstatementContext(SubstatementContext<A,D,E> original, QNameModule newQNameModule, StatementContextBase<?, ?, ?> newParent) throws SourceException {
+    SubstatementContext(SubstatementContext<A, D, E> original,
+            QNameModule newQNameModule,
+            StatementContextBase<?, ?, ?> newParent, TypeOfCopy typeOfCopy)
+            throws SourceException {
         super(original);
         this.parent = newParent;
 
-        if(newQNameModule != null && original.argument instanceof QName) {
+        if (newQNameModule != null && original.argument instanceof QName) {
             QName originalQName = (QName) original.argument;
-            this.argument =  (A) QName.create(newQNameModule,originalQName.getLocalName());
+            this.argument = (A) QName.create(newQNameModule,
+                    originalQName.getLocalName());
         } else {
             this.argument = original.argument;
         }
 
-        copyDeclaredStmts(original, newQNameModule);
+        copyDeclaredStmts(original, newQNameModule, typeOfCopy);
 
-        copyEffectiveStmts(original, newQNameModule);
+        copyEffectiveStmts(original, newQNameModule, typeOfCopy);
     }
 
     private void copyDeclaredStmts(SubstatementContext<A, D, E> original,
-            QNameModule newQNameModule) throws SourceException {
+            QNameModule newQNameModule, TypeOfCopy typeOfCopy)
+            throws SourceException {
         Collection<? extends StatementContextBase<?, ?, ?>> originalDeclaredSubstatements = original
                 .declaredSubstatements();
         for (StatementContextBase<?, ?, ?> stmtContext : originalDeclaredSubstatements) {
             if (GroupingUtils.needToCopyByUses(stmtContext)) {
-                StatementContextBase<?, ?, ?> copy = stmtContext
-                        .createCopy(newQNameModule,this);
+                StatementContextBase<?, ?, ?> copy = stmtContext.createCopy(
+                        newQNameModule, this, typeOfCopy);
                 this.addEffectiveSubstatement(copy);
             } else if (GroupingUtils.isReusedByUses(stmtContext)) {
                 this.addEffectiveSubstatement(stmtContext);
@@ -65,13 +71,14 @@ class SubstatementContext<A,D extends DeclaredStatement<A>, E extends EffectiveS
     }
 
     private void copyEffectiveStmts(SubstatementContext<A, D, E> original,
-            QNameModule newQNameModule) throws SourceException {
+            QNameModule newQNameModule, TypeOfCopy typeOfCopy)
+            throws SourceException {
         Collection<? extends StatementContextBase<?, ?, ?>> originalEffectiveSubstatements = original
                 .effectiveSubstatements();
         for (StatementContextBase<?, ?, ?> stmtContext : originalEffectiveSubstatements) {
             if (GroupingUtils.needToCopyByUses(stmtContext)) {
-                StatementContextBase<?, ?, ?> copy = stmtContext
-                        .createCopy(newQNameModule,this);
+                StatementContextBase<?, ?, ?> copy = stmtContext.createCopy(
+                        newQNameModule, this, typeOfCopy);
                 this.addEffectiveSubstatement(copy);
             } else if (GroupingUtils.isReusedByUses(stmtContext)) {
                 this.addEffectiveSubstatement(stmtContext);
@@ -80,7 +87,7 @@ class SubstatementContext<A,D extends DeclaredStatement<A>, E extends EffectiveS
     }
 
     @Override
-    public StatementContextBase<?,?,?> getParentContext() {
+    public StatementContextBase<?, ?, ?> getParentContext() {
         return parent;
     }
 
@@ -99,15 +106,19 @@ class SubstatementContext<A,D extends DeclaredStatement<A>, E extends EffectiveS
         return parent.getRoot();
     }
 
-
     @Override
     public A getStatementArgument() {
         return argument;
     }
 
     @Override
-    public StatementContextBase<A, D, E>  createCopy(QNameModule newQNameModule, StatementContextBase<?, ?, ?> newParent) throws SourceException {
-        StatementContextBase<A,D,E> copy = new SubstatementContext<A,D,E>(this,newQNameModule, newParent);
+    public StatementContextBase<A, D, E> createCopy(QNameModule newQNameModule,
+            StatementContextBase<?, ?, ?> newParent, TypeOfCopy typeOfCopy)
+            throws SourceException {
+        SubstatementContext<A, D, E> copy = new SubstatementContext<>(this,
+                newQNameModule, newParent, typeOfCopy);
+        copy.setTypeOfCopy(typeOfCopy);
+        copy.setOriginalCtx(this);
         return copy;
     }
 
@@ -118,5 +129,8 @@ class SubstatementContext<A,D extends DeclaredStatement<A>, E extends EffectiveS
         return argumentsFromRoot;
     }
 
-
+    @Override
+    public boolean isRootContext() {
+        return false;
+    }
 }
index 54dd02353de6eef7e5ca57ee4dede45965284a56..43af34cde4d0452c3f3132204d304ac786551b2f 100644 (file)
@@ -7,13 +7,10 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
-import static org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase.EFFECTIVE_MODEL;
-
 import java.util.Collection;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import javax.annotation.Nonnull;
-
 import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement;
@@ -29,27 +26,37 @@ import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.AugmentEffectiveStatementImpl;
 
-public class AugmentStatementImpl extends AbstractDeclaredStatement<SchemaNodeIdentifier> implements AugmentStatement {
+public class AugmentStatementImpl extends
+        AbstractDeclaredStatement<SchemaNodeIdentifier> implements
+        AugmentStatement {
 
-    private static final Logger LOG = LoggerFactory.getLogger(AugmentStatementImpl.class);
+    private static final Logger LOG = LoggerFactory
+            .getLogger(AugmentStatementImpl.class);
 
-    protected AugmentStatementImpl(StmtContext<SchemaNodeIdentifier, AugmentStatement, ?> context) {
+    protected AugmentStatementImpl(
+            StmtContext<SchemaNodeIdentifier, AugmentStatement, ?> context) {
         super(context);
     }
 
-    public static class Definition extends AbstractStatementSupport<SchemaNodeIdentifier, AugmentStatement, EffectiveStatement<SchemaNodeIdentifier, AugmentStatement>> {
+    public static class Definition
+            extends
+            AbstractStatementSupport<SchemaNodeIdentifier, AugmentStatement, EffectiveStatement<SchemaNodeIdentifier, AugmentStatement>> {
 
         public Definition() {
             super(Rfc6020Mapping.AUGMENT);
         }
 
         @Override
-        public SchemaNodeIdentifier parseArgumentValue(StmtContext<?, ?, ?> ctx, String value) throws SourceException {
-            return SchemaNodeIdentifier.create(AugmentUtils.parseAugmentPath(ctx, value), Utils.isXPathAbsolute(value));
+        public SchemaNodeIdentifier parseArgumentValue(
+                StmtContext<?, ?, ?> ctx, String value) throws SourceException {
+            return SchemaNodeIdentifier.create(
+                    AugmentUtils.parseAugmentPath(ctx, value),
+                    Utils.isXPathAbsolute(value));
         }
 
         @Override
-        public AugmentStatement createDeclared(StmtContext<SchemaNodeIdentifier, AugmentStatement, ?> ctx) {
+        public AugmentStatement createDeclared(
+                StmtContext<SchemaNodeIdentifier, AugmentStatement, ?> ctx) {
             return new AugmentStatementImpl(ctx);
         }
 
@@ -64,31 +71,42 @@ public class AugmentStatementImpl extends AbstractDeclaredStatement<SchemaNodeId
                 final StmtContext.Mutable<SchemaNodeIdentifier, AugmentStatement, EffectiveStatement<SchemaNodeIdentifier, AugmentStatement>> augmentNode)
                 throws SourceException {
 
-            final ModelActionBuilder augmentAction = augmentNode.newInferenceAction(EFFECTIVE_MODEL);
+            final ModelActionBuilder augmentAction = augmentNode
+                    .newInferenceAction(ModelProcessingPhase.FULL_DECLARATION);
             final ModelActionBuilder.Prerequisite<StmtContext<SchemaNodeIdentifier, AugmentStatement, EffectiveStatement<SchemaNodeIdentifier, AugmentStatement>>> sourceCtxPrereq = augmentAction
-                    .requiresCtx(augmentNode, ModelProcessingPhase.FULL_DECLARATION);
+                    .requiresCtx(augmentNode,
+                            ModelProcessingPhase.FULL_DECLARATION);
 
             augmentAction.apply(new ModelActionBuilder.InferenceAction() {
 
                 @Override
                 public void apply() throws InferenceException {
 
-                    final StatementContextBase<?, ?, ?> augmentTargetCtx = AugmentUtils.getAugmentTargetCtx(augmentNode);
-                    final StatementContextBase<?, ?, ?> augmentSourceCtx = (StatementContextBase<?, ?, ?>) sourceCtxPrereq.get();
+                    final StatementContextBase<?, ?, ?> augmentTargetCtx = AugmentUtils
+                            .getAugmentTargetCtx(augmentNode);
+
+                    if (augmentTargetCtx == null) {
+                        throw new InferenceException("Augment target not found: "+augmentNode.getStatementArgument(), augmentNode.getStatementSourceReference());
+                    }
+
+                    final StatementContextBase<?, ?, ?> augmentSourceCtx = (StatementContextBase<?, ?, ?>) sourceCtxPrereq
+                            .get();
 
                     try {
-                        AugmentUtils.copyFromSourceToTarget(augmentSourceCtx, augmentTargetCtx);
+                        AugmentUtils.copyFromSourceToTarget(augmentSourceCtx,
+                                augmentTargetCtx);
                     } catch (SourceException e) {
                         LOG.warn(e.getMessage(), e);
                     }
+
                 }
 
                 @Override
-                public void prerequisiteFailed(final Collection<? extends ModelActionBuilder.Prerequisite<?>> failed)
+                public void prerequisiteFailed(
+                        final Collection<? extends ModelActionBuilder.Prerequisite<?>> failed)
                         throws InferenceException {
-                    if (failed.contains(augmentAction)) {
-                        throw new InferenceException("Augment action failed", augmentNode.getStatementSourceReference());
-                    }
+                        throw new InferenceException("Augment target not found: "+augmentNode.getStatementArgument(),
+                                augmentNode.getStatementSourceReference());
                 }
             });
         }
index 3b9c18c0333b2a441a8b2e1cb21acf46e0888a01..9d99af203aa5c8077996b7e58e1bddac95bebff6 100644 (file)
@@ -7,10 +7,16 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
+import java.util.Iterator;
+import javax.annotation.Nullable;
+
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
@@ -18,22 +24,25 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
+import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
 import org.opendaylight.yangtools.yang.parser.spi.NamespaceToModule;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
 
 public final class AugmentUtils {
 
-    private AugmentUtils() {
-    }
-
     private static final String REGEX_PATH_REL1 = "\\.\\.?\\s*/(.+)";
     private static final String REGEX_PATH_REL2 = "//.*";
 
-    public static Iterable<QName> parseAugmentPath(StmtContext<?, ?, ?> ctx, String path) {
+    private AugmentUtils() {
+    }
+
+    public static Iterable<QName> parseAugmentPath(StmtContext<?, ?, ?> ctx,
+            String path) {
 
         if (path.matches(REGEX_PATH_REL1) || path.matches(REGEX_PATH_REL2)) {
             throw new IllegalArgumentException(
@@ -43,7 +52,8 @@ public final class AugmentUtils {
         return Utils.parseXPath(ctx, path);
     }
 
-    public static void copyFromSourceToTarget(StatementContextBase<?, ?, ?> sourceCtx,
+    public static void copyFromSourceToTarget(
+            StatementContextBase<?, ?, ?> sourceCtx,
             StatementContextBase<?, ?, ?> targetCtx) throws SourceException {
 
         QNameModule newQNameModule = getNewQNameModule(targetCtx, sourceCtx);
@@ -52,12 +62,17 @@ public final class AugmentUtils {
 
     }
 
-    public static void copyDeclaredStmts(StatementContextBase<?, ?, ?> sourceCtx,
-            StatementContextBase<?, ?, ?> targetCtx, QNameModule newQNameModule) throws SourceException {
-        Collection<? extends StatementContextBase<?, ?, ?>> declaredSubstatements = sourceCtx.declaredSubstatements();
+    public static void copyDeclaredStmts(
+            StatementContextBase<?, ?, ?> sourceCtx,
+            StatementContextBase<?, ?, ?> targetCtx, QNameModule newQNameModule)
+            throws SourceException {
+        Collection<? extends StatementContextBase<?, ?, ?>> declaredSubstatements = sourceCtx
+                .declaredSubstatements();
         for (StatementContextBase<?, ?, ?> originalStmtCtx : declaredSubstatements) {
             if (needToCopyByAugment(originalStmtCtx)) {
-                StatementContextBase<?, ?, ?> copy = originalStmtCtx.createCopy(newQNameModule, targetCtx);
+                StatementContextBase<?, ?, ?> copy = originalStmtCtx
+                        .createCopy(newQNameModule, targetCtx,
+                                TypeOfCopy.ADDED_BY_AUGMENTATION);
                 targetCtx.addEffectiveSubstatement(copy);
             } else if (isReusedByAugment(originalStmtCtx)) {
                 targetCtx.addEffectiveSubstatement(originalStmtCtx);
@@ -65,12 +80,17 @@ public final class AugmentUtils {
         }
     }
 
-    public static void copyEffectiveStmts(StatementContextBase<?, ?, ?> sourceCtx,
-            StatementContextBase<?, ?, ?> targetCtx, QNameModule newQNameModule) throws SourceException {
-        Collection<? extends StatementContextBase<?, ?, ?>> effectiveSubstatements = sourceCtx.effectiveSubstatements();
+    public static void copyEffectiveStmts(
+            StatementContextBase<?, ?, ?> sourceCtx,
+            StatementContextBase<?, ?, ?> targetCtx, QNameModule newQNameModule)
+            throws SourceException {
+        Collection<? extends StatementContextBase<?, ?, ?>> effectiveSubstatements = sourceCtx
+                .effectiveSubstatements();
         for (StatementContextBase<?, ?, ?> originalStmtCtx : effectiveSubstatements) {
             if (needToCopyByAugment(originalStmtCtx)) {
-                StatementContextBase<?, ?, ?> copy = originalStmtCtx.createCopy(newQNameModule, targetCtx);
+                StatementContextBase<?, ?, ?> copy = originalStmtCtx
+                        .createCopy(newQNameModule, targetCtx,
+                                TypeOfCopy.ADDED_BY_AUGMENTATION);
                 targetCtx.addEffectiveSubstatement(copy);
             } else if (isReusedByAugment(originalStmtCtx)) {
                 targetCtx.addEffectiveSubstatement(originalStmtCtx);
@@ -78,13 +98,15 @@ public final class AugmentUtils {
         }
     }
 
-    public static QNameModule getNewQNameModule(StatementContextBase<?, ?, ?> targetCtx,
+    public static QNameModule getNewQNameModule(
+            StatementContextBase<?, ?, ?> targetCtx,
             StatementContextBase<?, ?, ?> sourceCtx) {
         Object targetStmtArgument = targetCtx.getStatementArgument();
 
         final StatementContextBase<?, ?, ?> root = sourceCtx.getRoot();
         final String moduleName = (String) root.getStatementArgument();
-        final QNameModule sourceQNameModule = root.getFromNamespace(ModuleNameToModuleQName.class, moduleName);
+        final QNameModule sourceQNameModule = root.getFromNamespace(
+                ModuleNameToModuleQName.class, moduleName);
 
         if (targetStmtArgument instanceof QName) {
             QName targetQName = (QName) targetStmtArgument;
@@ -106,48 +128,137 @@ public final class AugmentUtils {
         noCopyDefSet.add(Rfc6020Mapping.USES);
 
         StatementDefinition def = stmtContext.getPublicDefinition();
-        return (!noCopyDefSet.contains(def));
+        return !noCopyDefSet.contains(def);
     }
 
     public static boolean isReusedByAugment(StmtContext<?, ?, ?> stmtContext) {
 
-        HashSet<StatementDefinition> reusedDefSet = new HashSet<>();
+        Set<StatementDefinition> reusedDefSet = new HashSet<>();
         reusedDefSet.add(Rfc6020Mapping.TYPEDEF);
 
         StatementDefinition def = stmtContext.getPublicDefinition();
-        if (reusedDefSet.contains(def))
-            return true;
-        else
-            return false;
+
+        return reusedDefSet.contains(def);
     }
 
     public static StatementContextBase<?, ?, ?> getAugmentTargetCtx(
             final Mutable<SchemaNodeIdentifier, AugmentStatement, EffectiveStatement<SchemaNodeIdentifier, AugmentStatement>> augmentNode) {
 
-        final SchemaNodeIdentifier augmentTargetPath = augmentNode.getStatementArgument();
-
-        QNameModule module;
-        if (augmentTargetPath != null) {
-            module = augmentTargetPath.getPathFromRoot().iterator().next().getModule();
-        } else {
+        final SchemaNodeIdentifier augmentTargetNode = augmentNode
+                .getStatementArgument();
+        if (augmentTargetNode == null) {
             throw new IllegalArgumentException(
                     "Augment argument null, something bad happened in some of previous parsing phases");
         }
 
-        StatementContextBase<?, ?, ?> rootStatementCtx = (StatementContextBase<?, ?, ?>) augmentNode.getFromNamespace(
-                NamespaceToModule.class, module);
+        List<StatementContextBase<?, ?, ?>> rootStatementCtxList = new LinkedList<>();
 
-        final StatementContextBase<?, ?, ?> augmentTargetCtx = Utils.findCtxOfNodeInRoot(rootStatementCtx,
-                augmentTargetPath);
+        if (augmentTargetNode.isAbsolute()) {
 
-        if (augmentTargetCtx == null) {
+            QNameModule module = augmentTargetNode.getPathFromRoot().iterator()
+                    .next().getModule();
 
-            throw new NullPointerException(String.format(
-                    "Augment path %s not found in target model so its resulting context is null",
-                    augmentNode.rawStatementArgument()));
+            StatementContextBase<?, ?, ?> rootStatementCtx = (StatementContextBase<?, ?, ?>) augmentNode
+                    .getFromNamespace(NamespaceToModule.class, module);
+            rootStatementCtxList.add(rootStatementCtx);
 
+            final Map<?, ?> subModules = rootStatementCtx
+                    .getAllFromNamespace(IncludedModuleContext.class);
+            if (subModules != null) {
+                rootStatementCtxList
+                        .addAll((Collection<? extends StatementContextBase<?, ?, ?>>) subModules
+                                .values());
+            }
+
+        } else {
+            StatementContextBase<?, ?, ?> parent = (StatementContextBase<?, ?, ?>) augmentNode
+                    .getParentContext();
+            if (StmtContextUtils.producesDeclared(parent, UsesStatement.class)) {
+                rootStatementCtxList.add(parent.getParentContext());
+            } else {
+                // error
+            }
+        }
+
+        StatementContextBase<?, ?, ?> augmentTargetCtx = null;
+        for (final StatementContextBase<?, ?, ?> rootStatementCtx : rootStatementCtxList) {
+            augmentTargetCtx = findCtxOfNodeInRoot(rootStatementCtx,
+                    augmentTargetNode);
+            if (augmentTargetCtx != null)
+                break;
         }
 
         return augmentTargetCtx;
     }
+
+    @Nullable
+    public static StatementContextBase<?, ?, ?> findCtxOfNodeInSubstatements(
+            StatementContextBase<?, ?, ?> rootStmtCtx,
+            final Iterable<QName> path) {
+
+        StatementContextBase<?, ?, ?> parent = rootStmtCtx;
+
+        Iterator<QName> pathIter = path.iterator();
+        while (pathIter.hasNext()) {
+            QName nextPathQName = pathIter.next();
+            StatementContextBase<?, ?, ?> foundSubstatement = getSubstatementByQName(
+                    parent, nextPathQName);
+
+            if (foundSubstatement == null) {
+                return null;
+            }
+            if (!pathIter.hasNext()) {
+                return foundSubstatement;
+            }
+
+            parent = foundSubstatement;
+        }
+
+        return null;
+    }
+
+    public static StatementContextBase<?, ?, ?> getSubstatementByQName(
+            StatementContextBase<?, ?, ?> parent, QName nextPathQName) {
+
+        Collection<StatementContextBase<?, ?, ?>> declaredSubstatement = parent
+                .declaredSubstatements();
+        Collection<StatementContextBase<?, ?, ?>> effectiveSubstatement = parent
+                .effectiveSubstatements();
+
+        Collection<StatementContextBase<?, ?, ?>> allSubstatements = new LinkedList<>();
+        allSubstatements.addAll(declaredSubstatement);
+        allSubstatements.addAll(effectiveSubstatement);
+
+        for (StatementContextBase<?, ?, ?> substatement : allSubstatements) {
+            if (isAllowedAugmentTarget(substatement)
+                    && nextPathQName
+                            .equals(substatement.getStatementArgument())) {
+                return substatement;
+            }
+        }
+
+        return null;
+    }
+
+    public static boolean isAllowedAugmentTarget(
+            StatementContextBase<?, ?, ?> substatement) {
+
+        /*
+         * :TODO Substatement must be allowed augment target type e.g.
+         * Container, etc... and must be not for example grouping, identity etc.
+         * It is problem in case when more than one substatements have the same
+         * QName, for example Grouping and Container are siblings and they have the
+         * same QName. We must find the Container and the Grouping must be ignored
+         * as disallowed augment target.
+         */
+
+        return true;
+    }
+
+    @Nullable
+    public static StatementContextBase<?, ?, ?> findCtxOfNodeInRoot(
+            StatementContextBase<?, ?, ?> rootStmtCtx,
+            final SchemaNodeIdentifier node) {
+        return findCtxOfNodeInSubstatements(rootStmtCtx, node.getPathFromRoot());
+    }
 }
index 316013160333f79d9b925299ca0ed70ec0513cf4..2aca8a1c806ef0e68bfc7ba4232554fef6bd5cb1 100644 (file)
@@ -7,9 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.CaseEffectiveStatementImpl;
+import java.util.Collection;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.PresenceEffectiveStatementImpl;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
@@ -24,9 +26,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import java.util.Collection;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.CaseEffectiveStatementImpl;
 
 public class CaseStatementImpl extends AbstractDeclaredStatement<QName> implements CaseStatement {
 
index 56755e411c02d4a821a22706c820b8adfe69bfff..5186596ad14d263dfc0cb9bdca7863fe6912e19e 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
+import org.opendaylight.yangtools.yang.model.api.Deviation;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.DeviateEffectiveStatementImpl;
 
 import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
@@ -16,39 +17,41 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+
 import javax.annotation.Nonnull;
 
-public class DeviateStatementImpl extends AbstractDeclaredStatement<String> implements DeviateStatement {
+public class DeviateStatementImpl extends AbstractDeclaredStatement<Deviation.Deviate> implements DeviateStatement {
 
     protected DeviateStatementImpl(
-            StmtContext<String, DeviateStatement, ?> context) {
+            StmtContext<Deviation.Deviate, DeviateStatement, ?> context) {
         super(context);
     }
 
-    public static class Definition extends AbstractStatementSupport<String,DeviateStatement,EffectiveStatement<String,DeviateStatement>> {
+    public static class Definition extends AbstractStatementSupport<Deviation.Deviate,DeviateStatement,EffectiveStatement<Deviation.Deviate,DeviateStatement>> {
 
         public Definition() {
             super(Rfc6020Mapping.DEVIATE);
         }
 
-        @Override public String parseArgumentValue(
+        @Override public Deviation.Deviate parseArgumentValue(
                 StmtContext<?, ?, ?> ctx, String value) throws SourceException {
-            return value;
+            return Utils.parseDeviateFromString(value);
         }
 
         @Override public DeviateStatement createDeclared(
-                StmtContext<String, DeviateStatement, ?> ctx) {
+                StmtContext<Deviation.Deviate, DeviateStatement, ?> ctx) {
             return new DeviateStatementImpl(ctx);
         }
 
-        @Override public EffectiveStatement<String, DeviateStatement> createEffective(
-                StmtContext<String, DeviateStatement, EffectiveStatement<String, DeviateStatement>> ctx) {
+        @Override public EffectiveStatement<Deviation.Deviate, DeviateStatement> createEffective(
+                StmtContext<Deviation.Deviate, DeviateStatement, EffectiveStatement<Deviation.Deviate, DeviateStatement>> ctx) {
             return new DeviateEffectiveStatementImpl(ctx);
         }
+
     }
 
     @Nonnull @Override
-    public String getValue() {
-        return rawArgument();
+    public Deviation.Deviate getValue() {
+        return argument();
     }
 }
index 2e9c54ffdd57abdf1be777a57ddc3719311f86c4..e3ff0d39fb7a3092fc9b6e062ac8c95252eb904c 100644 (file)
@@ -8,18 +8,20 @@
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ExtensionEffectiveStatementImpl;
-
-import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentStatement;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentStatement;
 import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.StatusStatement;
+import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 
 public class ExtensionStatementImpl extends AbstractDeclaredStatement<QName> implements ExtensionStatement {
 
@@ -35,7 +37,7 @@ public class ExtensionStatementImpl extends AbstractDeclaredStatement<QName> imp
 
         @Override
         public QName parseArgumentValue(StmtContext<?,?,?> ctx, String value) {
-            return Utils.qNameFromArgument(ctx,value);
+            return Utils.qNameFromArgument(ctx, value);
         }
 
         @Override
@@ -48,6 +50,10 @@ public class ExtensionStatementImpl extends AbstractDeclaredStatement<QName> imp
            return new ExtensionEffectiveStatementImpl(ctx);
         }
 
+        @Override
+        public void onStatementDefinitionDeclared(final StmtContext.Mutable<QName, ExtensionStatement, EffectiveStatement<QName, ExtensionStatement>> stmt) throws InferenceException, SourceException {
+            stmt.addContext(ExtensionNamespace.class, stmt.getStatementArgument(), stmt);
+        }
     }
 
     @Override
index 4f2a7ce735e2f3b6db6649d5f23005a0a09acf82..30d6ef0769c46e933d3bf28edf829299c98469eb 100644 (file)
@@ -7,25 +7,24 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.GroupingEffectiveStatementImpl;
-
-import org.opendaylight.yangtools.yang.parser.spi.GroupingNamespace;
-import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
-import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import java.util.Collection;
+
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.DataDefinitionStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.StatusStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement;
+import org.opendaylight.yangtools.yang.parser.spi.GroupingNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.GroupingEffectiveStatementImpl;
 
 public class GroupingStatementImpl extends AbstractDeclaredStatement<QName>
         implements GroupingStatement {
index f5a996dbe099fb2156004a0108534824ac31b4a8..9802db52b3b520c2d745005b46c46a1679d46f27 100644 (file)
@@ -7,10 +7,12 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
+import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
+
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
@@ -21,8 +23,8 @@ import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
 
@@ -36,27 +38,22 @@ public final class GroupingUtils {
      * @param targetCtx
      * @throws SourceException
      */
-    public static void copyFromSourceToTarget(
-            StatementContextBase<?, ?, ?> sourceGrpStmtCtx,
+    public static void copyFromSourceToTarget(StatementContextBase<?, ?, ?> sourceGrpStmtCtx,
             StatementContextBase<?, ?, ?> targetCtx) throws SourceException {
 
-        QNameModule newQNameModule = getNewQNameModule(targetCtx,
-                sourceGrpStmtCtx);
+        QNameModule newQNameModule = getNewQNameModule(targetCtx, sourceGrpStmtCtx);
         copyDeclaredStmts(sourceGrpStmtCtx, targetCtx, newQNameModule);
         copyEffectiveStmts(sourceGrpStmtCtx, targetCtx, newQNameModule);
 
     }
 
-    public static void copyDeclaredStmts(
-            StatementContextBase<?, ?, ?> sourceGrpStmtCtx,
-            StatementContextBase<?, ?, ?> targetCtx, QNameModule newQNameModule)
-            throws SourceException {
+    public static void copyDeclaredStmts(StatementContextBase<?, ?, ?> sourceGrpStmtCtx,
+            StatementContextBase<?, ?, ?> targetCtx, QNameModule newQNameModule) throws SourceException {
         Collection<? extends StatementContextBase<?, ?, ?>> declaredSubstatements = sourceGrpStmtCtx
                 .declaredSubstatements();
         for (StatementContextBase<?, ?, ?> originalStmtCtx : declaredSubstatements) {
             if (needToCopyByUses(originalStmtCtx)) {
-                StatementContextBase<?, ?, ?> copy = originalStmtCtx
-                        .createCopy(newQNameModule, targetCtx);
+                StatementContextBase<?, ?, ?> copy = originalStmtCtx.createCopy(newQNameModule, targetCtx, TypeOfCopy.ADDED_BY_USES);
                 targetCtx.addEffectiveSubstatement(copy);
             } else if (isReusedByUses(originalStmtCtx)) {
                 targetCtx.addEffectiveSubstatement(originalStmtCtx);
@@ -64,16 +61,13 @@ public final class GroupingUtils {
         }
     }
 
-    public static void copyEffectiveStmts(
-            StatementContextBase<?, ?, ?> sourceGrpStmtCtx,
-            StatementContextBase<?, ?, ?> targetCtx, QNameModule newQNameModule)
-            throws SourceException {
+    public static void copyEffectiveStmts(StatementContextBase<?, ?, ?> sourceGrpStmtCtx,
+            StatementContextBase<?, ?, ?> targetCtx, QNameModule newQNameModule) throws SourceException {
         Collection<? extends StatementContextBase<?, ?, ?>> effectiveSubstatements = sourceGrpStmtCtx
                 .effectiveSubstatements();
         for (StatementContextBase<?, ?, ?> originalStmtCtx : effectiveSubstatements) {
             if (needToCopyByUses(originalStmtCtx)) {
-                StatementContextBase<?, ?, ?> copy = originalStmtCtx
-                        .createCopy(newQNameModule, targetCtx);
+                StatementContextBase<?, ?, ?> copy = originalStmtCtx.createCopy(newQNameModule, targetCtx, TypeOfCopy.ADDED_BY_USES);
                 targetCtx.addEffectiveSubstatement(copy);
             } else if (isReusedByUses(originalStmtCtx)) {
                 targetCtx.addEffectiveSubstatement(originalStmtCtx);
@@ -81,14 +75,15 @@ public final class GroupingUtils {
         }
     }
 
-    public static QNameModule getNewQNameModule(
-            StatementContextBase<?, ?, ?> targetCtx,
+    public static QNameModule getNewQNameModule(StatementContextBase<?, ?, ?> targetCtx,
             StmtContext<?, ?, ?> stmtContext) {
         if (needToCreateNewQName(stmtContext.getPublicDefinition())) {
+            if(targetCtx.isRootContext()) {
+                return targetCtx.getFromNamespace(ModuleNameToModuleQName.class, targetCtx.rawStatementArgument());
+            }
             Object targetStmtArgument = targetCtx.getStatementArgument();
             Object sourceStmtArgument = stmtContext.getStatementArgument();
-            if (targetStmtArgument instanceof QName
-                    && sourceStmtArgument instanceof QName) {
+            if (targetStmtArgument instanceof QName && sourceStmtArgument instanceof QName) {
                 QName targetQName = (QName) targetStmtArgument;
                 QNameModule targetQNameModule = targetQName.getModule();
 
@@ -97,8 +92,7 @@ public final class GroupingUtils {
 
                 if (targetQNameModule.equals(sourceQNameModule)) {
                     return null;
-                }
-                else {
+                } else {
                     return targetQNameModule;
                 }
             } else {
@@ -109,8 +103,7 @@ public final class GroupingUtils {
         }
     }
 
-    public static boolean needToCreateNewQName(
-            StatementDefinition publicDefinition) {
+    public static boolean needToCreateNewQName(StatementDefinition publicDefinition) {
         return true;
     }
 
@@ -120,7 +113,7 @@ public final class GroupingUtils {
         noCopyDefSet.add(Rfc6020Mapping.USES);
 
         StatementDefinition def = stmtContext.getPublicDefinition();
-        return (!noCopyDefSet.contains(def));
+        return !noCopyDefSet.contains(def);
     }
 
     public static boolean isReusedByUses(StmtContext<?, ?, ?> stmtContext) {
@@ -129,29 +122,23 @@ public final class GroupingUtils {
         reusedDefSet.add(Rfc6020Mapping.TYPEDEF);
 
         StatementDefinition def = stmtContext.getPublicDefinition();
-        return (reusedDefSet.contains(def));
+        return reusedDefSet.contains(def);
     }
 
     public static void resolveUsesNode(
             Mutable<QName, UsesStatement, EffectiveStatement<QName, UsesStatement>> usesNode,
-            StatementContextBase<?, ?, ?> targetNodeStmtCtx)
-            throws SourceException {
+            StatementContextBase<?, ?, ?> targetNodeStmtCtx) throws SourceException {
 
-        Collection<StatementContextBase<?, ?, ?>> declaredSubstatements = usesNode
-                .declaredSubstatements();
+        Collection<StatementContextBase<?, ?, ?>> declaredSubstatements = usesNode.declaredSubstatements();
         for (StatementContextBase<?, ?, ?> subStmtCtx : declaredSubstatements) {
-            if (StmtContextUtils.producesDeclared(subStmtCtx,
-                    WhenStatement.class)) {
-                StatementContextBase<?, ?, ?> copy = subStmtCtx.createCopy(
-                        null, targetNodeStmtCtx);
+            if (StmtContextUtils.producesDeclared(subStmtCtx, WhenStatement.class)) {
+                StatementContextBase<?, ?, ?> copy = subStmtCtx.createCopy(null, targetNodeStmtCtx, TypeOfCopy.ADDED_BY_USES);
                 targetNodeStmtCtx.addEffectiveSubstatement(copy);
             }
-            if (StmtContextUtils.producesDeclared(subStmtCtx,
-                    RefineStatement.class)) {
+            if (StmtContextUtils.producesDeclared(subStmtCtx, RefineStatement.class)) {
                 // :TODO resolve and perform refine statement
             }
-            if (StmtContextUtils.producesDeclared(subStmtCtx,
-                    AugmentStatement.class)) {
+            if (StmtContextUtils.producesDeclared(subStmtCtx, AugmentStatement.class)) {
                 // :TODO find target node and perform augmentation
             }
             // :TODO resolve other uses substatements
index 70effef3906ca37ae4656323a829ad26a2cbd699..509f462975a472ea637abd52217f358b39c4d7bf 100644 (file)
@@ -90,7 +90,7 @@ public class IncludeStatementImpl extends AbstractDeclaredStatement<String> impl
                 @Override
                 public void prerequisiteFailed(Collection<? extends Prerequisite<?>> failed) throws InferenceException {
                     if (failed.contains(requiresCtxPrerequisite)) {
-                        throw new InferenceException("Included submodule was not found.", stmt
+                        throw new InferenceException("Included submodule was not found: "+stmt.getStatementArgument(), stmt
                                 .getStatementSourceReference());
                     }
                 }
index e2c6b531db1e8eae0f93b09d5327f92f82466c0d..963737a7decdb5f6320b5b228d9b9c4d4e27b251 100644 (file)
@@ -9,32 +9,32 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
 
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ModuleEffectiveStatementImpl;
-
-import org.opendaylight.yangtools.yang.parser.spi.source.ModuleQNameToModuleName;
-import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
-import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToModuleIdentifier;
-import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
-import org.opendaylight.yangtools.yang.parser.spi.source.ModuleIdentifierToModuleQName;
-import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
-import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.RevisionStatement;
-import com.google.common.base.Optional;
 import java.net.URI;
 import java.util.Date;
+
 import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.NamespaceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RevisionStatement;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl;
 import org.opendaylight.yangtools.yang.parser.spi.ModuleNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.NamespaceToModule;
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
-import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
+import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToModuleIdentifier;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModuleIdentifierToModuleQName;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModuleQNameToModuleName;
+import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ModuleEffectiveStatementImpl;
+
+import com.google.common.base.Optional;
 
 public class ModuleStatementSupport extends
         AbstractStatementSupport<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> {
index 02e94621919299b71a9cbfec5d9330c854fa086c..16dc0071c15b21bfeef6fb12cbd999e3268cab55 100644 (file)
@@ -26,7 +26,7 @@ public class PrefixStatementImpl extends AbstractDeclaredStatement<String> imple
 
         @Override
         public String parseArgumentValue(StmtContext<?, ?,?> ctx, String value) {
-            return (value);
+            return value;
         }
 
         @Override
index 7349082ec503e8610f5e2bb226838306bba575c2..19f77ecd0ebac6580b54654a60fe6d3188a1ea8d 100644 (file)
@@ -7,40 +7,38 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
-import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.findFirstDeclaredSubstatement;
+import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
 
-import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleName;
-
-import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
-import org.opendaylight.yangtools.yang.parser.spi.SubmoduleNamespace;
-import com.google.common.base.Optional;
 import java.net.URI;
 import java.util.Date;
+
 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.BelongsToStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.RevisionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionStatement;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl;
+import org.opendaylight.yangtools.yang.parser.spi.SubmoduleNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
-import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
+import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleName;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
-import org.opendaylight.yangtools.yang.model.api.stmt.BelongsToStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.SubmoduleEffectiveStatementImpl;
 
-public class SubmoduleStatementImpl extends
-        AbstractRootStatement<SubmoduleStatement> implements SubmoduleStatement {
+import com.google.common.base.Optional;
 
-    protected SubmoduleStatementImpl(
-            StmtContext<String, SubmoduleStatement, ?> context) {
+public class SubmoduleStatementImpl extends AbstractRootStatement<SubmoduleStatement> implements SubmoduleStatement {
+
+    protected SubmoduleStatementImpl(StmtContext<String, SubmoduleStatement, ?> context) {
         super(context);
     }
 
-    public static class Definition
-            extends
+    public static class Definition extends
             AbstractStatementSupport<String, SubmoduleStatement, EffectiveStatement<String, SubmoduleStatement>> {
 
         public Definition() {
@@ -53,15 +51,14 @@ public class SubmoduleStatementImpl extends
         }
 
         @Override
-        public SubmoduleStatement createDeclared(
-                StmtContext<String, SubmoduleStatement, ?> ctx) {
+        public SubmoduleStatement createDeclared(StmtContext<String, SubmoduleStatement, ?> ctx) {
             return new SubmoduleStatementImpl(ctx);
         }
 
         @Override
         public EffectiveStatement<String, SubmoduleStatement> createEffective(
                 StmtContext<String, SubmoduleStatement, EffectiveStatement<String, SubmoduleStatement>> ctx) {
-            throw new UnsupportedOperationException();
+            return new SubmoduleEffectiveStatementImpl(ctx);
         }
 
         @Override
@@ -69,33 +66,27 @@ public class SubmoduleStatementImpl extends
                 Mutable<String, SubmoduleStatement, EffectiveStatement<String, SubmoduleStatement>> stmt)
                 throws SourceException {
 
-            Optional<Date> revisionDate = Optional
-                    .fromNullable(firstAttributeOf(
-                            stmt.declaredSubstatements(),
-                            RevisionStatement.class));
+            Optional<Date> revisionDate = Optional.fromNullable(firstAttributeOf(stmt.declaredSubstatements(),
+                    RevisionStatement.class));
 
-            ModuleIdentifier submoduleIdentifier = new ModuleIdentifierImpl(
-                    stmt.getStatementArgument(), Optional.<URI> absent(),
-                    revisionDate);
+            ModuleIdentifier submoduleIdentifier = new ModuleIdentifierImpl(stmt.getStatementArgument(),
+                    Optional.<URI> absent(), revisionDate);
 
             stmt.addContext(SubmoduleNamespace.class, submoduleIdentifier, stmt);
 
-            String belongsToModuleName = firstAttributeOf(
-                    stmt.declaredSubstatements(), BelongsToStatement.class);
-            StmtContext<?, ?, ?> prefixSubStmtCtx = findFirstDeclaredSubstatement(
-                    stmt, 0, BelongsToStatement.class, PrefixStatement.class);
+            String belongsToModuleName = firstAttributeOf(stmt.declaredSubstatements(), BelongsToStatement.class);
+            StmtContext<?, ?, ?> prefixSubStmtCtx = findFirstDeclaredSubstatement(stmt, 0, BelongsToStatement.class,
+                    PrefixStatement.class);
 
-            if(prefixSubStmtCtx == null) {
+            if (prefixSubStmtCtx == null) {
                 throw new IllegalArgumentException("Prefix of belongsTo statement is missing in submodule ["
                         + stmt.getStatementArgument() + "].");
             }
 
             String prefix = (String) prefixSubStmtCtx.getStatementArgument();
 
-            stmt.addToNs(BelongsToPrefixToModuleName.class, prefix,
-                    belongsToModuleName);
+            stmt.addToNs(BelongsToPrefixToModuleName.class, prefix, belongsToModuleName);
         }
-
     }
 
     @Override
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UnknownStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UnknownStatementImpl.java
new file mode 100644 (file)
index 0000000..1dbb030
--- /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.yang.parser.stmt.rfc6020;
+
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
+import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
+import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+
+import javax.annotation.Nullable;
+
+public class UnknownStatementImpl extends AbstractDeclaredStatement<String> implements UnknownStatement<String> {
+
+    protected UnknownStatementImpl(StmtContext<String, ?, ?> context) {
+        super(context);
+    }
+
+    public static class Definition extends AbstractStatementSupport<String, UnknownStatement<String>, EffectiveStatement<String, UnknownStatement<String>>> {
+
+
+        public Definition(StatementDefinition publicDefinition) {
+            super(publicDefinition);
+        }
+
+        @Override
+        public String parseArgumentValue(StmtContext<?, ?, ?> ctx, String value) throws SourceException {
+            return value;
+        }
+
+        @Override
+        public UnknownStatement createDeclared(StmtContext<String, UnknownStatement<String>, ?> ctx) {
+            return new UnknownStatementImpl(ctx);
+        }
+
+        @Override
+        public EffectiveStatement<String, UnknownStatement<String>> createEffective(StmtContext<String, UnknownStatement<String>, EffectiveStatement<String, UnknownStatement<String>>> ctx) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    @Nullable
+    @Override
+    public String getArgument() {
+        return rawArgument();
+    }
+}
index 326e92a8073dc7215ff8e58fb5a192a95765ac5c..102ad007ff87b58aed7776614bef055331327802 100644 (file)
@@ -10,15 +10,10 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 import static org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase.FULL_DECLARATION;
 
 import java.util.Collection;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
-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.model.api.meta.StatementSource;
 import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.IfFeatureStatement;
@@ -38,6 +33,8 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.UsesEffectiveStatementImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 public class UsesStatementImpl extends AbstractDeclaredStatement<QName> implements UsesStatement {
@@ -91,7 +88,8 @@ public class UsesStatementImpl extends AbstractDeclaredStatement<QName> implemen
                 @Override
                 public void prerequisiteFailed(Collection<? extends Prerequisite<?>> failed) throws InferenceException {
                     if (failed.contains(sourceGroupingPre)) {
-                        throw new InferenceException("Grouping " + groupingName + " was not resovled.", usesNode.getStatementSourceReference());
+                        throw new InferenceException("Grouping " + groupingName + " was not resolved.", usesNode
+                                .getStatementSourceReference());
                     }
                     throw new InferenceException("Unknown error occurred.", usesNode.getStatementSourceReference());
                 }
@@ -150,35 +148,4 @@ public class UsesStatementImpl extends AbstractDeclaredStatement<QName> implemen
     public Collection<? extends RefineStatement> getRefines() {
         return allDeclared(RefineStatement.class);
     }
-
-    @Override
-    public QName argument() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String rawArgument() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Collection<? extends DeclaredStatement<?>> declaredSubstatements() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public StatementDefinition statementDefinition() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public StatementSource getStatementSource() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
 }
index 48131623a15d624ca8715877ee1b1f244ac5eafc..d55f99dedadace890ab11d320d9a7d16b428fc5d 100644 (file)
@@ -9,6 +9,8 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
 
+import java.util.Collection;
+
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
@@ -17,16 +19,20 @@ import java.util.Date;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-
 import javax.annotation.Nullable;
 import javax.xml.xpath.XPath;
 import javax.xml.xpath.XPathExpressionException;
 import javax.xml.xpath.XPathFactory;
-
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Splitter;
+import org.opendaylight.yangtools.yang.model.api.Deviation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.antlr.v4.runtime.tree.TerminalNode;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.YangConstants;
 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.stmt.BelongsToStatement;
@@ -41,29 +47,27 @@ import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToModuleIdenti
 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleIdentifierToModuleQName;
 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
 import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
+import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
 
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Splitter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 public final class Utils {
 
-    private Utils() {
-    }
-
     private static final Logger LOG = LoggerFactory.getLogger(Utils.class);
     private static final CharMatcher DOUBLE_QUOTE_MATCHER = CharMatcher.is('"');
-    private static final CharMatcher SINGLE_QUOTE_MATCHER = CharMatcher.is('\'');
+    private static final CharMatcher SINGLE_QUOTE_MATCHER = CharMatcher
+            .is('\'');
 
     private static final char SEPARATOR_NODENAME = '/';
 
-    private static final String REGEX_PATH_ABS = "/[^/].+";
+    private static final String REGEX_PATH_ABS = "/[^/].*";
+
+    private Utils() {
+    }
 
     public static List<String> splitPathToNodeNames(String path) {
 
-        Splitter keySplitter = Splitter.on(SEPARATOR_NODENAME).omitEmptyStrings().trimResults();
+        Splitter keySplitter = Splitter.on(SEPARATOR_NODENAME)
+                .omitEmptyStrings().trimResults();
         return keySplitter.splitToList(path);
     }
 
@@ -74,7 +78,8 @@ public final class Utils {
         try {
             xPath.compile(path);
         } catch (XPathExpressionException e) {
-            throw new IllegalArgumentException("Argument is not valid XPath string", e);
+            throw new IllegalArgumentException(
+                    "Argument is not valid XPath string", e);
         }
     }
 
@@ -85,7 +90,44 @@ public final class Utils {
         return path.matches(REGEX_PATH_ABS);
     }
 
-    public static Iterable<QName> parseXPath(StmtContext<?, ?, ?> ctx, String path) {
+    public static QName trimPrefix(QName identifier) {
+        String prefixedLocalName = identifier.getLocalName();
+        String[] namesParts = prefixedLocalName.split(":");
+
+        if (namesParts.length == 2) {
+            String localName = namesParts[1];
+            return QName.create(identifier.getModule(), localName);
+        }
+
+        return identifier;
+    }
+
+    public static boolean isValidStatementDefinition(PrefixToModule prefixes,
+            QNameToStatementDefinition stmtDef, QName identifier) {
+        if (stmtDef.get(identifier) != null) {
+            return true;
+        } else {
+            String prefixedLocalName = identifier.getLocalName();
+            String[] namesParts = prefixedLocalName.split(":");
+
+            if (namesParts.length == 2) {
+                String prefix = namesParts[0];
+                String localName = namesParts[1];
+                if (prefixes != null
+                        && prefixes.get(prefix) != null
+                        && stmtDef
+                                .get(new QName(
+                                        YangConstants.RFC6020_YIN_NAMESPACE,
+                                        localName)) != null) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public static Iterable<QName> parseXPath(StmtContext<?, ?, ?> ctx,
+            String path) {
 
         validateXPath(path);
 
@@ -104,10 +146,11 @@ public final class Utils {
         return qNames;
     }
 
-    public static String stringFromStringContext(final YangStatementParser.ArgumentContext context) {
+    public static String stringFromStringContext(
+            final YangStatementParser.ArgumentContext context) {
         StringBuilder sb = new StringBuilder();
         List<TerminalNode> strings = context.STRING();
-        if (strings.size() == 0) {
+        if (strings.isEmpty()) {
             strings = Arrays.asList(context.IDENTIFIER());
         }
         for (TerminalNode stringNode : strings) {
@@ -129,7 +172,7 @@ public final class Utils {
 
     public static QName qNameFromArgument(StmtContext<?, ?, ?> ctx, String value) {
 
-        String prefix = null;
+        String prefix;
         QNameModule qNameModule = null;
         try {
             qNameModule = QNameModule.create(new URI(""), new Date(0));
@@ -143,27 +186,38 @@ public final class Utils {
         case 1:
             localName = namesParts[0];
 
-            if (StmtContextUtils.producesDeclared(ctx.getRoot(), ModuleStatement.class)) {
-                prefix = firstAttributeOf(ctx.getRoot().declaredSubstatements(), PrefixStatement.class);
-                qNameModule = ctx.getFromNamespace(PrefixToModule.class, prefix);
-
-            } else if (StmtContextUtils.producesDeclared(ctx.getRoot(), SubmoduleStatement.class)) {
-                String belongsToModuleName = firstAttributeOf(ctx.getRoot().declaredSubstatements(),
-                        BelongsToStatement.class);
-                qNameModule = ctx.getFromNamespace(ModuleNameToModuleQName.class, belongsToModuleName);
+            if (StmtContextUtils.producesDeclared(ctx.getRoot(),
+                    ModuleStatement.class)) {
+                prefix = firstAttributeOf(
+                        ctx.getRoot().declaredSubstatements(),
+                        PrefixStatement.class);
+                qNameModule = ctx
+                        .getFromNamespace(PrefixToModule.class, prefix);
+
+            } else if (StmtContextUtils.producesDeclared(ctx.getRoot(),
+                    SubmoduleStatement.class)) {
+                String belongsToModuleName = firstAttributeOf(ctx.getRoot()
+                        .declaredSubstatements(), BelongsToStatement.class);
+                qNameModule = ctx.getFromNamespace(
+                        ModuleNameToModuleQName.class, belongsToModuleName);
             }
             break;
         case 2:
             prefix = namesParts[0];
             localName = namesParts[1];
 
-            ModuleIdentifier impModIdentifier = ctx.getRoot().getFromNamespace(ImpPrefixToModuleIdentifier.class,
-                    prefix);
-            qNameModule = ctx.getFromNamespace(ModuleIdentifierToModuleQName.class, impModIdentifier);
-
-            if (qNameModule == null && StmtContextUtils.producesDeclared(ctx.getRoot(), SubmoduleStatement.class)) {
-                String moduleName = ctx.getRoot().getFromNamespace(BelongsToPrefixToModuleName.class, prefix);
-                qNameModule = ctx.getFromNamespace(ModuleNameToModuleQName.class, moduleName);
+            ModuleIdentifier impModIdentifier = ctx.getRoot().getFromNamespace(
+                    ImpPrefixToModuleIdentifier.class, prefix);
+            qNameModule = ctx.getFromNamespace(
+                    ModuleIdentifierToModuleQName.class, impModIdentifier);
+
+            if (qNameModule == null
+                    && StmtContextUtils.producesDeclared(ctx.getRoot(),
+                            SubmoduleStatement.class)) {
+                String moduleName = ctx.getRoot().getFromNamespace(
+                        BelongsToPrefixToModuleName.class, prefix);
+                qNameModule = ctx.getFromNamespace(
+                        ModuleNameToModuleQName.class, moduleName);
             }
 
             break;
@@ -175,45 +229,63 @@ public final class Utils {
     }
 
     @Nullable
-    public static StatementContextBase<?, ?, ?> findCtxOfNodeInRoot(StatementContextBase<?, ?, ?> rootStmtCtx,
-            final SchemaNodeIdentifier node) {
+    public static StatementContextBase<?, ?, ?> findCtxOfNodeInSubstatements(
+            StatementContextBase<?, ?, ?> rootStmtCtx,
+            final Iterable<QName> path) {
 
         StatementContextBase<?, ?, ?> parent = rootStmtCtx;
-        final Iterator<QName> pathIter = node.getPathFromRoot().iterator();
-
-        QName targetNode = pathIter.next();
 
+        Iterator<QName> pathIter = path.iterator();
         while (pathIter.hasNext()) {
+            QName nextPathQName = pathIter.next();
+            StatementContextBase<?, ?, ?> foundSubstatement = getSubstatementByQName(
+                    parent, nextPathQName);
 
-            for (StatementContextBase<?, ?, ?> child : parent.declaredSubstatements()) {
-
-                if (targetNode.equals(child.getStatementArgument())) {
-                    parent = child;
-                    targetNode = pathIter.next();
-                }
-            }
-
-            if (parent.equals(rootStmtCtx)) {
-
+            if (foundSubstatement == null) {
                 return null;
             }
+            if (!pathIter.hasNext()) {
+                return foundSubstatement;
+            }
+
+            parent = foundSubstatement;
         }
 
-        StatementContextBase<?, ?, ?> targetCtx = null;
+        return null;
+    }
+
+    public static StatementContextBase<?, ?, ?> getSubstatementByQName(
+            StatementContextBase<?, ?, ?> parent, QName nextPathQName) {
+
+        Collection<StatementContextBase<?, ?, ?>> declaredSubstatement = parent
+                .declaredSubstatements();
+        Collection<StatementContextBase<?, ?, ?>> effectiveSubstatement = parent
+                .effectiveSubstatements();
 
-        for (StatementContextBase<?, ?, ?> child : parent.declaredSubstatements()) {
+        Collection<StatementContextBase<?, ?, ?>> allSubstatements = new LinkedList<>();
+        allSubstatements.addAll(declaredSubstatement);
+        allSubstatements.addAll(effectiveSubstatement);
 
-            if (targetNode.equals(child.getStatementArgument())) {
-                targetCtx = child;
+        for (StatementContextBase<?, ?, ?> substatement : allSubstatements) {
+            if (nextPathQName.equals(substatement.getStatementArgument())) {
+                return substatement;
             }
         }
 
-        return targetCtx;
+        return null;
+    }
+
+    @Nullable
+    public static StatementContextBase<?, ?, ?> findCtxOfNodeInRoot(
+            StatementContextBase<?, ?, ?> rootStmtCtx,
+            final SchemaNodeIdentifier node) {
+        return findCtxOfNodeInSubstatements(rootStmtCtx, node.getPathFromRoot());
     }
 
     public static SchemaPath getSchemaPath(StmtContext<?, ?, ?> ctx) {
 
-        Iterator<Object> argumentsIterator = ctx.getArgumentsFromRoot().iterator();
+        Iterator<Object> argumentsIterator = ctx.getArgumentsFromRoot()
+                .iterator();
         argumentsIterator.next(); // skip root argument
 
         List<QName> qNamesFromRoot = new LinkedList<>();
@@ -230,4 +302,19 @@ public final class Utils {
 
         return SchemaPath.create(qNamesFromRoot, true);
     }
+
+    public static Deviation.Deviate parseDeviateFromString(final String deviate) {
+        if ("not-supported".equals(deviate)) {
+            return Deviation.Deviate.NOT_SUPPORTED;
+        } else if ("add".equals(deviate)) {
+            return Deviation.Deviate.ADD;
+        } else if ("replace".equals(deviate)) {
+            return Deviation.Deviate.REPLACE;
+        } else if ("delete".equals(deviate)) {
+            return Deviation.Deviate.DELETE;
+        } else {
+            throw new IllegalArgumentException(
+                    "String %s is not valid deviate argument");
+        }
+    }
 }
index 34fc0fccfd95ad8cd8a679dd3c21ac935280f717..933cf31f40652664160e89331baf2ef3e74350fa 100644 (file)
@@ -11,39 +11,36 @@ import static org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour
 import static org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.sourceLocal;
 import static org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.treeScoped;
 
-import org.opendaylight.yangtools.yang.parser.spi.source.ModuleQNameToModuleName;
+import java.util.Map;
 
-import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
+import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.GroupingNamespace;
-import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleName;
-import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
-import org.opendaylight.yangtools.yang.parser.spi.SubmoduleNamespace;
-import org.opendaylight.yangtools.yang.parser.spi.source.ModuleIdentifierToModuleQName;
-import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToModuleIdentifier;
-import com.google.common.collect.ImmutableMap;
-import java.util.Map;
 import org.opendaylight.yangtools.yang.parser.spi.ModuleNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.NamespaceToModule;
+import org.opendaylight.yangtools.yang.parser.spi.SubmoduleNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportBundle;
+import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleName;
+import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToModuleIdentifier;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModuleIdentifierToModuleQName;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModuleQNameToModuleName;
+import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
+import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
 
+import com.google.common.collect.ImmutableMap;
+
 public final class YangInferencePipeline {
 
     public static final StatementSupportBundle LINKAGE_BUNDLE = StatementSupportBundle.builder()
-            .addSupport(new ModuleStatementSupport())
-            .addSupport(new SubmoduleStatementImpl.Definition())
-            .addSupport(new NamespaceStatementImpl.Definition())
-            .addSupport(new ImportStatementDefinition())
-            .addSupport(new IncludeStatementImpl.Definition())
-            .addSupport(new PrefixStatementImpl.Definition())
+            .addSupport(new ModuleStatementSupport()).addSupport(new SubmoduleStatementImpl.Definition())
+            .addSupport(new NamespaceStatementImpl.Definition()).addSupport(new ImportStatementDefinition())
+            .addSupport(new IncludeStatementImpl.Definition()).addSupport(new PrefixStatementImpl.Definition())
             .addSupport(new YangVersionStatementImpl.Definition())
-            .addSupport(new DescriptionStatementImpl.Definition())
-            .addSupport(new RevisionStatementImpl.Definition())
-            .addSupport(new RevisionDateStatementImpl.Definition())
-            .addSupport(new ReferenceStatementImpl.Definition())
-            .addSupport(new ContactStatementImpl.Definition())
-            .addSupport(new OrganizationStatementImpl.Definition())
+            .addSupport(new DescriptionStatementImpl.Definition()).addSupport(new RevisionStatementImpl.Definition())
+            .addSupport(new RevisionDateStatementImpl.Definition()).addSupport(new ReferenceStatementImpl.Definition())
+            .addSupport(new ContactStatementImpl.Definition()).addSupport(new OrganizationStatementImpl.Definition())
             .addSupport(new BelongsToStatementImpl.Definition())
             .addSupport(global(ModuleNamespace.class))
             .addSupport(global(SubmoduleNamespace.class))
@@ -56,21 +53,14 @@ public final class YangInferencePipeline {
             .addSupport(sourceLocal(IncludedModuleContext.class))
             .addSupport(sourceLocal(ImpPrefixToModuleIdentifier.class))
             .addSupport(sourceLocal(BelongsToPrefixToModuleName.class))
-            //.addSupport(global(ImpPrefixToModuleIdentifier.class))
-                    .build();
+            .addSupport(sourceLocal(QNameToStatementDefinition.class)).build();
 
-    private static final StatementSupportBundle STMT_DEF_BUNDLE = StatementSupportBundle.
-            derivedFrom(LINKAGE_BUNDLE)
-            .addSupport(new YinElementStatementImpl.Definition())
-            .addSupport(new ArgumentStatementImpl.Definition())
-            .addSupport(new ExtensionStatementImpl.Definition())
-            //TODO: implement extension support in SourceSpecificContext
-            // in order to prepare statements for full declaration phase,
-            // when those ones are read.
-            .build();
+    private static final StatementSupportBundle STMT_DEF_BUNDLE = StatementSupportBundle.derivedFrom(LINKAGE_BUNDLE)
+            .addSupport(new YinElementStatementImpl.Definition()).addSupport(new ArgumentStatementImpl.Definition())
+            .addSupport(new ExtensionStatementImpl.Definition()).addSupport(global(ExtensionNamespace.class)).build();
 
-    private static final StatementSupportBundle FULL_DECL_BUNDLE = StatementSupportBundle.
-            derivedFrom(STMT_DEF_BUNDLE)
+    private static final StatementSupportBundle FULL_DECL_BUNDLE = StatementSupportBundle
+            .derivedFrom(STMT_DEF_BUNDLE)
             .addSupport(new ContainerStatementImpl.Definition())
             .addSupport(new LeafStatementImpl.Definition())
             .addSupport(new TypeStatementImpl.Definition())
@@ -87,62 +77,48 @@ public final class YangInferencePipeline {
             .addSupport(new IfFeatureStatementImpl.Definition())
             .addSupport(new UsesStatementImpl.Definition())
             .addSupport(new GroupingStatementImpl.Definition())
-            .addSupport(treeScoped(GroupingNamespace.class)) //treeScoped
-            .addSupport(new StatusStatementImpl.Definition())
-            .addSupport(new ErrorMessageStatementImpl.Definition())
-            .addSupport(new ErrorAppTagStatementImpl.Definition())
-            .addSupport(new LeafListStatementImpl.Definition())
-            .addSupport(new ListStatementImpl.Definition())
-            .addSupport(new PresenceStatementImpl.Definition())
-            .addSupport(new KeyStatementImpl.Definition())
-            .addSupport(new MaxElementsStatementImpl.Definition())
-            .addSupport(new MinElementsStatementImpl.Definition())
-            .addSupport(new OrderedByStatementImpl.Definition())
-            .addSupport(new WhenStatementImpl.Definition())
-            .addSupport(new AugmentStatementImpl.Definition())
-            .addSupport(new RefineStatementImpl.Definition())
-            .addSupport(new IdentityStatementImpl.Definition())
-            .addSupport(new BaseStatementImpl.Definition())
-            .addSupport(new FractionDigitsStatementImpl.Definition())
-            .addSupport(new EnumStatementImpl.Definition())
-            .addSupport(new FeatureStatementImpl.Definition())
-            .addSupport(new RpcStatementImpl.Definition())
-            .addSupport(new InputStatementImpl.Definition())
-            .addSupport(new OutputStatementImpl.Definition())
-            .addSupport(new LengthStatementImpl.Definition())
-            .addSupport(new NotificationStatementImpl.Definition())
-            .addSupport(new PatternStatementImpl.Definition())
-            .addSupport(new PositionStatementImpl.Definition())
-            .addSupport(new RangeStatementImpl.Definition())
-            .addSupport(new ValueStatementImpl.Definition())
-            .addSupport(new UnitsStatementImpl.Definition())
+            .addSupport(treeScoped(GroupingNamespace.class))
+            // treeScoped
+            .addSupport(new StatusStatementImpl.Definition()).addSupport(new ErrorMessageStatementImpl.Definition())
+            .addSupport(new ErrorAppTagStatementImpl.Definition()).addSupport(new LeafListStatementImpl.Definition())
+            .addSupport(new ListStatementImpl.Definition()).addSupport(new PresenceStatementImpl.Definition())
+            .addSupport(new KeyStatementImpl.Definition()).addSupport(new MaxElementsStatementImpl.Definition())
+            .addSupport(new MinElementsStatementImpl.Definition()).addSupport(new OrderedByStatementImpl.Definition())
+            .addSupport(new WhenStatementImpl.Definition()).addSupport(new AugmentStatementImpl.Definition())
+            .addSupport(new RefineStatementImpl.Definition()).addSupport(new IdentityStatementImpl.Definition())
+            .addSupport(new BaseStatementImpl.Definition()).addSupport(new FractionDigitsStatementImpl.Definition())
+            .addSupport(new EnumStatementImpl.Definition()).addSupport(new FeatureStatementImpl.Definition())
+            .addSupport(new RpcStatementImpl.Definition()).addSupport(new InputStatementImpl.Definition())
+            .addSupport(new OutputStatementImpl.Definition()).addSupport(new LengthStatementImpl.Definition())
+            .addSupport(new NotificationStatementImpl.Definition()).addSupport(new PatternStatementImpl.Definition())
+            .addSupport(new PositionStatementImpl.Definition()).addSupport(new RangeStatementImpl.Definition())
+            .addSupport(new ValueStatementImpl.Definition()).addSupport(new UnitsStatementImpl.Definition())
             .addSupport(new RequireInstanceStatementImpl.Definition())
-            //TODO: add mapping to Rfc6020Mapping class and uncomment following. Please test it.
-//            .addSupport(new EnumSpecificationImpl.Definition())
-//            .addSupport(new Decimal64SpecificationImpl.Definition())
-//            .addSupport(new IdentityRefSpecificationImpl.Definition())
-//            .addSupport(new InstanceIdentifierSpecificationImpl.Definition())
-//            .addSupport(new LeafrefSpecificationImpl.Definition())
-//            .addSupport(new NumericalRestrictionsImpl.Definition())
-//            .addSupport(new StringRestrictionsImpl.Definition())
-//            .addSupport(new UnionSpecificationImpl.Definition())
-//            .addSupport(new BitStatementImpl.Definition())
+            // TODO: add mapping to Rfc6020Mapping class and uncomment
+            // following. Please test it.
+            // .addSupport(new EnumSpecificationImpl.Definition())
+            // .addSupport(new Decimal64SpecificationImpl.Definition())
+            // .addSupport(new IdentityRefSpecificationImpl.Definition())
+            // .addSupport(new InstanceIdentifierSpecificationImpl.Definition())
+            // .addSupport(new LeafrefSpecificationImpl.Definition())
+            // .addSupport(new NumericalRestrictionsImpl.Definition())
+            // .addSupport(new StringRestrictionsImpl.Definition())
+            // .addSupport(new UnionSpecificationImpl.Definition())
+            // .addSupport(new BitStatementImpl.Definition())
             .build();
 
     public static final Map<ModelProcessingPhase, StatementSupportBundle> RFC6020_BUNDLES = ImmutableMap
             .<ModelProcessingPhase, StatementSupportBundle> builder()
             .put(ModelProcessingPhase.SOURCE_LINKAGE, LINKAGE_BUNDLE)
-            .put(ModelProcessingPhase.STATEMENT_DEFINITION,STMT_DEF_BUNDLE)
-            .put(ModelProcessingPhase.FULL_DECLARATION,FULL_DECL_BUNDLE)
-            .put(ModelProcessingPhase.EFFECTIVE_MODEL,FULL_DECL_BUNDLE)
-            .build();
+            .put(ModelProcessingPhase.STATEMENT_DEFINITION, STMT_DEF_BUNDLE)
+            .put(ModelProcessingPhase.FULL_DECLARATION, FULL_DECL_BUNDLE)
+            .put(ModelProcessingPhase.EFFECTIVE_MODEL, FULL_DECL_BUNDLE).build();
 
     public static final CrossSourceStatementReactor RFC6020_REACTOR = CrossSourceStatementReactor.builder()
             .setBundle(ModelProcessingPhase.SOURCE_LINKAGE, LINKAGE_BUNDLE)
-            .setBundle(ModelProcessingPhase.STATEMENT_DEFINITION,STMT_DEF_BUNDLE)
-            .setBundle(ModelProcessingPhase.FULL_DECLARATION,FULL_DECL_BUNDLE)
-            .setBundle(ModelProcessingPhase.EFFECTIVE_MODEL,FULL_DECL_BUNDLE)
-            .build();
+            .setBundle(ModelProcessingPhase.STATEMENT_DEFINITION, STMT_DEF_BUNDLE)
+            .setBundle(ModelProcessingPhase.FULL_DECLARATION, FULL_DECL_BUNDLE)
+            .setBundle(ModelProcessingPhase.EFFECTIVE_MODEL, FULL_DECL_BUNDLE).build();
 
     private YangInferencePipeline() {
         throw new UnsupportedOperationException("Utility class");
index 210a837f81576413d58fc05b9bdd7ff3b3762f6c..2b6c97f8a8c8ed8b40e36ea40b9f464a3c201b30 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * 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.stmt.rfc6020;
 
 import org.antlr.v4.runtime.ANTLRInputStream;
index f0b521e21bc00e3df10866f5608572b60e821fbc..9bd91b6619ad892749081772ef61149a3f8d4b4f 100644 (file)
@@ -13,9 +13,12 @@ import com.google.common.collect.ImmutableMap;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+import java.util.Map;
 import java.util.Set;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
@@ -40,38 +43,38 @@ public abstract class AbstractEffectiveDocumentedDataNodeContainer<A, D extends
 
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        HashMap<QName, DataSchemaNode> childNodes = new HashMap<QName, DataSchemaNode>();
-        HashSet<GroupingDefinition> groupings = new HashSet<GroupingDefinition>();
-        HashSet<UsesNode> uses = new HashSet<UsesNode>();
-        HashSet<TypeDefinition<?>> typeDefinitions = new HashSet<TypeDefinition<?>>();
-        HashSet<DataSchemaNode> publicChildNodes = new HashSet<DataSchemaNode>();
+        Map<QName, DataSchemaNode> mutableChildNodes = new HashMap<QName, DataSchemaNode>();
+        Set<GroupingDefinition> mutableGroupings = new HashSet<GroupingDefinition>();
+        Set<UsesNode> mutableUses = new HashSet<UsesNode>();
+        Set<TypeDefinition<?>> mutableTypeDefinitions = new HashSet<TypeDefinition<?>>();
+        Set<DataSchemaNode> mutablePublicChildNodes = new HashSet<DataSchemaNode>();
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof DataSchemaNode) {
                 DataSchemaNode dataSchemaNode = (DataSchemaNode) effectiveStatement;
 
-                childNodes.put(dataSchemaNode.getQName(), dataSchemaNode);
-                publicChildNodes.add(dataSchemaNode);
+                mutableChildNodes.put(dataSchemaNode.getQName(), dataSchemaNode);
+                mutablePublicChildNodes.add(dataSchemaNode);
             }
             if (effectiveStatement instanceof UsesNode) {
                 UsesNode usesNode = (UsesNode) effectiveStatement;
-                uses.add(usesNode);
+                mutableUses.add(usesNode);
             }
             if (effectiveStatement instanceof TypeDefinition) {
                 TypeDefinition<?> typeDef = (TypeDefinition<?>) effectiveStatement;
-                typeDefinitions.add(typeDef);
+                mutableTypeDefinitions.add(typeDef);
             }
             if (effectiveStatement instanceof GroupingDefinition) {
                 GroupingDefinition grp = (GroupingDefinition) effectiveStatement;
-                groupings.add(grp);
+                mutableGroupings.add(grp);
             }
         }
 
-        this.childNodes = ImmutableMap.copyOf(childNodes);
-        this.groupings = ImmutableSet.copyOf(groupings);
-        this.publicChildNodes = ImmutableSet.copyOf(publicChildNodes);
-        this.typeDefinitions = ImmutableSet.copyOf(typeDefinitions);
-        this.uses = ImmutableSet.copyOf(uses);
+        this.childNodes = ImmutableMap.copyOf(mutableChildNodes);
+        this.groupings = ImmutableSet.copyOf(mutableGroupings);
+        this.publicChildNodes = ImmutableSet.copyOf(mutablePublicChildNodes);
+        this.typeDefinitions = ImmutableSet.copyOf(mutableTypeDefinitions);
+        this.uses = ImmutableSet.copyOf(mutableUses);
     }
 
     @Override
index 23ecee547575ec4853e1d7ee725c5f45e2e73cb4..763b14216238f55b21f27703df9ebae18e9c2cad 100644 (file)
@@ -26,14 +26,16 @@ public abstract class AbstractEffectiveDocumentedNode<A, D extends DeclaredState
         DescriptionEffectiveStatementImpl descStmt = firstEffective(DescriptionEffectiveStatementImpl.class);
         if (descStmt != null) {
             description = descStmt.argument();
-        } else
+        } else {
             description = "";
+        }
 
         ReferenceEffectiveStatementImpl refStmt = firstEffective(ReferenceEffectiveStatementImpl.class);
         if (refStmt != null) {
             reference = refStmt.argument();
-        } else
+        } else {
             reference = "";
+        }
 
         // :TODO
         status = null;
index e84af21131271e4eab3ed1a32204323320f29748..a4a94111a430e92c5985a70f9e54a325e432a0ec 100644 (file)
@@ -19,6 +19,7 @@ import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.NavigableSet;
 import java.util.Set;
 import java.util.TreeSet;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -40,9 +41,9 @@ import org.opendaylight.yangtools.yang.model.api.UsesNode;
 
 public abstract class AbstractEffectiveSchemaContext implements SchemaContext {
 
-    protected static final Supplier<TreeSet<Module>> MODULE_SET_SUPPLIER = new Supplier<TreeSet<Module>>() {
+    protected static final Supplier<NavigableSet<Module>> MODULE_SET_SUPPLIER = new Supplier<NavigableSet<Module>>() {
         @Override
-        public TreeSet<Module> get() {
+        public NavigableSet<Module> get() {
             return new TreeSet<>(REVISION_COMPARATOR);
         }
     };
index ff417e0e1d8e6c1c47b7721a0cc524c148a66f52..07e503e76b4a35888d5a26d783e515114eb64ea4 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
+
 import java.util.Collection;
 import java.util.LinkedList;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
@@ -44,21 +46,40 @@ public class AnyXmlEffectiveStatementImpl extends
         this.path = Utils.getSchemaPath(ctx);
 
         initSubstatementCollections();
+        initCopyType(ctx);
+    }
+
+    private void initCopyType(
+            StmtContext<QName, AnyxmlStatement, EffectiveStatement<QName, AnyxmlStatement>> ctx) {
+
+        TypeOfCopy typeOfCopy = ctx.getTypeOfCopy();
+        switch (typeOfCopy) {
+        case ADDED_BY_AUGMENTATION:
+            augmenting = true;
+            original = (AnyXmlSchemaNode) ctx.getOriginalCtx().buildEffective();
+            break;
+        case ADDED_BY_USES:
+            addedByUses = true;
+            original = (AnyXmlSchemaNode) ctx.getOriginalCtx().buildEffective();
+            break;
+        default:
+            break;
+        }
     }
 
     private void initSubstatementCollections() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof UnknownSchemaNode) {
                 UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+                unknownNodesInit.add(unknownNode);
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
     }
 
     @Override
index 0d3f3741f768db64de227e2e8b2dc5b924086a69..39e51d1f9793ed834da551205d402d3b6d0bd66c 100644 (file)
@@ -60,16 +60,16 @@ public class AugmentEffectiveStatementImpl
     private void initSubstatementCollections() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof UnknownSchemaNode) {
                 UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+                unknownNodesInit.add(unknownNode);
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
     }
 
     public void setCopyOf(final AugmentationSchema build) {
index e406e610973aa71086d8a89897fcbe111db02a16..50fb528446527c05441950faa092799df4bc583d 100644 (file)
@@ -7,10 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
+
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.LinkedList;
-
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement;
@@ -50,27 +51,46 @@ public class CaseEffectiveStatementImpl extends
         // :TODO init other fields
 
         initSubstatementCollections();
+        initCopyType(ctx);
+    }
+
+    private void initCopyType(
+            StmtContext<QName, CaseStatement, EffectiveStatement<QName, CaseStatement>> ctx) {
+
+        TypeOfCopy typeOfCopy = ctx.getTypeOfCopy();
+        switch (typeOfCopy) {
+        case ADDED_BY_AUGMENTATION:
+            augmenting = true;
+            original = (ChoiceCaseNode) ctx.getOriginalCtx().buildEffective();
+            break;
+        case ADDED_BY_USES:
+            addedByUses = true;
+            original = (ChoiceCaseNode) ctx.getOriginalCtx().buildEffective();
+            break;
+        default:
+            break;
+        }
     }
 
     private void initSubstatementCollections() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
-        HashSet<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
+        Set<AugmentationSchema> augmentationsInit = new HashSet<>();
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof UnknownSchemaNode) {
                 UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+                unknownNodesInit.add(unknownNode);
             }
             if (effectiveStatement instanceof AugmentationSchema) {
                 AugmentationSchema augmentationSchema = (AugmentationSchema) effectiveStatement;
-                augmentations.add(augmentationSchema);
+                augmentationsInit.add(augmentationSchema);
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
-        this.augmentations = ImmutableSet.copyOf(augmentations);
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
+        this.augmentations = ImmutableSet.copyOf(augmentationsInit);
     }
 
     @Override
index 00262b5070e97c8cae5224eb957aa2d76aff6ed7..7c36706d07b3cb0aace0088468f6a7a40f085e51 100644 (file)
@@ -7,10 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
+
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.LinkedList;
-
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceStatement;
@@ -52,34 +53,52 @@ public class ChoiceEffectiveStatementImpl extends AbstractEffectiveDocumentedNod
         //:TODO init other fields
 
         initSubstatementCollections();
-
+        initCopyType(ctx);
+    }
+
+    private void initCopyType(
+            StmtContext<QName, ChoiceStatement, EffectiveStatement<QName, ChoiceStatement>> ctx) {
+
+        TypeOfCopy typeOfCopy = ctx.getTypeOfCopy();
+        switch (typeOfCopy) {
+        case ADDED_BY_AUGMENTATION:
+            augmenting = true;
+            original = (ChoiceSchemaNode) ctx.getOriginalCtx().buildEffective();
+            break;
+        case ADDED_BY_USES:
+            addedByUses = true;
+            original = (ChoiceSchemaNode) ctx.getOriginalCtx().buildEffective();
+            break;
+        default:
+            break;
+        }
     }
 
     private void initSubstatementCollections() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
-        HashSet<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
-        HashSet<ChoiceCaseNode> cases = new HashSet<ChoiceCaseNode>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
+        Set<AugmentationSchema> augmentationsInit = new HashSet<>();
+        Set<ChoiceCaseNode> casesInit = new HashSet<>();
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof UnknownSchemaNode) {
                 UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+                unknownNodesInit.add(unknownNode);
             }
             if (effectiveStatement instanceof AugmentationSchema) {
                 AugmentationSchema augmentationSchema = (AugmentationSchema) effectiveStatement;
-                augmentations.add(augmentationSchema);
+                augmentationsInit.add(augmentationSchema);
             }
             if (effectiveStatement instanceof ChoiceCaseNode) {
                 ChoiceCaseNode choiceCaseNode = (ChoiceCaseNode) effectiveStatement;
-                cases.add(choiceCaseNode);
+                casesInit.add(choiceCaseNode);
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
-        this.augmentations = ImmutableSet.copyOf(augmentations);
-        this.cases = ImmutableSet.copyOf(cases);
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
+        this.augmentations = ImmutableSet.copyOf(augmentationsInit);
+        this.cases = ImmutableSet.copyOf(casesInit);
     }
 
     @Override
index d7a70c4a66d020d82a79d0c09c33221200b010d6..7cb1b79a546473e738bb59014bcc8a61e00f502b 100644 (file)
@@ -7,8 +7,9 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
-import com.google.common.collect.ImmutableSet;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
 
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableList;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
 import java.util.HashSet;
@@ -31,15 +32,16 @@ import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 public class ContainerEffectiveStatementImpl extends
         AbstractEffectiveDocumentedDataNodeContainer<QName, ContainerStatement>
         implements ContainerSchemaNode, DerivableSchemaNode {
+
     private final QName qname;
     private final SchemaPath path;
-    private final boolean presence;
 
-    boolean augmenting;
-    boolean addedByUses;
-    boolean configuration;
-    ContainerSchemaNode original;
-    ConstraintDefinition constraints;
+    private boolean presence;
+    private boolean augmenting;
+    private boolean addedByUses;
+    private boolean configuration;
+    private ContainerSchemaNode original;
+    private ConstraintDefinition constraints;
 
     private ImmutableSet<AugmentationSchema> augmentations;
     private ImmutableList<UnknownSchemaNode> unknownNodes;
@@ -50,32 +52,56 @@ public class ContainerEffectiveStatementImpl extends
 
         qname = ctx.getStatementArgument();
         path = Utils.getSchemaPath(ctx);
-        presence = (firstEffective(PresenceEffectiveStatementImpl.class) == null) ? false
-                : true;
+
+        initCopyType(ctx);
+        initFields();
         // :TODO init other fields
+    }
 
-        initSubstatementCollections();
+    private void initCopyType(
+            StmtContext<QName, ContainerStatement, EffectiveStatement<QName, ContainerStatement>> ctx) {
+
+        TypeOfCopy typeOfCopy = ctx.getTypeOfCopy();
+        switch (typeOfCopy) {
+        case ADDED_BY_AUGMENTATION:
+            augmenting = true;
+            original = (ContainerSchemaNode) ctx.getOriginalCtx().buildEffective();
+            break;
+        case ADDED_BY_USES:
+            addedByUses = true;
+            original = (ContainerSchemaNode) ctx.getOriginalCtx().buildEffective();
+            break;
+        default:
+            break;
+        }
     }
 
-    private void initSubstatementCollections() {
+    private void initFields() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
-        HashSet<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
+        Set<AugmentationSchema> augmentationsInit = new HashSet<>();
 
-        for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
-            if (effectiveStatement instanceof UnknownSchemaNode) {
-                UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+        for (EffectiveStatement<?, ?> effectiveSubstatement : effectiveSubstatements) {
+            if (effectiveSubstatement instanceof UnknownSchemaNode) {
+                UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveSubstatement;
+                unknownNodesInit.add(unknownNode);
+            }
+            if (effectiveSubstatement instanceof AugmentationSchema) {
+                AugmentationSchema augmentationSchema = (AugmentationSchema) effectiveSubstatement;
+                augmentationsInit.add(augmentationSchema);
+            }
+            if (effectiveSubstatement instanceof PresenceEffectiveStatementImpl) {
+                presence = true;
             }
-            if (effectiveStatement instanceof AugmentationSchema) {
-                AugmentationSchema augmentationSchema = (AugmentationSchema) effectiveStatement;
-                augmentations.add(augmentationSchema);
+            if (effectiveSubstatement instanceof ConfigEffectiveStatementImpl) {
+                ConfigEffectiveStatementImpl config = (ConfigEffectiveStatementImpl) effectiveSubstatement;
+                this.configuration = config.argument();
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
-        this.augmentations = ImmutableSet.copyOf(augmentations);
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
+        this.augmentations = ImmutableSet.copyOf(augmentationsInit);
     }
 
     @Override
index 2528b6d901a4ed4c2b467a7742ca0d31e8928326..6365a71552387f0312718cbc70df80b828b512b9 100644 (file)
@@ -7,13 +7,14 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
+import org.opendaylight.yangtools.yang.model.api.Deviation;
 import org.opendaylight.yangtools.yang.model.api.stmt.DeviateStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 
 public class DeviateEffectiveStatementImpl extends
-        EffectiveStatementBase<String, DeviateStatement> {
+        EffectiveStatementBase<Deviation.Deviate, DeviateStatement> {
     public DeviateEffectiveStatementImpl(
-            StmtContext<String, DeviateStatement, ?> ctx) {
+            StmtContext<Deviation.Deviate, DeviateStatement, ?> ctx) {
         super(ctx);
     }
 }
\ No newline at end of file
index c424b9e151814b9a6c5f0b2a3af8c81718d545af..66a19f22ab3504e883ed27da28a451c5b9256e46 100644 (file)
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
+import java.util.LinkedList;
+import java.util.List;
+
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.model.api.Deviation;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.DeviationStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 
-public class DeviationEffectiveStatementImpl extends
-        EffectiveStatementBase<SchemaNodeIdentifier, DeviationStatement> {
+import com.google.common.collect.ImmutableList;
+
+public class DeviationEffectiveStatementImpl extends EffectiveStatementBase<SchemaNodeIdentifier, DeviationStatement>
+        implements Deviation, Immutable {
+
+    private SchemaPath targetPath;
+    private Deviate deviate;
+    private String reference;
+    private ImmutableList<UnknownSchemaNode> unknownSchemaNodes;
 
-    public DeviationEffectiveStatementImpl(
-            StmtContext<SchemaNodeIdentifier, DeviationStatement, ?> ctx) {
+    public DeviationEffectiveStatementImpl(StmtContext<SchemaNodeIdentifier, DeviationStatement, ?> ctx) {
         super(ctx);
 
+        List<UnknownSchemaNode> unknownSchemaNodesInit = new LinkedList<>();
+
+        targetPath = SchemaPath.create(ctx.getStatementArgument().getPathFromRoot(), ctx.getStatementArgument()
+                .isAbsolute());
+
+        for (final EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
+            if (effectiveStatement instanceof DeviateEffectiveStatementImpl) {
+                deviate = ((DeviateEffectiveStatementImpl) effectiveStatement).argument();
+            }
+            if (effectiveStatement instanceof ReferenceEffectiveStatementImpl) {
+                reference = ((ReferenceEffectiveStatementImpl) effectiveStatement).argument();
+            }
+            if (effectiveStatement instanceof UnknownSchemaNode) {
+                unknownSchemaNodesInit.add((UnknownSchemaNode) effectiveStatement);
+            }
+        }
+
+        unknownSchemaNodes = ImmutableList.copyOf(unknownSchemaNodesInit);
+    }
+
+    @Override
+    public SchemaPath getTargetPath() {
+        return targetPath;
+    }
+
+    @Override
+    public Deviate getDeviate() {
+        return deviate;
     }
 
+    @Override
+    public String getReference() {
+        return reference;
+    }
+
+    @Override
+    public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+        return unknownSchemaNodes;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((targetPath == null) ? 0 : targetPath.hashCode());
+        result = prime * result + ((deviate == null) ? 0 : deviate.hashCode());
+        result = prime * result + ((reference == null) ? 0 : reference.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        DeviationEffectiveStatementImpl other = (DeviationEffectiveStatementImpl) obj;
+        if (targetPath == null) {
+            if (other.targetPath != null) {
+                return false;
+            }
+        } else if (!targetPath.equals(other.targetPath)) {
+            return false;
+        }
+        if (deviate == null) {
+            if (other.deviate != null) {
+                return false;
+            }
+        } else if (!deviate.equals(other.deviate)) {
+            return false;
+        }
+        if (reference == null) {
+            if (other.reference != null) {
+                return false;
+            }
+        } else if (!reference.equals(other.reference)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(DeviationEffectiveStatementImpl.class.getSimpleName());
+        sb.append("[");
+        sb.append("targetPath=").append(targetPath);
+        sb.append(", deviate=").append(deviate);
+        sb.append(", reference=").append(reference);
+        sb.append("]");
+        return sb.toString();
+    }
 }
\ No newline at end of file
index cc837626ed4a1159844ebf7de4eaa7391ff06b51..4cedda12fa6c55db907185ad5b05d864776a86d3 100644 (file)
@@ -42,21 +42,21 @@ public class EffectiveSchemaContext extends AbstractEffectiveSchemaContext {
         this.rootEffectiveStatements = ImmutableList
                 .copyOf(rootEffectiveStatements);
 
-        HashSet<Module> modules = new HashSet<Module>();
+        Set<Module> modulesInit = new HashSet<>();
         for (EffectiveStatement<?, ?> rootEffectiveStatement : rootEffectiveStatements) {
             if (rootEffectiveStatement instanceof Module) {
                 Module module = (Module) rootEffectiveStatement;
-                modules.add(module);
+                modulesInit.add(module);
             }
         }
-        this.modules = ImmutableSet.copyOf(modules);
+        this.modules = ImmutableSet.copyOf(modulesInit);
 
         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);
 
-        for (Module m : modules) {
+        for (Module m : modulesInit) {
             nameMap.put(m.getName(), m);
             nsMap.put(m.getNamespace(), m);
         }
index 804be7bd029e5078ad33799a20a0793911852900..fd269a1f163d67f89a47795369571e65b4231bd0 100644 (file)
@@ -51,11 +51,11 @@ abstract public class EffectiveStatementBase<A, D extends DeclaredStatement<A>>
         Collection<StatementContextBase<?, ?, ?>> effectiveSubstatements = ctx
                 .effectiveSubstatements();
 
-        Collection<StatementContextBase<?, ?, ?>> substatements = new LinkedList<StatementContextBase<?, ?, ?>>();
-        substatements.addAll(declaredSubstatements);
-        substatements.addAll(effectiveSubstatements);
+        Collection<StatementContextBase<?, ?, ?>> substatementsInit = new LinkedList<>();
+        substatementsInit.addAll(declaredSubstatements);
+        substatementsInit.addAll(effectiveSubstatements);
 
-        this.substatements = FluentIterable.from(substatements)
+        this.substatements = FluentIterable.from(substatementsInit)
                 .transform(StmtContextUtils.buildEffective()).toList();
     }
 
@@ -127,7 +127,7 @@ abstract public class EffectiveStatementBase<A, D extends DeclaredStatement<A>>
             result = Collection.class.cast(Collections2.filter(substatements,
                     Predicates.instanceOf(type)));
         } catch (NoSuchElementException e) {
-            result = Collections.EMPTY_LIST;
+            result = Collections.emptyList();
         }
         return result;
     }
@@ -152,7 +152,7 @@ abstract public class EffectiveStatementBase<A, D extends DeclaredStatement<A>>
             result = Collection.class.cast(Collections2.filter(substatements,
                     Predicates.instanceOf(type)));
         } catch (NoSuchElementException e) {
-            result = Collections.EMPTY_LIST;
+            result = Collections.emptyList();
         }
         return result;
     }
index cdea92063311b54a3887f85ff1f3598923c6e242..f9f1d8066557af3a21c814b67d07819e0b93f688 100644 (file)
@@ -54,24 +54,25 @@ public class ExtensionEffectiveStatementImpl extends
 
         if (yinElement != null) {
             this.yin = yinElement.argument();
-        } else
-            yin = false;
+        } else {
+            this.yin = false;
+        }
 
     }
 
     private void initSubstatementCollections() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof UnknownSchemaNode) {
                 UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+                unknownNodesInit.add(unknownNode);
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
     }
 
     @Override
index 38c982ff61cdb7034a5f937fb78f5a623ba8c0bc..8ee820a7ba2eafa961d54f59b9fc9997fad14bc0 100644 (file)
@@ -49,16 +49,16 @@ public class IdentityEffectiveStatementImpl extends
     private void initSubstatementCollections() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof UnknownSchemaNode) {
                 UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+                unknownNodesInit.add(unknownNode);
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
     }
 
     @Override
index 7eaae54024826c854d30c7dd1b7a6d01b5530c3a..d322c22a7d82d76efa02a4f29e9faa8469bbd12a 100644 (file)
@@ -7,14 +7,99 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
+import java.util.Date;
+
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ImportStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 
-public class ImportEffectiveStatementImpl extends
-        EffectiveStatementBase<String, ImportStatement> {
+public class ImportEffectiveStatementImpl extends EffectiveStatementBase<String, ImportStatement> implements
+        ModuleImport {
+
+    private String moduleName;
+    private Date revision;
+    private String prefix;
 
-    public ImportEffectiveStatementImpl(
-            StmtContext<String, ImportStatement, ?> ctx) {
+    public ImportEffectiveStatementImpl(StmtContext<String, ImportStatement, ?> ctx) {
         super(ctx);
+
+        moduleName = ctx.getStatementArgument();
+
+        for (final EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
+            if (effectiveStatement instanceof RevisionEffectiveStatementImpl) {
+                revision = ((RevisionEffectiveStatementImpl) effectiveStatement).argument();
+            }
+            if (effectiveStatement instanceof PrefixEffectiveStatementImpl) {
+                prefix = ((PrefixEffectiveStatementImpl) effectiveStatement).argument();
+            }
+        }
+    }
+
+    @Override
+    public String getModuleName() {
+        return moduleName;
+    }
+
+    @Override
+    public Date getRevision() {
+        return revision;
+    }
+
+    @Override
+    public String getPrefix() {
+        return prefix;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((moduleName == null) ? 0 : moduleName.hashCode());
+        result = prime * result + ((revision == null) ? 0 : revision.hashCode());
+        result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        ImportEffectiveStatementImpl other = (ImportEffectiveStatementImpl) obj;
+        if (getModuleName() == null) {
+            if (other.getModuleName() != null) {
+                return false;
+            }
+        } else if (!getModuleName().equals(other.getModuleName())) {
+            return false;
+        }
+        if (getRevision() == null) {
+            if (other.getRevision() != null) {
+                return false;
+            }
+        } else if (!getRevision().equals(other.getRevision())) {
+            return false;
+        }
+        if (getPrefix() == null) {
+            if (other.getPrefix() != null) {
+                return false;
+            }
+        } else if (!getPrefix().equals(other.getPrefix())) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return ImportEffectiveStatementImpl.class.getSimpleName() + "[moduleName=" + moduleName + ", revision="
+                + revision + ", prefix=" + prefix + "]";
     }
 }
index 54e2f10b247a8c95fc7c76db355c98358d692015..03f1daf92892dcc0fc0211a4b8234ed6277cf876 100644 (file)
@@ -7,10 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
+
 import java.util.HashSet;
 import java.util.LinkedList;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
-
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import java.util.List;
@@ -54,27 +55,48 @@ public class InputEffectiveStatementImpl extends
         // :TODO init other fields
 
         initSubstatementCollections();
+        initCopyType(ctx);
+    }
+
+    private void initCopyType(
+            StmtContext<QName, InputStatement, EffectiveStatement<QName, InputStatement>> ctx) {
+
+        TypeOfCopy typeOfCopy = ctx.getTypeOfCopy();
+        switch (typeOfCopy) {
+        case ADDED_BY_AUGMENTATION:
+            augmenting = true;
+            original = (ContainerSchemaNode) ctx.getOriginalCtx()
+                    .buildEffective();
+            break;
+        case ADDED_BY_USES:
+            addedByUses = true;
+            original = (ContainerSchemaNode) ctx.getOriginalCtx()
+                    .buildEffective();
+            break;
+        default:
+            break;
+        }
     }
 
     private void initSubstatementCollections() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
-        HashSet<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
+        Set<AugmentationSchema> augmentationsInit = new HashSet<>();
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof UnknownSchemaNode) {
                 UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+                unknownNodesInit.add(unknownNode);
             }
             if (effectiveStatement instanceof AugmentationSchema) {
                 AugmentationSchema augmentationSchema = (AugmentationSchema) effectiveStatement;
-                augmentations.add(augmentationSchema);
+                augmentationsInit.add(augmentationSchema);
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
-        this.augmentations = ImmutableSet.copyOf(augmentations);
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
+        this.augmentations = ImmutableSet.copyOf(augmentationsInit);
     }
 
     @Override
index 45ecda59e1a1b81932f556c631f359fe7bcc3c29..37980b55757b646d298f8e468f61eb379757d273 100644 (file)
@@ -7,9 +7,10 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
+
 import java.util.Collection;
 import java.util.LinkedList;
-
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
@@ -50,21 +51,40 @@ public class LeafEffectiveStatementImpl extends
         // :TODO init other fields
 
         initSubstatementCollections();
+        initCopyType(ctx);
+    }
+
+    private void initCopyType(
+            StmtContext<QName, LeafStatement, EffectiveStatement<QName, LeafStatement>> ctx) {
+
+        TypeOfCopy typeOfCopy = ctx.getTypeOfCopy();
+        switch (typeOfCopy) {
+        case ADDED_BY_AUGMENTATION:
+            augmenting = true;
+            original = (LeafSchemaNode) ctx.getOriginalCtx().buildEffective();
+            break;
+        case ADDED_BY_USES:
+            addedByUses = true;
+            original = (LeafSchemaNode) ctx.getOriginalCtx().buildEffective();
+            break;
+        default:
+            break;
+        }
     }
 
     private void initSubstatementCollections() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof UnknownSchemaNode) {
                 UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+                unknownNodesInit.add(unknownNode);
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
     }
 
     @Override
index 768a99e084d42920f9e11d598fee936fea499b30..afb24b4d3306fcf27b7ff453e187297b6feb34fd 100644 (file)
@@ -7,9 +7,10 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
+
 import java.util.Collection;
 import java.util.LinkedList;
-
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
@@ -25,7 +26,9 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 
-public class LeafListEffectiveStatementImpl extends AbstractEffectiveDocumentedNode<QName, LeafListStatement> implements LeafListSchemaNode, DerivableSchemaNode {
+public class LeafListEffectiveStatementImpl extends
+        AbstractEffectiveDocumentedNode<QName, LeafListStatement> implements
+        LeafListSchemaNode, DerivableSchemaNode {
     private final QName qname;
     private final SchemaPath path;
 
@@ -39,28 +42,50 @@ public class LeafListEffectiveStatementImpl extends AbstractEffectiveDocumentedN
 
     private ImmutableList<UnknownSchemaNode> unknownNodes;
 
-    public LeafListEffectiveStatementImpl(StmtContext<QName, LeafListStatement, EffectiveStatement<QName, LeafListStatement>> ctx) {
+    public LeafListEffectiveStatementImpl(
+            StmtContext<QName, LeafListStatement, EffectiveStatement<QName, LeafListStatement>> ctx) {
         super(ctx);
         this.qname = ctx.getStatementArgument();
         this.path = Utils.getSchemaPath(ctx);
-        //:TODO init other fields
+        // :TODO init other fields
 
         initSubstatementCollections();
+        initCopyType(ctx);
+    }
+
+    private void initCopyType(
+            StmtContext<QName, LeafListStatement, EffectiveStatement<QName, LeafListStatement>> ctx) {
+
+        TypeOfCopy typeOfCopy = ctx.getTypeOfCopy();
+        switch (typeOfCopy) {
+        case ADDED_BY_AUGMENTATION:
+            augmenting = true;
+            original = (LeafListSchemaNode) ctx.getOriginalCtx()
+                    .buildEffective();
+            break;
+        case ADDED_BY_USES:
+            addedByUses = true;
+            original = (LeafListSchemaNode) ctx.getOriginalCtx()
+                    .buildEffective();
+            break;
+        default:
+            break;
+        }
     }
 
     private void initSubstatementCollections() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof UnknownSchemaNode) {
                 UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+                unknownNodesInit.add(unknownNode);
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
     }
 
     @Override
@@ -153,7 +178,8 @@ public class LeafListEffectiveStatementImpl extends AbstractEffectiveDocumentedN
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder(LeafListEffectiveStatementImpl.class.getSimpleName());
+        StringBuilder sb = new StringBuilder(
+                LeafListEffectiveStatementImpl.class.getSimpleName());
         sb.append("[");
         sb.append(qname);
         sb.append("]");
index 30ba7d425bfefd941e7b0eacc05ed9b536446be1..4e205bde1a1ab1b36f39cf5dfd02ded1eee51311 100644 (file)
@@ -1,7 +1,8 @@
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
 
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -48,44 +49,63 @@ public class ListEffectiveStatementImpl extends
 
         initKeyDefinition();
         initSubstatementCollections();
+        initCopyType(ctx);
+    }
+
+    private void initCopyType(
+            StmtContext<QName, ListStatement, EffectiveStatement<QName, ListStatement>> ctx) {
+
+        TypeOfCopy typeOfCopy = ctx.getTypeOfCopy();
+        switch (typeOfCopy) {
+        case ADDED_BY_AUGMENTATION:
+            augmenting = true;
+            original = (ListSchemaNode) ctx.getOriginalCtx().buildEffective();
+            break;
+        case ADDED_BY_USES:
+            addedByUses = true;
+            original = (ListSchemaNode) ctx.getOriginalCtx().buildEffective();
+            break;
+        default:
+            break;
+        }
     }
 
     /**
      *
      */
     private void initKeyDefinition() {
-        List<QName> keyDefinition = new LinkedList<QName>();
+        List<QName> keyDefinitionInit = new LinkedList<QName>();
         KeyEffectiveStatementImpl key = firstEffective(KeyEffectiveStatementImpl.class);
 
         if (key != null) {
             Collection<SchemaNodeIdentifier> keyParts = key.argument();
             for (SchemaNodeIdentifier keyPart : keyParts) {
-                keyDefinition.add(keyPart.getLastComponent());
+                keyDefinitionInit.add(keyPart.getLastComponent());
             }
         }
 
-        this.keyDefinition = ImmutableList.copyOf(keyDefinition);
+        this.keyDefinition = ImmutableList.copyOf(keyDefinitionInit);
     }
 
     private void initSubstatementCollections() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
-        HashSet<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<UnknownSchemaNode>();
+        Set<AugmentationSchema> augmentationsInit = new HashSet<AugmentationSchema>();
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof UnknownSchemaNode) {
                 UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+                unknownNodesInit.add(unknownNode);
             }
             if (effectiveStatement instanceof AugmentationSchema) {
                 AugmentationSchema augmentationSchema = (AugmentationSchema) effectiveStatement;
-                augmentations.add(augmentationSchema);
+                augmentationsInit.add(augmentationSchema);
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
-        this.augmentations = ImmutableSet.copyOf(augmentations);
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
+        this.augmentations = ImmutableSet.copyOf(augmentationsInit);
     }
 
     @Override
index 1e6d51cf8b27912fdf920afea11c4f1b00c1b696..a514971e287a83b0dd909c824be7c06f36e48d14 100644 (file)
@@ -7,39 +7,42 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
+import java.net.URI;
 import java.util.Collection;
+import java.util.Date;
 import java.util.HashSet;
 import java.util.LinkedList;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import java.net.URI;
-import java.util.Date;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleImpl;
 import java.util.List;
 import java.util.Set;
+
+import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.Deviation;
 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
-import org.opendaylight.yangtools.concepts.Immutable;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.IncludeStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleImpl;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.IncludedModuleContext;
 
-public class ModuleEffectiveStatementImpl extends
-        AbstractEffectiveDocumentedDataNodeContainer<String, ModuleStatement>
+public class ModuleEffectiveStatementImpl extends AbstractEffectiveDocumentedDataNodeContainer<String, ModuleStatement>
         implements Module, Immutable {
 
-    private final QNameModule qnameModule;
+    private final QNameModule qNameModule;
     private final String name;
     private String sourcePath;
     private String prefix;
@@ -58,39 +61,93 @@ public class ModuleEffectiveStatementImpl extends
     private ImmutableList<UnknownSchemaNode> unknownNodes;
     private String source;
 
-    public ModuleEffectiveStatementImpl(
-            StmtContext<String, ModuleStatement, ?> ctx) {
+    public ModuleEffectiveStatementImpl(StmtContext<String, ModuleStatement, ?> ctx) {
         super(ctx);
 
         name = argument();
-        qnameModule = ctx.getFromNamespace(ModuleNameToModuleQName.class, name);
-        // :TODO init other fields
+        qNameModule = ctx.getFromNamespace(ModuleNameToModuleQName.class, name);
 
-        initSubstatementCollections();
+        for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
+            if (effectiveStatement instanceof PrefixEffectiveStatementImpl) {
+                prefix = ((PrefixEffectiveStatementImpl) effectiveStatement).argument();
+            }
+            if (effectiveStatement instanceof YangVersionEffectiveStatementImpl) {
+                yangVersion = ((YangVersionEffectiveStatementImpl) effectiveStatement).argument();
+            }
+            if (effectiveStatement instanceof OrganizationEffectiveStatementImpl) {
+                organization = ((OrganizationEffectiveStatementImpl) effectiveStatement).argument();
+            }
+            if (effectiveStatement instanceof ContactEffectiveStatementImpl) {
+                contact = ((ContactEffectiveStatementImpl) effectiveStatement).argument();
+            }
+        }
+
+        source = ctx.getStatementSource().name();
+
+        //ctx.getFromNamespace(IncludedModuleContext.class, ) //ModuleIdentifier
 
+        initSubstatementCollections();
     }
 
     private void initSubstatementCollections() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
-        HashSet<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
+        Set<AugmentationSchema> augmentationsInit = new HashSet<>();
+        Set<ModuleImport> importsInit = new HashSet<>();
+        Set<Module> submodulesInit = new HashSet<>();
+        Set<NotificationDefinition> notificationsInit = new HashSet<>();
+        Set<RpcDefinition> rpcsInit = new HashSet<>();
+        Set<Deviation> deviationsInit = new HashSet<>();
+        Set<IdentitySchemaNode> identitiesInit = new HashSet<>();
+        Set<FeatureDefinition> featuresInit = new HashSet<>();
+        List<ExtensionDefinition> extensionNodesInit = new LinkedList<>();
+
+
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof UnknownSchemaNode) {
-                UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+                unknownNodesInit.add((UnknownSchemaNode) effectiveStatement);
             }
             if (effectiveStatement instanceof AugmentationSchema) {
-                AugmentationSchema augmentationSchema = (AugmentationSchema) effectiveStatement;
-                augmentations.add(augmentationSchema);
+                augmentationsInit.add((AugmentationSchema) effectiveStatement);
+            }
+            if (effectiveStatement instanceof ModuleImport) {
+                importsInit.add((ModuleImport) effectiveStatement);
+            }
+            if (effectiveStatement instanceof IncludeEffectiveStatementImpl) {
+//                ((IncludeEffectiveStatementImpl) effectiveStatement).
+            }
+            if (effectiveStatement instanceof NotificationDefinition) {
+                notificationsInit.add((NotificationDefinition) effectiveStatement);
+            }
+            if (effectiveStatement instanceof RpcDefinition) {
+                rpcsInit.add((RpcDefinition) effectiveStatement);
+            }
+            if (effectiveStatement instanceof Deviation) {
+                deviationsInit.add((Deviation) effectiveStatement);
+            }
+            if (effectiveStatement instanceof IdentitySchemaNode) {
+                identitiesInit.add((IdentitySchemaNode) effectiveStatement);
+            }
+            if (effectiveStatement instanceof FeatureDefinition) {
+                featuresInit.add((FeatureDefinition) effectiveStatement);
+            }
+            if (effectiveStatement instanceof ExtensionDefinition) {
+                extensionNodesInit.add((ExtensionDefinition) effectiveStatement);
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
-        this.augmentations = ImmutableSet.copyOf(augmentations);
-
-        // :TODO other substatement collections ...
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
+        this.augmentations = ImmutableSet.copyOf(augmentationsInit);
+        this.imports = ImmutableSet.copyOf(importsInit);
+        this.submodules = ImmutableSet.copyOf(submodulesInit);
+        this.notifications = ImmutableSet.copyOf(notificationsInit);
+        this.rpcs = ImmutableSet.copyOf(rpcsInit);
+        this.deviations = ImmutableSet.copyOf(deviationsInit);
+        this.identities = ImmutableSet.copyOf(identitiesInit);
+        this.features = ImmutableSet.copyOf(featuresInit);
+        this.extensionNodes = ImmutableList.copyOf(extensionNodesInit);
     }
 
     @Override
@@ -100,7 +157,7 @@ public class ModuleEffectiveStatementImpl extends
 
     @Override
     public URI getNamespace() {
-        return qnameModule.getNamespace();
+        return qNameModule.getNamespace();
     }
 
     @Override
@@ -110,7 +167,7 @@ public class ModuleEffectiveStatementImpl extends
 
     @Override
     public Date getRevision() {
-        return qnameModule.getRevision();
+        return qNameModule.getRevision();
     }
 
     @Override
@@ -193,9 +250,8 @@ public class ModuleEffectiveStatementImpl extends
         final int prime = 31;
         int result = 1;
         result = prime * result + ((name == null) ? 0 : name.hashCode());
-        result = prime * result
-                + ((yangVersion == null) ? 0 : yangVersion.hashCode());
-        result = prime * result + qnameModule.hashCode();
+        result = prime * result + ((yangVersion == null) ? 0 : yangVersion.hashCode());
+        result = prime * result + qNameModule.hashCode();
         return result;
     }
 
@@ -218,7 +274,7 @@ public class ModuleEffectiveStatementImpl extends
         } else if (!name.equals(other.name)) {
             return false;
         }
-        if (!qnameModule.equals(other.qnameModule)) {
+        if (!qNameModule.equals(other.qNameModule)) {
             return false;
         }
         if (yangVersion == null) {
@@ -231,13 +287,6 @@ public class ModuleEffectiveStatementImpl extends
         return true;
     }
 
-    // private static <T extends SchemaNode> Set<T> toImmutableSortedSet(final
-    // Set<T> original) {
-    // TreeSet<T> sorted = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
-    // sorted.addAll(original);
-    // return Collections.unmodifiableSet(sorted);
-    // }
-
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder(ModuleImpl.class.getSimpleName());
@@ -253,7 +302,7 @@ public class ModuleEffectiveStatementImpl extends
 
     @Override
     public QNameModule getQNameModule() {
-        return qnameModule;
+        return qNameModule;
     }
 
 }
index 4afe4f4dcf554b800fc0095fd66695cb84d181ef..b53772ae92ae421fe1297951e6f15f72ba8cad4c 100644 (file)
@@ -46,22 +46,22 @@ public class NotificationEffectiveStatementImpl
     private void initSubstatementCollections() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
-        HashSet<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
+        Set<AugmentationSchema> augmentationsInit = new HashSet<>();
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof UnknownSchemaNode) {
                 UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+                unknownNodesInit.add(unknownNode);
             }
             if (effectiveStatement instanceof AugmentationSchema) {
                 AugmentationSchema augmentationSchema = (AugmentationSchema) effectiveStatement;
-                augmentations.add(augmentationSchema);
+                augmentationsInit.add(augmentationSchema);
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
-        this.augmentations = ImmutableSet.copyOf(augmentations);
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
+        this.augmentations = ImmutableSet.copyOf(augmentationsInit);
     }
 
     @Override
index e35efd9948d1ac9740eb90285df46ac458909acc..0d061e115b260b861d0c0fcdbe095e602a6e9242 100644 (file)
@@ -7,10 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
+
 import java.util.HashSet;
 import java.util.LinkedList;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
-
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import java.util.List;
@@ -54,27 +55,48 @@ public class OutputEffectiveStatementImpl extends
         // :TODO init other fields
 
         initSubstatementCollections();
+        initCopyType(ctx);
+    }
+
+    private void initCopyType(
+            StmtContext<QName, OutputStatement, EffectiveStatement<QName, OutputStatement>> ctx) {
+
+        TypeOfCopy typeOfCopy = ctx.getTypeOfCopy();
+        switch (typeOfCopy) {
+        case ADDED_BY_AUGMENTATION:
+            augmenting = true;
+            original = (ContainerSchemaNode) ctx.getOriginalCtx()
+                    .buildEffective();
+            break;
+        case ADDED_BY_USES:
+            addedByUses = true;
+            original = (ContainerSchemaNode) ctx.getOriginalCtx()
+                    .buildEffective();
+            break;
+        default:
+            break;
+        }
     }
 
     private void initSubstatementCollections() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
-        HashSet<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
+        Set<AugmentationSchema> augmentationsInit = new HashSet<>();
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof UnknownSchemaNode) {
                 UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+                unknownNodesInit.add(unknownNode);
             }
             if (effectiveStatement instanceof AugmentationSchema) {
                 AugmentationSchema augmentationSchema = (AugmentationSchema) effectiveStatement;
-                augmentations.add(augmentationSchema);
+                augmentationsInit.add(augmentationSchema);
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
-        this.augmentations = ImmutableSet.copyOf(augmentations);
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
+        this.augmentations = ImmutableSet.copyOf(augmentationsInit);
     }
 
     @Override
index a0d1ad12293e1e51f739fff4e227abfaea8fc64e..1fcecde23e0ab67808ff54699d8608183a6a82c1 100644 (file)
@@ -49,22 +49,22 @@ public class RpcEffectiveStatementImpl extends AbstractEffectiveDocumentedNode<Q
     private void initSubstatements() {
         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
 
-        LinkedList<UnknownSchemaNode> unknownNodes = new LinkedList<UnknownSchemaNode>();
-        HashSet<GroupingDefinition> groupings = new HashSet<GroupingDefinition>();
-        HashSet<TypeDefinition<?>> typeDefinitions = new HashSet<TypeDefinition<?>>();
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
+        Set<GroupingDefinition> groupingsInit = new HashSet<>();
+        Set<TypeDefinition<?>> typeDefinitionsInit = new HashSet<>();
 
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
             if (effectiveStatement instanceof UnknownSchemaNode) {
                 UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement;
-                unknownNodes.add(unknownNode);
+                unknownNodesInit.add(unknownNode);
             }
             if (effectiveStatement instanceof GroupingDefinition) {
                 GroupingDefinition groupingDefinition = (GroupingDefinition) effectiveStatement;
-                groupings.add(groupingDefinition);
+                groupingsInit.add(groupingDefinition);
             }
             if (effectiveStatement instanceof TypeDefinition) {
                 TypeDefinition<?> typeDefinition = (TypeDefinition<?>) effectiveStatement;
-                typeDefinitions.add(typeDefinition);
+                typeDefinitionsInit.add(typeDefinition);
             }
             if (this.input == null && effectiveStatement instanceof InputEffectiveStatementImpl) {
                 this.input = (InputEffectiveStatementImpl) effectiveStatement;
@@ -74,9 +74,9 @@ public class RpcEffectiveStatementImpl extends AbstractEffectiveDocumentedNode<Q
             }
         }
 
-        this.unknownNodes = ImmutableList.copyOf(unknownNodes);
-        this.groupings = ImmutableSet.copyOf(groupings);
-        this.typeDefinitions = ImmutableSet.copyOf(typeDefinitions);
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
+        this.groupings = ImmutableSet.copyOf(groupingsInit);
+        this.typeDefinitions = ImmutableSet.copyOf(typeDefinitionsInit);
     }
 
     @Override
index 762d408b7882a1de318e0a19fec777eaa1fee8f4..380bcb10ccb3c9c2073b3be0da9c907ff937e3af 100644 (file)
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
+import java.net.URI;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
 
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.Deviation;
+import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
+import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.BelongsToStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleImpl;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
+
+import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
+
 public class SubmoduleEffectiveStatementImpl extends
-        ModuleEffectiveStatementImpl {
+        AbstractEffectiveDocumentedDataNodeContainer<String, SubmoduleStatement> implements Module, Immutable {
 
-    public SubmoduleEffectiveStatementImpl(
-            StmtContext<String, ModuleStatement, ?> ctx) {
+    private final QNameModule qNameModule;
+    private final String name;
+    private String sourcePath;
+    private String prefix;
+    private String yangVersion;
+    private String organization;
+    private String contact;
+    private ImmutableSet<ModuleImport> imports;
+    private ImmutableSet<Module> submodules;
+    private ImmutableSet<FeatureDefinition> features;
+    private ImmutableSet<NotificationDefinition> notifications;
+    private ImmutableSet<AugmentationSchema> augmentations;
+    private ImmutableSet<RpcDefinition> rpcs;
+    private ImmutableSet<Deviation> deviations;
+    private ImmutableList<ExtensionDefinition> extensionNodes;
+    private ImmutableSet<IdentitySchemaNode> identities;
+    private ImmutableList<UnknownSchemaNode> unknownNodes;
+    private String source;
+
+    public SubmoduleEffectiveStatementImpl(StmtContext<String, SubmoduleStatement, ?> ctx) {
         super(ctx);
 
+        name = argument();
+
+        String belongsToModuleName = firstAttributeOf(ctx.declaredSubstatements(), BelongsToStatement.class);
+        final QNameModule belongsToModule = ctx.getFromNamespace(ModuleNameToModuleQName.class, belongsToModuleName);
+        qNameModule = QNameModule.create(belongsToModule.getNamespace(), belongsToModule.getRevision());
+
+        for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
+            if (effectiveStatement instanceof PrefixEffectiveStatementImpl) {
+                prefix = ((PrefixEffectiveStatementImpl) effectiveStatement).argument();
+            }
+            if (effectiveStatement instanceof YangVersionEffectiveStatementImpl) {
+                yangVersion = ((YangVersionEffectiveStatementImpl) effectiveStatement).argument();
+            }
+            if (effectiveStatement instanceof OrganizationEffectiveStatementImpl) {
+                organization = ((OrganizationEffectiveStatementImpl) effectiveStatement).argument();
+            }
+            if (effectiveStatement instanceof ContactEffectiveStatementImpl) {
+                contact = ((ContactEffectiveStatementImpl) effectiveStatement).argument();
+            }
+        }
+
+        source = ctx.getStatementSource().name();
+
+        initSubstatementCollections();
     }
 
+    private void initSubstatementCollections() {
+        Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
+
+        List<UnknownSchemaNode> unknownNodesInit = new LinkedList<>();
+        Set<AugmentationSchema> augmentationsInit = new HashSet<>();
+        Set<ModuleImport> importsInit = new HashSet<>();
+        Set<Module> submodulesInit = new HashSet<>();
+        Set<NotificationDefinition> notificationsInit = new HashSet<>();
+        Set<RpcDefinition> rpcsInit = new HashSet<>();
+        Set<Deviation> deviationsInit = new HashSet<>();
+        Set<IdentitySchemaNode> identitiesInit = new HashSet<>();
+        Set<FeatureDefinition> featuresInit = new HashSet<>();
+        List<ExtensionDefinition> extensionNodesInit = new LinkedList<>();
+
+        for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
+            if (effectiveStatement instanceof UnknownSchemaNode) {
+                unknownNodesInit.add((UnknownSchemaNode) effectiveStatement);
+            }
+            if (effectiveStatement instanceof AugmentationSchema) {
+                augmentationsInit.add((AugmentationSchema) effectiveStatement);
+            }
+            if (effectiveStatement instanceof ModuleImport) {
+                importsInit.add((ModuleImport) effectiveStatement);
+            }
+            if (effectiveStatement instanceof Module) {
+                submodulesInit.add((Module) effectiveStatement);
+            }
+            if (effectiveStatement instanceof NotificationDefinition) {
+                notificationsInit.add((NotificationDefinition) effectiveStatement);
+            }
+            if (effectiveStatement instanceof RpcDefinition) {
+                rpcsInit.add((RpcDefinition) effectiveStatement);
+            }
+            if (effectiveStatement instanceof Deviation) {
+                deviationsInit.add((Deviation) effectiveStatement);
+            }
+            if (effectiveStatement instanceof IdentitySchemaNode) {
+                identitiesInit.add((IdentitySchemaNode) effectiveStatement);
+            }
+            if (effectiveStatement instanceof FeatureDefinition) {
+                featuresInit.add((FeatureDefinition) effectiveStatement);
+            }
+            if (effectiveStatement instanceof ExtensionDefinition) {
+                extensionNodesInit.add((ExtensionDefinition) effectiveStatement);
+            }
+        }
+
+        this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
+        this.augmentations = ImmutableSet.copyOf(augmentationsInit);
+        this.imports = ImmutableSet.copyOf(importsInit);
+        this.submodules = ImmutableSet.copyOf(submodulesInit);
+        this.notifications = ImmutableSet.copyOf(notificationsInit);
+        this.rpcs = ImmutableSet.copyOf(rpcsInit);
+        this.deviations = ImmutableSet.copyOf(deviationsInit);
+        this.identities = ImmutableSet.copyOf(identitiesInit);
+        this.features = ImmutableSet.copyOf(featuresInit);
+        this.extensionNodes = ImmutableList.copyOf(extensionNodesInit);
+    }
+
+    @Override
+    public String getModuleSourcePath() {
+        return sourcePath;
+    }
+
+    @Override
+    public URI getNamespace() {
+        return qNameModule.getNamespace();
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public Date getRevision() {
+        return qNameModule.getRevision();
+    }
+
+    @Override
+    public String getPrefix() {
+        return prefix;
+    }
+
+    @Override
+    public String getYangVersion() {
+        return yangVersion;
+    }
+
+    @Override
+    public String getOrganization() {
+        return organization;
+    }
+
+    @Override
+    public String getContact() {
+        return contact;
+    }
+
+    @Override
+    public Set<ModuleImport> getImports() {
+        return imports;
+    }
+
+    @Override
+    public Set<Module> getSubmodules() {
+        return submodules;
+    }
+
+    @Override
+    public Set<FeatureDefinition> getFeatures() {
+        return features;
+    }
+
+    @Override
+    public Set<NotificationDefinition> getNotifications() {
+        return notifications;
+    }
+
+    @Override
+    public Set<AugmentationSchema> getAugmentations() {
+        return augmentations;
+    }
+
+    @Override
+    public Set<RpcDefinition> getRpcs() {
+        return rpcs;
+    }
+
+    @Override
+    public Set<Deviation> getDeviations() {
+        return deviations;
+    }
+
+    @Override
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {
+        return extensionNodes;
+    }
+
+    @Override
+    public Set<IdentitySchemaNode> getIdentities() {
+        return identities;
+    }
+
+    @Override
+    public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+        return unknownNodes;
+    }
+
+    @Override
+    public String getSource() {
+        return source;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((yangVersion == null) ? 0 : yangVersion.hashCode());
+        result = prime * result + qNameModule.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        SubmoduleEffectiveStatementImpl other = (SubmoduleEffectiveStatementImpl) obj;
+        if (name == null) {
+            if (other.name != null) {
+                return false;
+            }
+        } else if (!name.equals(other.name)) {
+            return false;
+        }
+        if (!qNameModule.equals(other.qNameModule)) {
+            return false;
+        }
+        if (yangVersion == null) {
+            if (other.yangVersion != null) {
+                return false;
+            }
+        } else if (!yangVersion.equals(other.yangVersion)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(ModuleImpl.class.getSimpleName());
+        sb.append("[");
+        sb.append("name=").append(name);
+        sb.append(", namespace=").append(getNamespace());
+        sb.append(", revision=").append(getRevision());
+        sb.append(", prefix=").append(prefix);
+        sb.append(", yangVersion=").append(yangVersion);
+        sb.append("]");
+        return sb.toString();
+    }
+
+    @Override
+    public QNameModule getQNameModule() {
+        return qNameModule;
+    }
 }
index 105e2978910d18a52b1cb11d62d05ec4242c37b4..7d3ba2aee42f7ebc65deb6c2f4360b1670c7c252 100644 (file)
@@ -26,7 +26,7 @@ public final class TopologicalSort {
 
     /**
      * Topological sort of dependent nodes in acyclic graphs.
-     * 
+     *
      * @return Sorted {@link List} of {@link Node}s. Order: Nodes with no
      *         dependencies starting.
      * @throws IllegalStateException
@@ -61,7 +61,7 @@ public final class TopologicalSort {
     private static Set<Node> getDependentNodes(Set<Node> nodes) {
         Set<Node> dependentNodes = Sets.newHashSet();
         for (Node n : nodes) {
-            if (n.getOutEdges().size() == 0) {
+            if (n.getOutEdges().isEmpty()) {
                 dependentNodes.add(n);
             }
         }
@@ -108,6 +108,11 @@ public final class TopologicalSort {
         private final Set<Edge> inEdges;
         private final Set<Edge> outEdges;
 
+        public NodeImpl() {
+            inEdges = Sets.newHashSet();
+            outEdges = Sets.newHashSet();
+        }
+
         @Override
         public Set<Edge> getInEdges() {
             return inEdges;
@@ -123,11 +128,6 @@ public final class TopologicalSort {
             outEdges.add(e);
             to.getInEdges().add(e);
         }
-
-        public NodeImpl() {
-            inEdges = Sets.newHashSet();
-            outEdges = Sets.newHashSet();
-        }
     }
 
     /**
@@ -137,6 +137,11 @@ public final class TopologicalSort {
         private final Node from;
         private final Node to;
 
+        public EdgeImpl(Node from, Node to) {
+            this.from = from;
+            this.to = to;
+        }
+
         @Override
         public Node getFrom() {
             return from;
@@ -147,12 +152,6 @@ public final class TopologicalSort {
             return to;
         }
 
-        public EdgeImpl(Node from, Node to) {
-            this.from = from;
-            this.to = to;
-
-        }
-
         @Override
         public int hashCode() {
             final int prime = 31;
index 2ea109939976ce34986a85f2f24d07c9359b8767..74d38ae920e482d89e4bf488a0b4a392ecbb9906 100644 (file)
@@ -6,22 +6,45 @@
  */
 package org.opendaylight.yangtools.yang.parser.builder.impl;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 
-import com.google.common.base.Optional;
 import java.net.URI;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.TreeMap;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.*;
+import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+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.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.util.Uint16;
-import org.opendaylight.yangtools.yang.parser.builder.api.*;
+import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
+import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
 
+import com.google.common.base.Optional;
+
 /**
  * Test suite for increasing of test coverage of BuilderUtils implementation.
  *
@@ -67,7 +90,7 @@ public class BuilderUtilsTest {
 
     @Test
     public void testFindModuleFromBuildersWithNullPrefix() throws Exception {
-        final Map<String, TreeMap<Date, ModuleBuilder>> testModules = initModuleBuildersForTest();
+        final Map<String, NavigableMap<Date, ModuleBuilder>> testModules = initModuleBuildersForTest();
 
         ModuleBuilder result = BuilderUtils.findModuleFromBuilders(testModules, masterModule, null, 12);
         assertEquals(masterModule, result);
@@ -79,8 +102,8 @@ public class BuilderUtilsTest {
         assertEquals(dependentModule, result);
     }
 
-    private Map<String, TreeMap<Date, ModuleBuilder>> initModuleBuildersForTest() throws Exception {
-        final Map<String, TreeMap<Date, ModuleBuilder>> modules = new HashMap<>();
+    private Map<String, NavigableMap<Date, ModuleBuilder>> initModuleBuildersForTest() throws Exception {
+        final Map<String, NavigableMap<Date, ModuleBuilder>> modules = new HashMap<>();
         final String module3Name = "Module3";
 
         ModuleBuilder module3 = new ModuleBuilder(module3Name, "test/module/path/module3.yang");
@@ -92,13 +115,13 @@ public class BuilderUtilsTest {
 
         dependentModule.addModuleImport(module3.getModuleName(), module3.getRevision(), "ter");
 
-        final TreeMap<Date, ModuleBuilder> module1Map = new TreeMap<>();
+        final NavigableMap<Date, ModuleBuilder> module1Map = new TreeMap<>();
         module1Map.put(masterModule.getRevision(), masterModule);
 
-        final TreeMap<Date, ModuleBuilder> module2Map = new TreeMap<>();
+        final NavigableMap<Date, ModuleBuilder> module2Map = new TreeMap<>();
         module2Map.put(dependentModule.getRevision(), dependentModule);
 
-        final TreeMap<Date, ModuleBuilder> module3Map = new TreeMap<>();
+        final NavigableMap<Date, ModuleBuilder> module3Map = new TreeMap<>();
         module3Map.put(module3.getRevision(), module3);
 
         modules.put(masterModule.getName(), module1Map);
@@ -110,7 +133,7 @@ public class BuilderUtilsTest {
 
     @Test(expected = YangParseException.class)
     public void testFindModuleFromBuildersWithNoImportedModule() throws Exception {
-        final Map<String, TreeMap<Date, ModuleBuilder>> testModules = initModuleBuildersForTest();
+        final Map<String, NavigableMap<Date, ModuleBuilder>> testModules = initModuleBuildersForTest();
 
         BuilderUtils.findModuleFromBuilders(testModules, masterModule, "eth", 12);
     }
@@ -379,8 +402,8 @@ public class BuilderUtilsTest {
 
     @Test
     public void testFindModule() {
-        final Map<URI, TreeMap<Date, ModuleBuilder>> modules = new HashMap<>(1);
-        final TreeMap<Date, ModuleBuilder> masterModuleMap = new TreeMap<>();
+        final Map<URI, NavigableMap<Date, ModuleBuilder>> modules = new HashMap<>(1);
+        final NavigableMap<Date, ModuleBuilder> masterModuleMap = new TreeMap<>();
         masterModuleMap.put(masterModule.getRevision(), masterModule);
         modules.put(masterModule.getNamespace(), masterModuleMap);
 
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveModuleTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveModuleTest.java
new file mode 100644 (file)
index 0000000..c7ce9e4
--- /dev/null
@@ -0,0 +1,127 @@
+package org.opendaylight.yangtools.yang.stmt.effective.build.test;
+
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.Deviation;
+import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
+
+import java.net.URI;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class EffectiveModuleTest {
+
+    private static final YangStatementSourceImpl ROOT_MODULE = new YangStatementSourceImpl(
+            "/semantic-statement-parser/effective-module/root.yang");
+    private static final YangStatementSourceImpl IMPORTED_MODULE = new YangStatementSourceImpl(
+            "/semantic-statement-parser/effective-module/imported.yang");
+    private static final YangStatementSourceImpl SUBMODULE = new YangStatementSourceImpl(
+            "/semantic-statement-parser/effective-module/submod.yang");
+
+    private static final QNameModule ROOT_MODULE_QNAME = QNameModule.create(URI.create("root-ns"), null);
+
+    private static final QName cont = QName.create(ROOT_MODULE_QNAME, "cont");
+
+    private static final SchemaPath contSchemaPath = SchemaPath.create(true, cont);
+
+    private static Date revision;
+
+    @BeforeClass
+    public static void init() {
+        try {
+            revision = SimpleDateFormatUtil.getRevisionFormat()
+                    .parse("2000-01-01");
+        } catch (ParseException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    @Test
+    public void effectiveBuildTest() throws SourceException, ReactorException {
+        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
+        addSources(reactor, ROOT_MODULE, IMPORTED_MODULE, SUBMODULE);
+        EffectiveSchemaContext result = reactor.buildEffective();
+
+        assertNotNull(result);
+
+        Module rootModule = result.findModuleByName("root", null);
+        assertNotNull(rootModule);
+
+        assertEquals("root-pref", rootModule.getPrefix());
+        assertEquals("1", rootModule.getYangVersion());
+        assertEquals("kisko", rootModule.getOrganization());
+        assertEquals("kisko email", rootModule.getContact());
+
+        final Set<AugmentationSchema> augmentations = rootModule.getAugmentations();
+        assertEquals(1, augmentations.size());
+        assertEquals(contSchemaPath, augmentations.iterator().next().getTargetPath());
+
+        final Set<ModuleImport> imports = rootModule.getImports();
+        assertEquals(1, imports.size());
+        final ModuleImport importStmt = imports.iterator().next();
+        assertNotNull(importStmt);
+        assertEquals("imported", importStmt.getModuleName());
+        assertEquals(revision, importStmt.getRevision());
+        assertEquals("imp-pref", importStmt.getPrefix());
+
+        final Set<Module> submodules = rootModule.getSubmodules();
+        //assertEquals(1, submodules.size());
+        //assertEquals("submod", submodules.iterator().next().getName());
+
+        final Set<NotificationDefinition> notifications = rootModule.getNotifications();
+        assertEquals(1, notifications.size());
+        assertEquals("notif1", notifications.iterator().next().getQName().getLocalName());
+
+        final Set<RpcDefinition> rpcs = rootModule.getRpcs();
+        assertEquals(1, rpcs.size());
+        assertEquals("rpc1", rpcs.iterator().next().getQName().getLocalName());
+
+        final Set<Deviation> deviations = rootModule.getDeviations();
+        assertEquals(1, deviations.size());
+        final Deviation deviationStmt = deviations.iterator().next();
+        assertNotNull(deviationStmt);
+        assertEquals(contSchemaPath, deviationStmt.getTargetPath());
+        assertEquals(Deviation.Deviate.ADD, deviationStmt.getDeviate());
+        assertEquals("deviate reference", deviationStmt.getReference());
+
+        final Set<IdentitySchemaNode> identities = rootModule.getIdentities();
+        assertEquals(1, identities.size());
+        assertEquals("identity1", identities.iterator().next().getQName().getLocalName());
+
+//        final Set<FeatureDefinition> features = rootModule.getFeatures();
+//        assertEquals(1, features.size());
+//        assertEquals("feature1", features.iterator().next().getQName().getLocalName());
+
+        final List<ExtensionDefinition> extensionSchemaNodes = rootModule.getExtensionSchemaNodes();
+        assertEquals(1, extensionSchemaNodes.size());
+        assertEquals("ext1", extensionSchemaNodes.iterator().next().getQName().getLocalName());
+    }
+
+    private void addSources(CrossSourceStatementReactor.BuildAction reactor, YangStatementSourceImpl... sources) {
+        for (YangStatementSourceImpl source : sources) {
+            reactor.addSource(source);
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/YangFileStatementSource.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/YangFileStatementSource.java
deleted file mode 100644 (file)
index 9738c46..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.opendaylight.yangtools.yang.stmt.effective.build.test;
-
-import org.antlr.v4.runtime.ANTLRInputStream;
-import org.antlr.v4.runtime.CommonTokenStream;
-import org.antlr.v4.runtime.tree.ParseTreeWalker;
-import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementLexer;
-import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser;
-import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
-import org.opendaylight.yangtools.yang.parser.impl.YangStatementParserListenerImpl;
-import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
-import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
-import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-public class YangFileStatementSource implements StatementStreamSource {
-
-        private YangStatementParserListenerImpl yangStatementModelParser;
-        private YangStatementParser.StatementContext statementContext;
-        private ParseTreeWalker walker;
-
-        public YangFileStatementSource(String fileName) {
-                try {
-                        statementContext = parseYangSource(loadFile(fileName));
-                        walker = new ParseTreeWalker();
-                        yangStatementModelParser = new YangStatementParserListenerImpl(REF);
-                } catch (Exception e) {
-                        e.printStackTrace();
-                }
-        }
-
-        private StatementSourceReference REF = new StatementSourceReference() {
-
-                @Override
-                public StatementSource getStatementSource() {
-                        return StatementSource.DECLARATION;
-                }
-        };
-
-        @Override
-        public void writeLinkage(StatementWriter writer, QNameToStatementDefinition stmtDef) throws SourceException {
-                yangStatementModelParser.setAttributes(writer, stmtDef);
-                walker.walk(yangStatementModelParser, statementContext);
-        }
-
-        @Override
-        public void writeLinkageAndStatementDefinitions(StatementWriter writer, QNameToStatementDefinition stmtDef, PrefixToModule prefixes) throws SourceException {
-                yangStatementModelParser.setAttributes(writer, stmtDef, prefixes);
-                walker.walk(yangStatementModelParser, statementContext);
-        }
-
-        @Override
-        public void writeFull(StatementWriter writer, QNameToStatementDefinition stmtDef, PrefixToModule prefixes) throws SourceException {
-                yangStatementModelParser.setAttributes(writer, stmtDef, prefixes);
-                walker.walk(yangStatementModelParser, statementContext);
-        }
-
-        private FileInputStream loadFile(String fileName) throws Exception {
-                return new FileInputStream(new File(getClass().getResource(fileName).toURI()));
-        }
-
-        private YangStatementParser.StatementContext parseYangSource(final InputStream stream) throws IOException {
-                final YangStatementLexer lexer = new YangStatementLexer(new ANTLRInputStream(stream));
-                final CommonTokenStream tokens = new CommonTokenStream(lexer);
-                final YangStatementParser parser = new YangStatementParser(tokens);
-                //TODO: no error listener yet
-                //parser.removeErrorListeners();
-                //final YangErrorListener errorListener = new YangErrorListener();
-                //parser.addErrorListener(errorListener);
-                final YangStatementParser.StatementContext result = parser.statement();
-                //errorListener.validate();
-                return result;
-        }
-}
\ No newline at end of file
index d9ecd4eef523ba1cd2e73920ff0f4a849005f640..10cba77b1a6a035b7ea9057e8353ebe6a3157bbf 100644 (file)
@@ -2,14 +2,17 @@ package org.opendaylight.yangtools.yang.stmt.test;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-
+import static org.junit.Assert.assertNull;
+import java.net.URI;
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.meta.ModelStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
@@ -17,69 +20,218 @@ import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementR
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
-
-import java.net.URI;
+import com.google.common.collect.ImmutableList;
 
 public class AugmentProcessTest {
 
     private static final YangStatementSourceImpl AUGMENTED = new YangStatementSourceImpl(
-            "/stmt-test/effective-build/augmented.yang");
+            "/stmt-test/augments/augmented.yang");
     private static final YangStatementSourceImpl ROOT = new YangStatementSourceImpl(
-            "/stmt-test/effective-build/aug-root.yang");
+            "/stmt-test/augments/aug-root.yang");
 
-    private static final QNameModule AUGMENTED_QNAME_MODULE = QNameModule.create(URI.create("aug"), null);
+    private static final QNameModule ROOT_QNAME_MODULE = QNameModule.create(
+            URI.create("root"), null);
+    private static final QNameModule AUGMENTED_QNAME_MODULE = QNameModule
+            .create(URI.create("aug"), null);
 
-    QName augParent1 = QName.create(AUGMENTED_QNAME_MODULE, "aug-parent1");
-    QName augParent2 = QName.create(AUGMENTED_QNAME_MODULE, "aug-parent2");
-    QName contTarget = QName.create(AUGMENTED_QNAME_MODULE, "cont-target");
+    private static GroupingDefinition grp2Def;
 
-    QName contAdded1 = QName.create(AUGMENTED_QNAME_MODULE, "cont-added1");
-    QName contAdded2 = QName.create(AUGMENTED_QNAME_MODULE, "cont-added2");
+    private final QName augParent1 = QName.create(AUGMENTED_QNAME_MODULE,
+            "aug-parent1");
+    private final QName augParent2 = QName.create(AUGMENTED_QNAME_MODULE,
+            "aug-parent2");
+    private final QName contTarget = QName.create(AUGMENTED_QNAME_MODULE,
+            "cont-target");
 
-    QName list1 = QName.create(AUGMENTED_QNAME_MODULE, "list1");
-    QName axml = QName.create(AUGMENTED_QNAME_MODULE, "axml");
+    private final QName contAdded1 = QName.create(AUGMENTED_QNAME_MODULE,
+            "cont-added1");
+    private final QName contAdded2 = QName.create(AUGMENTED_QNAME_MODULE,
+            "cont-added2");
 
-    QName contGrp = QName.create(AUGMENTED_QNAME_MODULE, "cont-grp");
-    QName axmlGrp = QName.create(AUGMENTED_QNAME_MODULE, "axml-grp");
+    private final QName list1 = QName.create(AUGMENTED_QNAME_MODULE, "list1");
+    private final QName axml = QName.create(AUGMENTED_QNAME_MODULE, "axml");
 
-    @Test
-    public void readAndParseYangFileTest() throws SourceException, ReactorException {
+    private final QName contGrp = QName.create(AUGMENTED_QNAME_MODULE,
+            "cont-grp");
+    private final QName axmlGrp = QName.create(AUGMENTED_QNAME_MODULE,
+            "axml-grp");
 
-        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        addSources(reactor, AUGMENTED, ROOT);
+    private final QName augCont1 = QName.create(ROOT_QNAME_MODULE, "aug-cont1");
+    private final QName augCont2 = QName.create(ROOT_QNAME_MODULE, "aug-cont2");
+
+    private final QName grpCont2 = QName.create(ROOT_QNAME_MODULE, "grp-cont2");
+    private final QName grpCont22 = QName.create(ROOT_QNAME_MODULE,
+            "grp-cont22");
+    private final QName grpAdd = QName.create(ROOT_QNAME_MODULE, "grp-add");
+
+    private static final YangStatementSourceImpl MULTIPLE_AUGMENT = new YangStatementSourceImpl(
+            "/stmt-test/augments/multiple-augment-test.yang");
+
+    private static final YangStatementSourceImpl MULTIPLE_AUGMENT_ROOT = new YangStatementSourceImpl(
+            "/stmt-test/augments/multiple-augment-root.yang");
+    private static final YangStatementSourceImpl MULTIPLE_AUGMENT_IMPORTED = new YangStatementSourceImpl(
+            "/stmt-test/augments/multiple-augment-imported.yang");
+    private static final YangStatementSourceImpl MULTIPLE_AUGMENT_SUBMODULE = new YangStatementSourceImpl(
+            "/stmt-test/augments/multiple-augment-submodule.yang");
+
+    private static final YangStatementSourceImpl MULTIPLE_AUGMENT_INCORRECT = new YangStatementSourceImpl(
+            "/stmt-test/augments/multiple-augment-incorrect.yang");
+
+    private static final YangStatementSourceImpl MULTIPLE_AUGMENT_INCORRECT2 = new YangStatementSourceImpl(
+            "/stmt-test/augments/multiple-augment-incorrect2.yang");
 
-        final EffectiveSchemaContext result = reactor.buildEffective();
+    @Test
+    public void multipleAugmentsAndMultipleModulesTest() throws SourceException,
+            ReactorException {
+        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
+                .newBuild();
+        addSources(reactor, MULTIPLE_AUGMENT_ROOT, MULTIPLE_AUGMENT_IMPORTED, MULTIPLE_AUGMENT_SUBMODULE);
+
+        EffectiveSchemaContext result = null;
+        try {
+            result = reactor.buildEffective();
+        } catch (Exception e) {
+            log(e, "");
+        }
+        assertNotNull(result);
+    }
 
+    @Test
+    public void multipleAugmentTest() throws SourceException, ReactorException {
+        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
+                .newBuild();
+        addSources(reactor, MULTIPLE_AUGMENT);
+
+        EffectiveSchemaContext result = null;
+        try {
+            result = reactor.buildEffective();
+        } catch (Exception e) {
+            log(e, "");
+        }
         assertNotNull(result);
+    }
 
-        Module augmentedModule = result.findModuleByName("augmented", null);
+    @Test
+    public void multipleAugmentIncorrectPathTest() throws SourceException,
+            ReactorException {
+        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
+                .newBuild();
+        addSources(reactor, MULTIPLE_AUGMENT_INCORRECT);
+
+        EffectiveSchemaContext result = null;
+        try {
+            result = reactor.buildEffective();
+        } catch (Exception e) {
+            log(e, "");
+        }
+
+        assertNull(result);
+    }
+
+    @Test
+    public void multipleAugmentIncorrectPathAndGrpTest() throws SourceException,
+            ReactorException {
+        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
+                .newBuild();
+        addSources(reactor, MULTIPLE_AUGMENT_INCORRECT2);
+
+        EffectiveSchemaContext result = null;
+        try {
+            result = reactor.buildEffective();
+        } catch (Exception e) {
+            log(e, "");
+        }
+
+        assertNull(result);
+    }
+
+    private void log(Throwable e, String indent) {
+        System.out.println(indent + e.getMessage());
+
+        Throwable[] suppressed = e.getSuppressed();
+        for (Throwable throwable : suppressed) {
+            log(throwable, indent + "        ");
+        }
+    }
+
+    @Test
+    public void readAndParseYangFileTest() throws SourceException,
+            ReactorException {
+
+        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
+                .newBuild();
+        addSources(reactor, AUGMENTED, ROOT);
+
+        final EffectiveSchemaContext root = reactor.buildEffective();
+        assertNotNull(root);
+
+        Module augmentedModule = root.findModuleByName("augmented", null);
         assertNotNull(augmentedModule);
 
-        ContainerSchemaNode augParent1Node = (ContainerSchemaNode) result.getDataChildByName(augParent1);
-        ContainerSchemaNode augParent2Node = (ContainerSchemaNode) augParent1Node.getDataChildByName(augParent2);
-        ContainerSchemaNode targetContNode = (ContainerSchemaNode) augParent2Node.getDataChildByName(contTarget);
+        ContainerSchemaNode augParent1Node = (ContainerSchemaNode) root
+                .getDataChildByName(augParent1);
+        ContainerSchemaNode augParent2Node = (ContainerSchemaNode) augParent1Node
+                .getDataChildByName(augParent2);
+        ContainerSchemaNode targetContNode = (ContainerSchemaNode) augParent2Node
+                .getDataChildByName(contTarget);
         assertNotNull(targetContNode);
 
         assertNotNull(targetContNode.getChildNodes());
         assertEquals(3, targetContNode.getChildNodes().size());
 
-        ContainerSchemaNode contAdded1Node = (ContainerSchemaNode) targetContNode.getDataChildByName(contAdded1);
+        ContainerSchemaNode contAdded1Node = (ContainerSchemaNode) targetContNode
+                .getDataChildByName(contAdded1);
         assertNotNull(contAdded1Node);
-        ListSchemaNode list1Node = (ListSchemaNode) contAdded1Node.getDataChildByName(list1);
+        ListSchemaNode list1Node = (ListSchemaNode) contAdded1Node
+                .getDataChildByName(list1);
         assertNotNull(list1Node);
 
-        ContainerSchemaNode contAdded2Node = (ContainerSchemaNode) targetContNode.getDataChildByName(contAdded2);
+        ContainerSchemaNode contAdded2Node = (ContainerSchemaNode) targetContNode
+                .getDataChildByName(contAdded2);
         assertNotNull(contAdded2Node);
-        AnyXmlSchemaNode axmlNode = (AnyXmlSchemaNode) contAdded2Node.getDataChildByName(axml);
+        AnyXmlSchemaNode axmlNode = (AnyXmlSchemaNode) contAdded2Node
+                .getDataChildByName(axml);
         assertNotNull(axmlNode);
 
-        ContainerSchemaNode contGrpNode = (ContainerSchemaNode) targetContNode.getDataChildByName(contGrp);
+        ContainerSchemaNode contGrpNode = (ContainerSchemaNode) targetContNode
+                .getDataChildByName(contGrp);
         assertNotNull(contGrpNode);
-        AnyXmlSchemaNode axmlGrpNode = (AnyXmlSchemaNode) contGrpNode.getDataChildByName(axmlGrp);
+        AnyXmlSchemaNode axmlGrpNode = (AnyXmlSchemaNode) contGrpNode
+                .getDataChildByName(axmlGrp);
         assertNotNull(axmlGrpNode);
+
+        ContainerSchemaNode augCont1Node = (ContainerSchemaNode) root
+                .getDataChildByName(augCont1);
+        ContainerSchemaNode augCont2Node = (ContainerSchemaNode) augCont1Node
+                .getDataChildByName(augCont2);
+        assertNotNull(augCont2Node);
+
+        ContainerSchemaNode grpCont2Node = (ContainerSchemaNode) augCont2Node
+                .getDataChildByName(grpCont2);
+        ContainerSchemaNode grpCont22Node = (ContainerSchemaNode) grpCont2Node
+                .getDataChildByName(grpCont22);
+        assertNotNull(grpCont22Node);
+
+        ContainerSchemaNode grpAddNode = (ContainerSchemaNode) grpCont22Node
+                .getDataChildByName(grpAdd);
+        assertNotNull(grpAddNode);
+    }
+
+    private <T extends ModelStatement> T findInStatements(QName target,
+            ImmutableList<T> statements) {
+
+        for (final T statement : statements) {
+            if (target
+                    .equals(statement.statementDefinition().getArgumentName())) {
+                return statement;
+            }
+        }
+
+        return null;
     }
 
-    private void addSources(CrossSourceStatementReactor.BuildAction reactor, StatementStreamSource... sources) {
+    private void addSources(CrossSourceStatementReactor.BuildAction reactor,
+            StatementStreamSource... sources) {
         for (StatementStreamSource source : sources) {
             reactor.addSource(source);
         }
similarity index 50%
rename from yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/augment/AugmentTest.java
rename to yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentTest.java
index 85308f284130cf8aac27560ad2d3cd9483d0a1f1..8e9399d443ceeddbf48f6cdc1b92c6eee22918f9 100644 (file)
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.yangtools.yang.stmt.test.augment;
+package org.opendaylight.yangtools.yang.stmt.test;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -18,93 +18,36 @@ import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor.BuildAction;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
 
 public class AugmentTest {
 
-    private static final TestAugmentSource IMPORTED = new TestAugmentSource("imp", "/a");
-    private static final TestAugmentSource VALID_ABS = new TestAugmentSource("root", "/aug1/aug11/aug111");
-    private static final TestAugmentSource VALID_ABS_PREFIXED = new TestAugmentSource("root",
-            "/imp:aug1/imp:aug11/imp:aug111", "imp");
-    private static final TestAugmentSource VALID_REL = new TestAugmentSource("root", "aug1/aug11");
-    private static final TestAugmentSource VALID_REL_PREFIXED = new TestAugmentSource("root",
-            "imp:aug1/imp:aug11/imp:aug111", "imp");
-    private static final TestAugmentSource INVALID_REL_WHITE_SPACE = new TestAugmentSource("root", "..   /aug1/aug11");
-    private static final TestAugmentSource INVALID_REL1 = new TestAugmentSource("root", "./aug1/aug11");
-    private static final TestAugmentSource INVALID_REL2 = new TestAugmentSource("root", "../aug1/aug11");
-    private static final TestAugmentSource INVALID_ABS = new TestAugmentSource("root", "//aug1/aug11/aug111");
-    private static final TestAugmentSource INVALID_ABS_PREFIXED_NO_IMP = new TestAugmentSource("root",
-            "imp:aug1/imp:aug11/imp:aug111");
-    private static final TestAugmentSource INVALID_EMPTY = new TestAugmentSource("root", "");
-    private static final TestAugmentSource INVALID_XPATH = new TestAugmentSource("root", "/aug1/-");
+    private static final YangStatementSourceImpl IMPORTED = new YangStatementSourceImpl(
+            "/semantic-statement-parser/augment-arg-parsing/imported.yang");
+
+    private static YangStatementSourceImpl VALID_ARGS = new YangStatementSourceImpl(
+            "/semantic-statement-parser/augment-arg-parsing/root-valid-aug-args.yang");
+    private static YangStatementSourceImpl INVALID_REL1 = new YangStatementSourceImpl(
+            "/semantic-statement-parser/augment-arg-parsing/root-invalid-rel1.yang");
+    private static YangStatementSourceImpl INVALID_REL2 = new YangStatementSourceImpl(
+            "/semantic-statement-parser/augment-arg-parsing/root-invalid-rel2.yang");
+    private static YangStatementSourceImpl INVALID_ABS = new YangStatementSourceImpl(
+            "/semantic-statement-parser/augment-arg-parsing/root-invalid-abs.yang");
+    private static YangStatementSourceImpl INVALID_ABS_PREFIXED_NO_IMP = new YangStatementSourceImpl(
+            "/semantic-statement-parser/augment-arg-parsing/root-invalid-abs-no-imp.yang");
+    private static YangStatementSourceImpl INVALID_EMPTY = new YangStatementSourceImpl(
+            "/semantic-statement-parser/augment-arg-parsing/root-invalid-empty.yang");
+    private static YangStatementSourceImpl INVALID_XPATH = new YangStatementSourceImpl(
+            "/semantic-statement-parser/augment-arg-parsing/root-invalid-xpath.yang");
 
     @Test
     public void validAugAbsTest() throws SourceException, ReactorException {
 
         BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        addSources(reactor, VALID_ABS);
+        addSources(reactor, IMPORTED, VALID_ARGS);
 
-        try {
-            reactor.build();
-        } catch (Exception e) {
-            // if augment argument is correct we only catch an exception that it cannot be found in mock model
-            assertEquals(NullPointerException.class, e.getClass());
-        }
-    }
-
-    @Test
-    public void validAugAbsPrefixedTest() throws SourceException, ReactorException {
-
-        BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        addSources(reactor, IMPORTED, VALID_ABS_PREFIXED);
-
-        try {
-            reactor.build();
-        } catch (Exception e) {
-            // if augment argument is correct we only catch an exception that it cannot be found in mock model
-            assertEquals(NullPointerException.class, e.getClass());
-        }
-    }
-
-    @Test
-    public void validAugRelTest() throws SourceException, ReactorException {
-
-        BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        addSources(reactor, VALID_REL);
-
-        try {
-            reactor.build();
-        } catch (Exception e) {
-            // if augment argument is correct we only catch an exception that it cannot be found in mock model
-            assertEquals(NullPointerException.class, e.getClass());
-        }
-    }
-
-    @Test
-    public void validAugRelPrefixedTest() throws SourceException, ReactorException {
-
-        BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        addSources(reactor, IMPORTED, VALID_REL_PREFIXED);
-
-        try {
-            reactor.build();
-        } catch (Exception e) {
-            // if augment argument is correct we only catch an exception that it cannot be found in mock model
-            assertEquals(NullPointerException.class, e.getClass());
-        }
-    }
-
-    @Test
-    public void validAugRelWhiteSpaceTest() throws SourceException, ReactorException {
-
-        BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        addSources(reactor, INVALID_REL_WHITE_SPACE);
-
-        try {
-            reactor.build();
-            fail("reactor.process should fail due to invalid relative path");
-        } catch (Exception e) {
-            assertEquals(IllegalArgumentException.class, e.getClass());
-        }
+        final EffectiveModelContext result = reactor.build();
+        assertNotNull(result);
     }
 
     @Test
@@ -191,10 +134,9 @@ public class AugmentTest {
         }
     }
 
-    private void addSources(BuildAction reactor, TestAugmentSource... sources) {
-        for (TestAugmentSource source : sources) {
+    private void addSources(BuildAction reactor, YangStatementSourceImpl... sources) {
+        for (YangStatementSourceImpl source : sources) {
             reactor.addSource(source);
         }
     }
-
 }
index cfdc863d2cbaca2a036cc408ed22ad2dcdfe79b9..a301f322fc5e50d85b5f79516261ba8fe04bbcb4 100644 (file)
@@ -22,6 +22,8 @@ import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
 
 class ImportBasicTestStatementSource implements StatementStreamSource {
 
@@ -157,6 +159,4 @@ class ImportBasicTestStatementSource implements StatementStreamSource {
         writer.endStatement(REF);
         return this;
     }
-
-
 }
similarity index 64%
rename from yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/key/KeyTest.java
rename to yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/KeyTest.java
index 0a1569a09424a7118c4cff51160721b544af40ae..d0ef8c2fe3d0e87c333db4b8fc902f009b422129 100644 (file)
@@ -6,7 +6,11 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.yangtools.yang.stmt.test.key;
+package org.opendaylight.yangtools.yang.stmt.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
 
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
@@ -14,30 +18,20 @@ import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor.BuildAction;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
-
-import static org.junit.Assert.*;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
 
 public class KeyTest {
 
-    private static final TestKeySource KEY_SIMPLE = new TestKeySource("root", "key");
-    private static final TestKeySource KEY_COMP = new TestKeySource("root", "key1 key2 key3");
-    private static final TestKeySource KEY_COMP_DUPLICATE = new TestKeySource("root", "key1 key1 key2");
+    private static final YangStatementSourceImpl KEY_SIMPLE_AND_COMP = new YangStatementSourceImpl(
+            "/semantic-statement-parser/key-arg-parsing/key-simple-and-comp.yang");
+    private static final YangStatementSourceImpl KEY_COMP_DUPLICATE = new YangStatementSourceImpl(
+            "/semantic-statement-parser/key-arg-parsing/key-comp-duplicate.yang");
 
     @Test
     public void keySimpleTest() throws SourceException, ReactorException {
 
         BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        addSources(reactor, KEY_SIMPLE);
-
-        EffectiveModelContext result = reactor.build();
-        assertNotNull(result);
-    }
-
-    @Test
-    public void keyCompositeTest() throws SourceException, ReactorException {
-
-        BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        addSources(reactor, KEY_COMP);
+        addSources(reactor, KEY_SIMPLE_AND_COMP);
 
         EffectiveModelContext result = reactor.build();
         assertNotNull(result);
@@ -57,8 +51,8 @@ public class KeyTest {
         }
     }
 
-    private void addSources(BuildAction reactor, TestKeySource... sources) {
-        for (TestKeySource source : sources) {
+    private void addSources(BuildAction reactor, YangStatementSourceImpl... sources) {
+        for (YangStatementSourceImpl source : sources) {
             reactor.addSource(source);
         }
     }
index ee2b10a22209a22dceb8b1a0c103d359a2d8274e..967ec3f1800cb4d217a02e5cc3e824023d0a3ab2 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -15,49 +15,45 @@ import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementR
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
-
 import static org.junit.Assert.assertNotNull;
 
 public class YangFileStmtTest {
-        private static final YangStatementSourceImpl YANGFILE = new YangStatementSourceImpl("/semantic-statement-parser/test.yang");
-        private static final YangStatementSourceImpl IMPORTEDYANGFILE = new YangStatementSourceImpl("/semantic-statement-parser/importedtest.yang");
-        private static final YangStatementSourceImpl SIMPLENODES = new YangStatementSourceImpl("/semantic-statement-parser/simple-nodes-semantic.yang");
-        private static final YangStatementSourceImpl FOO = new YangStatementSourceImpl("/semantic-statement-parser/foo.yang");
-        private static final YangStatementSourceImpl FILE1 = new YangStatementSourceImpl("/model/bar.yang");
-        private static final YangStatementSourceImpl FILE2 = new YangStatementSourceImpl("/model/baz.yang");
-        private static final YangStatementSourceImpl FILE3 = new YangStatementSourceImpl("/model/foo.yang");
-        private static final YangStatementSourceImpl FILE4 = new YangStatementSourceImpl("/model/subfoo.yang");
-        private static final YangStatementSourceImpl EXTFILE = new YangStatementSourceImpl("/semantic-statement-parser/ext-typedef.yang");
-        private static final YangStatementSourceImpl EXTUSE = new YangStatementSourceImpl("/semantic-statement-parser/ext-use.yang");
-
-        @Test
-        public void readAndParseYangFileTest1() throws SourceException, ReactorException {
-                CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-                addSources(reactor, YANGFILE, SIMPLENODES, IMPORTEDYANGFILE, FOO);
-                EffectiveModelContext result = reactor.build();
-                assertNotNull(result);
-        }
+    //basic statements to parse and write
+    private static final YangStatementSourceImpl YANGFILE = new YangStatementSourceImpl("/semantic-statement-parser/test.yang");
+    private static final YangStatementSourceImpl IMPORTEDYANGFILE = new YangStatementSourceImpl("/semantic-statement-parser/importedtest.yang");
+    private static final YangStatementSourceImpl SIMPLENODES = new YangStatementSourceImpl("/semantic-statement-parser/simple-nodes-semantic.yang");
+    private static final YangStatementSourceImpl FOOBAR = new YangStatementSourceImpl("/semantic-statement-parser/foobar.yang");
+    //extension statement to parse and write
+    private static final YangStatementSourceImpl EXTFILE = new YangStatementSourceImpl("/semantic-statement-parser/ext-typedef.yang");
+    private static final YangStatementSourceImpl EXTUSE = new YangStatementSourceImpl("/semantic-statement-parser/ext-use.yang");
 
-        // TODO uncomment when Augment in Uses implemented
-//        @Test
-//        public void readAndParseYangFileTest2() throws SourceException, ReactorException {
-//                CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-//                addSources(reactor, FILE1, FILE2, FILE3, FILE4);
-//                EffectiveModelContext result = reactor.build();
-//                assertNotNull(result);
-//        }
-
-        @Test
-        public void readAndParseYangFileTest3() throws SourceException, ReactorException {
-                CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-                addSources(reactor, EXTFILE, EXTUSE);
-                EffectiveModelContext result = reactor.build();
-                assertNotNull(result);
-        }
 
-        private void addSources(CrossSourceStatementReactor.BuildAction reactor, StatementStreamSource... sources) {
-                for (StatementStreamSource source : sources) {
-                        reactor.addSource(source);
-                }
+    private static final YangStatementSourceImpl BAR = new YangStatementSourceImpl("/model-new/bar.yang");
+    private static final YangStatementSourceImpl BAZ = new YangStatementSourceImpl("/model-new/baz.yang");
+    private static final YangStatementSourceImpl FOO = new YangStatementSourceImpl("/model-new/foo.yang");
+    private static final YangStatementSourceImpl SUBFOO = new YangStatementSourceImpl("/model-new/subfoo.yang");
+
+    @Test
+    public void readAndParseYangFileTestModel() throws SourceException, ReactorException {
+        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
+
+        addSources(reactor, BAZ,FOO,BAR,SUBFOO);
+        EffectiveModelContext result = reactor.build();
+        assertNotNull(result);
+    }
+
+    @Test
+    public void readAndParseYangFileTest() throws SourceException, ReactorException {
+        CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
+        addSources(reactor, YANGFILE, SIMPLENODES, IMPORTEDYANGFILE, FOOBAR);
+        addSources(reactor, EXTFILE, EXTUSE);
+        EffectiveModelContext result = reactor.build();
+        assertNotNull(result);
+    }
+
+    private void addSources(CrossSourceStatementReactor.BuildAction reactor, StatementStreamSource... sources) {
+        for (StatementStreamSource source : sources) {
+            reactor.addSource(source);
         }
+    }
 }
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/augment/TestAugmentSource.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/augment/TestAugmentSource.java
deleted file mode 100644 (file)
index 6019009..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-package org.opendaylight.yangtools.yang.stmt.test.augment;
-
-import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.AUGMENT;
-import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.IMPORT;
-import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.MODULE;
-import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.NAMESPACE;
-import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.PREFIX;
-
-import java.util.Arrays;
-
-import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
-import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
-import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
-import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
-import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter;
-
-public class TestAugmentSource implements StatementStreamSource {
-
-    private static final String NS_PREFIX = "urn:org:opendaylight:yangtools:test:";
-
-    private final String name;
-    private final String augment;
-    private final java.util.List<String> imports;
-    private StatementWriter writer;
-    private StatementSourceReference REF = new StatementSourceReference() {
-
-        @Override
-        public StatementSource getStatementSource() {
-            return StatementSource.DECLARATION;
-        }
-    };
-
-    public TestAugmentSource(String name, String augment, String... imports) {
-        this.name = name;
-        this.augment = augment;
-        this.imports = Arrays.asList(imports);
-    }
-
-    @Override
-    public void writeFull(StatementWriter writer, QNameToStatementDefinition stmtDef, PrefixToModule prefixes)
-            throws SourceException {
-        this.writer = writer;
-        header();
-        extensions();
-        body();
-        end();
-    }
-
-    @Override
-    public void writeLinkage(StatementWriter writer, QNameToStatementDefinition stmtDef) throws SourceException {
-        this.writer = writer;
-        header().end();
-    }
-
-    @Override
-    public void writeLinkageAndStatementDefinitions(StatementWriter writer, QNameToStatementDefinition stmtDef,
-                                                    PrefixToModule prefixes) throws SourceException {
-        this.writer = writer;
-        header();
-        extensions();
-        end();
-    }
-
-    protected void extensions() throws SourceException {
-
-    }
-
-    protected void body() throws SourceException {
-
-        stmt(AUGMENT).arg(augment);
-        end();
-    }
-
-    TestAugmentSource header() throws SourceException {
-
-        stmt(MODULE).arg(name);
-        {
-            stmt(NAMESPACE).arg(getNamespace()).end();
-            stmt(PREFIX).arg(name).end();
-        }
-
-        for (String impEntry : imports) {
-
-            stmt(IMPORT).arg(impEntry);
-            {
-                stmt(PREFIX).arg(impEntry).end();
-            }
-            end();
-        }
-
-        return this;
-    }
-
-    private String getNamespace() {
-        return NS_PREFIX + name;
-    }
-
-    protected TestAugmentSource arg(String arg) throws SourceException {
-        writer.argumentValue(arg, REF);
-        return this;
-    }
-
-    protected TestAugmentSource stmt(Rfc6020Mapping stmt) throws SourceException {
-        writer.startStatement(stmt.getStatementName(), REF);
-        return this;
-    }
-
-    protected TestAugmentSource end() throws SourceException {
-        writer.endStatement(REF);
-        return this;
-    }
-}
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/key/TestKeySource.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/key/TestKeySource.java
deleted file mode 100644 (file)
index fea5430..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.opendaylight.yangtools.yang.stmt.test.key;
-
-import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.KEY;
-import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.MODULE;
-import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.NAMESPACE;
-import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.PREFIX;
-
-import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
-import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
-import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
-import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
-import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter;
-
-public class TestKeySource implements StatementStreamSource {
-
-    private static final String NS_PREFIX = "urn:org:opendaylight:yangtools:test:";
-
-    private final String name;
-    private final String key;
-    private StatementWriter writer;
-    private StatementSourceReference REF = new StatementSourceReference() {
-
-        @Override
-        public StatementSource getStatementSource() {
-            return StatementSource.DECLARATION;
-        }
-    };
-
-    public TestKeySource(String name, String key) {
-        this.name = name;
-        this.key = key;
-    }
-
-    @Override
-    public void writeFull(StatementWriter writer, QNameToStatementDefinition stmtDef, PrefixToModule prefixes)
-            throws SourceException {
-
-        this.writer = writer;
-
-        header();
-        extensions();
-        body();
-        end();
-    }
-
-    @Override
-    public void writeLinkage(StatementWriter writer, QNameToStatementDefinition stmtDef) throws SourceException {
-        this.writer = writer;
-        header().end();
-    }
-
-    @Override
-    public void writeLinkageAndStatementDefinitions(StatementWriter writer, QNameToStatementDefinition stmtDef,
-            PrefixToModule prefixes) throws SourceException {
-        this.writer = writer;
-        header();
-        extensions();
-        end();
-    }
-
-    protected void extensions() throws SourceException {
-
-    }
-
-    protected void body() throws SourceException {
-
-        stmt(Rfc6020Mapping.LIST).arg("lst");
-        {
-            stmt(KEY).arg(key).end();
-        }
-        end();
-    }
-
-    TestKeySource header() throws SourceException {
-
-        stmt(MODULE).arg(name);
-        {
-            stmt(NAMESPACE).arg(getNamespace()).end();
-            stmt(PREFIX).arg(name).end();
-        }
-
-        return this;
-    }
-
-    private String getNamespace() {
-        return NS_PREFIX + name;
-    }
-
-    protected TestKeySource arg(String arg) throws SourceException {
-        writer.argumentValue(arg, REF);
-        return this;
-    }
-
-    protected TestKeySource stmt(Rfc6020Mapping stmt) throws SourceException {
-        writer.startStatement(stmt.getStatementName(), REF);
-        return this;
-    }
-
-    protected TestKeySource end() throws SourceException {
-        writer.endStatement(REF);
-        return this;
-    }
-}
diff --git a/yang/yang-parser-impl/src/test/resources/model-new/bar.yang b/yang/yang-parser-impl/src/test/resources/model-new/bar.yang
new file mode 100644 (file)
index 0000000..fd0276e
--- /dev/null
@@ -0,0 +1,118 @@
+module bar {
+    yang-version 1;
+    namespace "urn:opendaylight.bar";
+    prefix "bar";
+
+    organization "opendaylight";
+    contact "http://www.opendaylight.org/";
+    description "This model define custom type definitions";
+
+    revision "2013-07-03" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    typedef int32-ext1 {
+        type int32 {
+            range "2..20";
+        }
+    }
+
+    typedef int32-ext2 {
+        type int32-ext1 {
+            range "3..9|11..max";
+        }
+        units "mile";
+        default "11";
+    }
+
+    typedef string-ext1 {
+        type string {
+            pattern "[a-k]*";
+            length "5..11";
+        }
+    }
+
+    typedef string-ext2 {
+        type string-ext1 {
+            length "6..10";
+        }
+    }
+
+    typedef string-ext3 {
+        type string-ext2 {
+            pattern "[b-u]*";
+        }
+    }
+
+    typedef string-ext4 {
+        type string-ext3 {
+            pattern "[e-z]*";
+        }
+    }
+
+    typedef invalid-string-pattern {
+        type string {
+            pattern "[[A-1*-%22!^^}";
+        }
+    }
+
+    typedef multiple-pattern-string {
+        type string {
+            pattern "[[A-1*-%22!^^}";
+            pattern "[e-z]*";
+        }
+    }
+
+    typedef my-decimal-type {
+        type decimal64 {
+            fraction-digits 6;
+        }
+    }
+
+    typedef my-union {
+        type union {
+            type int16 {
+                range "1..100";
+            }
+            type int32;
+        }
+    }
+
+    typedef my-union-ext {
+        type my-union;
+    }
+
+    typedef nested-union2 {
+        type union {
+            type my-union-ext;
+            type string;
+        }
+    }
+
+    container interfaces {
+        grouping ifEntry {
+            container augment-holder;
+        }
+        list ifEntry {
+            key "ifIndex";
+
+            leaf ifIndex {
+                type uint32;
+                units minutes;
+            }
+
+            leaf ifMtu {
+                type int32;
+            }
+
+            min-elements 1;
+            max-elements 11;
+        }
+    }
+
+    extension opendaylight {
+        argument "name" {
+            yin-element "true";
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/model-new/baz.yang b/yang/yang-parser-impl/src/test/resources/model-new/baz.yang
new file mode 100644 (file)
index 0000000..862b1eb
--- /dev/null
@@ -0,0 +1,189 @@
+module baz {
+    yang-version 1;
+    namespace "urn:opendaylight.baz";
+    prefix "baz";
+
+    import bar { prefix "br"; revision-date 2013-07-03; }
+
+    organization "opendaylight";
+    contact "http://www.opendaylight.org/";
+
+    revision "2013-02-27" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    typedef union1 {
+        type union2;
+    }
+
+    typedef union2 {
+        type union {
+            type int32;
+            type br:nested-union2;
+        }
+    }
+
+    augment "/br:interfaces/br:ifEntry" {
+        when "if:ifType='ds0'";
+        container augment-holder {
+            description "Description for augment holder";
+        }
+    }
+
+    augment "/br:interfaces/br:ifEntry" {
+        when "if:ifType='ds2'";
+        container augment-holder2 {
+            description "Description for augment holder";
+        }
+    }
+
+    container network {
+        c-define point {
+        }
+
+        description "network-description";
+        reference "network-reference";
+        status obsolete;
+        config true;
+        presence "some presence text";
+    }
+
+    feature local-storage {
+        description
+                "This feature means the device supports local storage (memory,
+                flash or disk) that can be used to store syslog messages.";
+    }
+
+    extension c-define {
+        description "Takes as argument a name string. Makes the code generator use
+                the given name in the #define.";
+        argument "name" {
+            yin-element "true";
+        }
+    }
+
+    notification event {
+        leaf event-class {
+            type string;
+        }
+        anyxml reporting-entity;
+        leaf severity {
+            type string;
+        }
+    }
+
+    rpc get-config {
+        description "Retrieve all or part of a specified configuration.";
+        reference "RFC 6241, Section 7.1";
+
+        input {
+            container source {
+                description
+                                "Particular configuration to retrieve.";
+
+                choice config-source {
+                    mandatory true;
+                    description
+                                        "The configuration to retrieve.";
+                    case a {
+                        leaf candidate {
+                            if-feature candidate;
+                            type empty;
+                            description
+                                                        "The candidate configuration is the config source.";
+                        }
+                    }
+                    case b {
+                        leaf running {
+                            type empty;
+                            description
+                                                        "The running configuration is the config source.";
+                        }
+                    }
+                    case c {
+                        leaf startup {
+                            if-feature startup;
+                            type empty;
+                            description
+                                                        "The startup configuration is the config source. This is optional-to-implement
+                                                        on the server because not all servers will support filtering for
+                                                        this datastore.";
+                        }
+                    }
+                }
+            }
+
+            anyxml filter {
+                description "Subtree or XPath filter to use.";
+                baz:c-define element-attributes;
+            }
+        }
+
+        output {
+            anyxml data {
+                description
+                                "Copy of the source datastore subset that matched the filter criteria
+                                (if any). An empty data container indicates that the request did
+                                not produce any results.";
+            }
+        }
+    }
+
+    grouping target {
+        anyxml data {
+            config true;
+            description "Copy of the source datastore subset.";
+            mandatory false;
+            must "test-condition-text";
+            reference "test-no-reference";
+            status "obsolete";
+            when "test-when-text";
+        }
+        choice how {
+            description "test choice description";
+            default interval;
+            case interval {
+                leaf interval {
+                    type uint16;
+                    default 30;
+                    units minutes;
+                }
+            }
+            case daily {
+                leaf daily {
+                    type empty;
+                }
+                leaf time-of-day {
+                    type string;
+                    units 24-hour-clock;
+                    default 1am;
+                }
+            }
+        }
+        leaf address {
+            type string;
+            description "Target IP address";
+            mandatory true;
+        }
+        container port {
+            description "Target port container";
+        }
+        list addresses {
+            key "id";
+            leaf id {
+                type int8;
+            }
+        }
+        grouping target-inner {
+            description "target-inner default description";
+            leaf inner-grouping-id {
+                type int8;
+            }
+        }
+        typedef group-type {
+            type br:my-decimal-type;
+        }
+
+        br:opendaylight;
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/model-new/foo.yang b/yang/yang-parser-impl/src/test/resources/model-new/foo.yang
new file mode 100644 (file)
index 0000000..7b820cc
--- /dev/null
@@ -0,0 +1,228 @@
+module foo {
+    yang-version 1;
+    namespace "urn:opendaylight.foo";
+    prefix "foo";
+
+    import bar { prefix "br"; revision-date 2013-07-03; }
+
+    import baz { prefix "bz"; revision-date 2013-02-27; }
+
+    include subfoo {
+        revision-date "2013-02-27";
+    }
+
+    organization "opendaylight";
+    contact "http://www.opendaylight.org/";
+
+    revision "2013-02-27" {
+        reference " WILL BE DEFINED LATER";
+    }
+
+    typedef identifier {
+        type int32;
+    }
+
+    leaf int32-leaf {
+        type br:int32-ext2 {
+            range "12..max";
+        }
+    }
+
+    leaf string-leaf {
+        type br:string-ext4;
+    }
+
+    leaf invalid-pattern-string-leaf {
+        type br:invalid-string-pattern;
+    }
+
+    leaf invalid-direct-string-pattern-def-leaf {
+        type string {
+            pattern "[[A-1*-%22!^^}";
+        }
+    }
+
+    leaf multiple-pattern-string-leaf {
+        type br:multiple-pattern-string;
+    }
+
+    leaf multiple-pattern-direct-string-def-leaf {
+        type string {
+            pattern "[e-z]*";
+            pattern "[[A-1*-%22!^^}";
+            pattern "[a-d]*";
+        }
+    }
+
+    leaf length-leaf {
+        type br:string-ext2 {
+            length "7..max";
+        }
+    }
+
+    leaf decimal-leaf {
+        type br:my-decimal-type {
+            fraction-digits 4;
+        }
+    }
+
+    leaf decimal-leaf2 {
+        type br:my-decimal-type;
+    }
+
+    container ext {
+        bz:c-define "MY_INTERFACES";
+    }
+
+    leaf union-leaf {
+        type br:my-union-ext;
+    }
+
+    deviation /br:interfaces/br:ifEntry {
+        deviate add {
+            default "admin";
+            config "true";
+        }
+        reference "system/user ref";
+    }
+
+    leaf custom-union-leaf {
+        type bz:union1;
+    }
+
+    container transfer {
+        choice how {
+            default interval;
+            container input {
+            }
+            list output {
+                leaf id {
+                    type string;
+                }
+            }
+            case interval {
+                leaf interval {
+                    type uint16;
+                    default 30;
+                    units minutes;
+                }
+            }
+            case daily {
+                leaf daily {
+                    type empty;
+                }
+                leaf time-of-day {
+                    type string;
+                    units 24-hour-clock;
+                    default 1am;
+                }
+            }
+            case manual {
+                leaf manual {
+                    type empty;
+                }
+            }
+        }
+    }
+
+    anyxml datas {
+        description
+                "Copy of the source typesstore subset that matched the filter
+                criteria (if any). An empty types container indicates that the
+                request did not produce any results.";
+        status obsolete;
+    }
+
+    augment "/br:interfaces/br:ifEntry/br:augment-holder" {
+        when "if:ifType='ds0'";
+        leaf ds0ChannelNumber {
+            type string;
+        }
+        leaf interface-id {
+            type leafref {
+                path "/if:interfaces/if:interface/if:name";
+            }
+        }
+        leaf my-type {
+            type br:int32-ext2;
+        }
+        container schemas {
+        }
+        choice odl {
+            leaf id {
+                type int8;
+            }
+            case node1 {
+                description "node1";
+            }
+            case node2 {
+                description "node2";
+            }
+            container node3 {
+                description "node3";
+            }
+        }
+    }
+
+    container mycont {
+        container innercont {
+            typedef mytype {
+                type string;
+            }
+            leaf myleaf {
+                type mytype;
+            }
+        }
+    }
+
+    uses bz:target {
+        augment "how/interval" {
+            description "inner augment";
+            leaf name {
+                type string;
+            }
+        }
+    }
+
+    container peer {
+        container destination {
+            uses bz:target {
+                refine address {
+                    default "1.2.3.4";
+                    description "IP address of target node";
+                    reference "address reference added by refine";
+                    config false;
+                    mandatory false;
+                    must "ifType != 'ethernet' or " +
+                                        "(ifType = 'ethernet' and ifMTU = 1500)" {
+                        error-message "An ethernet MTU must be 1500";
+                    }
+                    mountpoint "mnt-extension";
+                }
+                refine port {
+                    description "description of port defined by refine";
+                    reference "port reference added by refine";
+                    config false;
+                    presence "presence is required";
+                }
+                refine "addresses" {
+                    description "description of addresses defined by refine";
+                    reference "addresses reference added by refine";
+                    config false;
+                    min-elements 2;
+                    max-elements unbounded;
+                }
+                refine addresses/id {
+                    description "id of address";
+                }
+            }
+        }
+    }
+
+    extension mountpoint {
+        description "enter point";
+        argument "name" {
+            yin-element "true";
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/model-new/subfoo.yang b/yang/yang-parser-impl/src/test/resources/model-new/subfoo.yang
new file mode 100644 (file)
index 0000000..1900530
--- /dev/null
@@ -0,0 +1,70 @@
+submodule subfoo {
+    yang-version 1;
+
+    belongs-to foo {
+        prefix f;
+    }
+
+    import bar {
+        prefix "br";
+        revision-date 2013-07-03;
+    }
+
+    import baz {
+        prefix "bz";
+        revision-date 2013-02-27;
+    }
+
+    revision "2013-02-27" {
+    }
+
+    leaf id {
+        type br:int32-ext2 {
+            range "12..max";
+        }
+    }
+
+    leaf foo-id {
+        type f:identifier;
+    }
+
+    container sub-ext {
+        bz:c-define "MY_INTERFACES";
+    }
+
+    container sub-transfer {
+        choice how {
+            default interval;
+            container input {
+            }
+            list output {
+                leaf id {
+                    type string;
+                }
+            }
+            case manual {
+                leaf manual {
+                    type empty;
+                }
+            }
+        }
+    }
+
+    anyxml sub-datas {
+        status obsolete;
+    }
+
+    augment "/br:interfaces/br:ifEntry/br:augment-holder" {
+        when "if:ifType='ds0'";
+        leaf subleaf {
+            type string;
+        }
+    }
+
+    extension sub-mountpoint {
+        argument "name" {
+            yin-element "true";
+        }
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/imported.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/imported.yang
new file mode 100644 (file)
index 0000000..3fa44c4
--- /dev/null
@@ -0,0 +1,19 @@
+module imported {
+       namespace imp;
+       prefix imp;
+
+       container aug1 {
+        container aug11 {
+            container aug111 {
+
+            }
+        }
+    }
+
+    grouping grp {
+        container aug2 {
+            container aug22 {
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-abs-no-imp.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-abs-no-imp.yang
new file mode 100644 (file)
index 0000000..77802f4
--- /dev/null
@@ -0,0 +1,9 @@
+module root-invalid-abs-no-imp {
+       namespace root;
+       prefix root;
+
+       augment "imp:aug1/imp:aug11/imp:aug111" {
+               container add {
+               }
+       }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-abs.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-abs.yang
new file mode 100644 (file)
index 0000000..ea0ed83
--- /dev/null
@@ -0,0 +1,9 @@
+module root-invalid-abs {
+       namespace root;
+       prefix root;
+
+       augment "//aug1/aug11/aug111" {
+               container add {
+               }
+       }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-empty.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-empty.yang
new file mode 100644 (file)
index 0000000..6d46632
--- /dev/null
@@ -0,0 +1,9 @@
+module root-invalid-empty {
+       namespace root;
+       prefix root;
+
+       augment "" {
+               container add {
+               }
+       }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-rel1.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-rel1.yang
new file mode 100644 (file)
index 0000000..a35f83f
--- /dev/null
@@ -0,0 +1,9 @@
+module root-invalid-rel1 {
+       namespace root;
+       prefix root;
+
+       augment "./aug1/aug11" {
+               container add {
+               }
+       }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-rel2.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-rel2.yang
new file mode 100644 (file)
index 0000000..2c8d32a
--- /dev/null
@@ -0,0 +1,9 @@
+module root-invalid-rel2 {
+       namespace root;
+       prefix root;
+
+       augment "../aug1/aug11" {
+               container add {
+               }
+       }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-xpath.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-invalid-xpath.yang
new file mode 100644 (file)
index 0000000..2a8e82c
--- /dev/null
@@ -0,0 +1,9 @@
+module root-invalid-xpath {
+       namespace root;
+       prefix root;
+
+       augment "/aug1/-" {
+               container add {
+               }
+       }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-valid-aug-args.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/augment-arg-parsing/root-valid-aug-args.yang
new file mode 100644 (file)
index 0000000..8683912
--- /dev/null
@@ -0,0 +1,39 @@
+module root-valid-aug-args {
+       namespace root;
+       prefix root;
+
+       import imported;
+
+       augment "/aug1/aug11/aug111" {
+               container add {
+               }
+       }
+
+       container aug1 {
+               container aug11 {
+                       container aug111 {
+
+            }
+               }
+       }
+
+    augment "/imp:aug1/imp:aug11/imp:aug111" {
+        container add {
+        }
+    }
+
+       grouping grp {
+               container aug2 {
+                       container aug22 {
+                       }
+               }
+       }
+
+       uses grp {
+
+               augment "aug2/aug22" {
+                       container add {
+                       }
+               }
+       }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/effective-module/imported.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/effective-module/imported.yang
new file mode 100644 (file)
index 0000000..3059998
--- /dev/null
@@ -0,0 +1,6 @@
+module imported {
+       namespace imported;
+       prefix imported;
+
+       revision "2000-01-01";
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/effective-module/root.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/effective-module/root.yang
new file mode 100644 (file)
index 0000000..4f07856
--- /dev/null
@@ -0,0 +1,45 @@
+module root {
+       namespace root-ns;
+       prefix root-pref;
+
+       yang-version 1;
+       organization "kisko";
+       contact "kisko email";
+
+       import imported {
+               prefix imp-pref;
+               revision "2000-01-01";
+       }
+       include submod;
+
+       container cont {
+       }
+
+       augment "/cont" {
+               container cont-aug {
+               }
+       }
+
+       notification notif1 {
+       }
+
+       rpc rpc1 {
+       }
+
+       deviation /cont {
+               deviate add {
+                       container subcont{
+                       }
+               }
+               reference "deviate reference";
+       }
+
+       identity identity1 {
+       }
+
+       feature feature1 {
+       }
+
+       extension ext1 {
+       }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/effective-module/submod.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/effective-module/submod.yang
new file mode 100644 (file)
index 0000000..be060f8
--- /dev/null
@@ -0,0 +1,6 @@
+submodule submod {
+       belongs-to "root" {
+               prefix root;
+       }
+       revision "2000-01-01";
+}
\ No newline at end of file
similarity index 87%
rename from yang/yang-parser-impl/src/test/resources/semantic-statement-parser/foo.yang
rename to yang/yang-parser-impl/src/test/resources/semantic-statement-parser/foobar.yang
index 6854e33aac2adcda9e0ab2ca7f20be39d242db6d..6870055629f5c491d390d786c8a7de0b0bcf19d2 100644 (file)
@@ -1,7 +1,7 @@
-module foo {
+module foobar {
     yang-version 1;
-    namespace "urn:opendaylight.foo";
-    prefix "foo";
+    namespace "urn:opendaylight.foobar";
+    prefix "foobar";
 
     revision "2015-07-08" {
     }
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/key-arg-parsing/key-comp-duplicate.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/key-arg-parsing/key-comp-duplicate.yang
new file mode 100644 (file)
index 0000000..e56e1f7
--- /dev/null
@@ -0,0 +1,14 @@
+module key-comp-duplicate {
+       namespace root;
+       prefix root;
+
+       list comp {
+               key "key1 key2 key2";
+               container key1 {
+        }
+               container key2 {
+        }
+               container key3 {
+        }
+       }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/key-arg-parsing/key-simple-and-comp.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/key-arg-parsing/key-simple-and-comp.yang
new file mode 100644 (file)
index 0000000..86ce815
--- /dev/null
@@ -0,0 +1,20 @@
+module key-simple-and-comp {
+       namespace root;
+       prefix root;
+
+       list simple {
+               key "key1";
+               container key1 {
+               }
+       }
+
+       list comp {
+               key "key1 key2 key3";
+               container key1 {
+        }
+               container key2 {
+        }
+               container key3 {
+        }
+       }
+}
\ No newline at end of file
index dcc8578ad3838b3b2bd336f0fdbd9308456bd2d5..247aceb56512987dff3cf111b2d31e4a6a1510c0 100644 (file)
@@ -29,7 +29,7 @@ module simple-nodes {
 
 
     anyxml data {
-        config false;
+         config false;
          description "anyxml desc";
          if-feature has-name;
          mandatory true;
diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/augments/aug-root.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/augments/aug-root.yang
new file mode 100644 (file)
index 0000000..42ced8d
--- /dev/null
@@ -0,0 +1,37 @@
+module aug-root {
+    namespace root;
+    prefix root;
+
+    import augmented { prefix aug; }
+
+    augment "/aug:aug-parent1/aug:aug-parent2/aug:cont-target" {
+        container cont-added1 {
+            list list1 {
+            }
+        }
+
+        container cont-added2 {
+            anyxml axml;
+        }
+
+        uses aug:grp;
+    }
+
+    grouping grp2 {
+        container grp-cont2 {
+            container grp-cont22 {
+            }
+        }
+    }
+
+    container aug-cont1 {
+        container aug-cont2 {
+            uses grp2 {
+                augment "grp-cont2/grp-cont22" {
+                    container grp-add {
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/augments/augmented.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/augments/augmented.yang
new file mode 100644 (file)
index 0000000..6ff2422
--- /dev/null
@@ -0,0 +1,17 @@
+module augmented {
+    namespace aug;
+    prefix aug;
+
+    container aug-parent1 {
+        container aug-parent2 {
+            container cont-target {
+            }
+        }
+    }
+
+    grouping grp {
+        container cont-grp {
+            anyxml axml-grp;
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-imported.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-imported.yang
new file mode 100644 (file)
index 0000000..0d030b2
--- /dev/null
@@ -0,0 +1,60 @@
+module multiple-augment-imported {
+
+    namespace "multiple-augment-imported";
+    prefix imp;
+
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-in-uses-augment/sub-container-from-augment2/sub-container-from-augment3 {
+        container sub-container-from-augment4 {
+        }
+    }
+
+    container root-container {
+        uses grp1 {
+            augment container-from-grp1/sub-container-from-grp1 {
+                container container-in-uses-augment {
+                }
+            }
+        }
+    }
+
+    grouping grp1 {
+        container container-from-grp1 {
+            container sub-container-from-grp1 {
+                uses grp2 {
+                    augment container-from-grp2/sub-container-from-grp2 {
+                        container augmented-container-in-uses-grp2;
+                    }
+                }
+            }
+        }
+    }
+
+    augment /root-container/added-container-1 {
+        container added-container-2 {
+        }
+    }
+
+    grouping grp2 {
+        container container-from-grp2 {
+            container sub-container-from-grp2 {
+            }
+        }
+        uses grp3;
+    }
+
+    grouping grp3 {
+        container container-from-grp3 {
+        }
+    }
+
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-in-uses-augment {
+        container sub-container-from-augment2 {
+        }
+    }
+    
+    grouping grp-from-import {
+        container container-from-grp-from-import {
+            
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-incorrect.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-incorrect.yang
new file mode 100644 (file)
index 0000000..61ad3e3
--- /dev/null
@@ -0,0 +1,80 @@
+module multiple-augment-incorrect {
+
+    namespace "multiple-augment-test";
+    prefix mpa;
+    
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-in-uses-augment/sub-container-from-augment2/sub-container-from-augment3 {
+        container sub-container-from-augment4 {
+        }
+    }
+    
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-in-uses-augment/sub-container-from-augment2 {
+        container sub-container-from-augment3 {
+        }
+    }
+
+    augment /root-container/container-from-grp1/sub-container-from-grp1 {
+        container sub-container-from-augment {
+        }
+    }
+
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-from-grp2/sub-container-from-grp2/augmented-container-in-uses-grp2 {
+        container sub-container-from-augment6 {
+        }
+    }
+    
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-from-grp2/sub-container-from-grp2/sub-container-from-augment5 {
+        container sub-container-from-augment7 {
+        }
+    }
+    
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-from-grp2/sub-container-from-grp2 {
+        container sub-container-from-augment5 {
+        }
+    }
+
+    augment /root-container/added-container-1 {
+        container added-container-2 {
+        }
+    }
+
+    augment /root-container {
+        container added-container-1 {
+        }
+    }
+
+    grouping grp1 {
+        container container-from-grp1 {
+            container sub-container-from-grp1 {
+                uses grp2 {
+                    augment container-from-grp2/sub-container-from-grp2 {
+                        container augmented-container-in-uses-grp2;
+                    }
+                }
+            }
+        }
+    }
+
+    grouping grp2 {
+        container container-from-grp2 {
+            container sub-container-from-grp2 {
+            }
+        }
+        uses grp3;
+    }
+    
+    grouping grp3 {
+      container container-from-grp3 {
+          
+      }
+    }
+    
+    container root-container {
+        uses grp1 {
+            augment container-from-grp1/sub-container-from-grp1 {
+                container container-in-uses-augment {
+                }
+            }
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-incorrect2.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-incorrect2.yang
new file mode 100644 (file)
index 0000000..c0e51c8
--- /dev/null
@@ -0,0 +1,89 @@
+module multiple-augment-incorrect2 {
+
+    namespace "multiple-augment-test";
+    prefix mpa;
+
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-in-uses-augment/sub-container-from-augment2/sub-container-from-augment3 {
+        container sub-container-from-augment4 {
+        }
+    }
+
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-in-uses-augment/sub-container-from-augment2 {
+        container sub-container-from-augment3 {
+        }
+    }
+
+    augment /root-container/container-from-grp1/sub-container-from-grp1 {
+        container sub-container-from-augment {
+        }
+    }
+
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-from-grp2/sub-container-from-grp2/augmented-container-in-uses-grp2 {
+        container sub-container-from-augment6 {
+        }
+    }
+
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-from-grp2/sub-container-from-grp2/sub-container-from-augment5 {
+        container sub-container-from-augment7 {
+        }
+    }
+
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-from-grp2/sub-container-from-grp2 {
+        container sub-container-from-augment5 {
+        }
+    }
+
+    augment /root-container/added-container-1 {
+        container added-container-2 {
+        }
+    }
+
+    augment /root-container {
+        container added-container-1 {
+        }
+    }
+
+    grouping grp1 {
+        container container-from-grp1 {
+            container sub-container-from-grp1 {
+                uses grp2 {
+                    augment container-from-grp2/sub-container-from-grp2 {
+                        container augmented-container-in-uses-grp2;
+                    }
+                }
+            }
+        }
+    }
+
+    grouping grp2 {
+        container container-from-grp2 {
+            container sub-container-from-grp2 {
+            }
+        }
+        uses grp3;
+    }
+
+    grouping grp3 {
+        container container-from-grp3 {
+        }
+    }
+
+    container root-container {
+        uses grp1 {
+            augment container-from-grp1/sub-container-from-grp1 {
+                container container-in-uses-augment {
+                }
+            }
+        }
+    }
+    
+    container container-with-incorrect-uses {
+        uses grp4 {
+            augment unknown {
+                container new {
+                    
+                }
+            }
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-root.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-root.yang
new file mode 100644 (file)
index 0000000..88123f7
--- /dev/null
@@ -0,0 +1,54 @@
+module multiple-augment-root {
+
+    namespace "multiple-augment-root";
+    prefix root;
+
+    import multiple-augment-imported { prefix imp; revision-date 1970-01-01; }
+    
+    include multiple-augment-submodule { revision-date 1970-01-01; }
+
+    augment /imp:root-container/imp:container-from-grp1/imp:sub-container-from-grp1/imp:container-in-uses-augment/imp:sub-container-from-augment2 {
+        container sub-container-from-augment3 {
+        }
+    }
+
+    augment /imp:root-container/imp:container-from-grp1/imp:sub-container-from-grp1 {
+        container sub-container-from-augment {
+        }
+    }
+
+    augment /imp:root-container/imp:container-from-grp1/imp:sub-container-from-grp1/imp:container-from-grp2/imp:sub-container-from-grp2/imp:augmented-container-in-uses-grp2 {
+        container sub-container-from-augment6 {
+        }
+    }
+
+    augment /imp:root-container/imp:container-from-grp1/imp:sub-container-from-grp1/imp:container-from-grp2/imp:sub-container-from-grp2/imp:sub-container-from-augment5 {
+        container sub-container-from-augment7 {
+        }
+    }
+
+    augment /imp:root-container/imp:container-from-grp1/imp:sub-container-from-grp1/imp:container-from-grp2/imp:sub-container-from-grp2 {
+        container sub-container-from-augment5 {
+        }
+    }
+
+    augment /imp:root-container {
+        container added-container-1 {
+        }
+    }
+    
+    container container-with-multiple-uses {
+        uses imp:grp-from-import{
+            augment container-from-grp-from-import {
+                container new {
+                }
+            }
+        }
+        uses grp-from-include{
+            augment container-from-grp-from-include {
+                container new {
+                }
+            }
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-submodule.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-submodule.yang
new file mode 100644 (file)
index 0000000..ec5b70e
--- /dev/null
@@ -0,0 +1,11 @@
+submodule multiple-augment-submodule {
+    
+    belongs-to multiple-augment-root {
+     prefix rt;   
+    }
+    
+    grouping grp-from-include{
+        container container-from-grp-from-include {
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-test.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/augments/multiple-augment-test.yang
new file mode 100644 (file)
index 0000000..7912b7d
--- /dev/null
@@ -0,0 +1,85 @@
+module multiple-augment-test {
+
+    namespace "multiple-augment-test";
+    prefix mpa;
+    
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-in-uses-augment/sub-container-from-augment2/sub-container-from-augment3 {
+        container sub-container-from-augment4 {
+        }
+    }
+    
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-in-uses-augment/sub-container-from-augment2 {
+        container sub-container-from-augment3 {
+        }
+    }
+
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-in-uses-augment {
+        container sub-container-from-augment2 {
+        }
+    }
+
+    augment /root-container/container-from-grp1/sub-container-from-grp1 {
+        container sub-container-from-augment {
+        }
+    }
+
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-from-grp2/sub-container-from-grp2/augmented-container-in-uses-grp2 {
+        container sub-container-from-augment6 {
+        }
+    }
+    
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-from-grp2/sub-container-from-grp2/sub-container-from-augment5 {
+        container sub-container-from-augment7 {
+        }
+    }
+    
+    augment /root-container/container-from-grp1/sub-container-from-grp1/container-from-grp2/sub-container-from-grp2 {
+        container sub-container-from-augment5 {
+        }
+    }
+
+    augment /root-container/added-container-1 {
+        container added-container-2 {
+        }
+    }
+
+    augment /root-container {
+        container added-container-1 {
+        }
+    }
+
+    grouping grp1 {
+        container container-from-grp1 {
+            container sub-container-from-grp1 {
+                uses grp2 {
+                    augment container-from-grp2/sub-container-from-grp2 {
+                        container augmented-container-in-uses-grp2;
+                    }
+                }
+            }
+        }
+    }
+
+    grouping grp2 {
+        container container-from-grp2 {
+            container sub-container-from-grp2 {
+            }
+        }
+        uses grp3;
+    }
+    
+    grouping grp3 {
+      container container-from-grp3 {
+          
+      }
+    }
+    
+    container root-container {
+        uses grp1 {
+            augment container-from-grp1/sub-container-from-grp1 {
+                container container-in-uses-augment {
+                }
+            }
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/effective-build/aug-root.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/effective-build/aug-root.yang
deleted file mode 100644 (file)
index 017b108..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-module aug-root {
-       namespace root;
-       prefix root;
-
-       import augmented {
-               prefix aug;
-       }
-
-       augment "aug:aug-parent1/aug:aug-parent2/aug:cont-target" {
-               container cont-added1 {
-                       list list1 {
-                       }
-               }
-
-               container cont-added2 {
-                       anyxml axml;
-               }
-
-               uses aug:grp;
-       }
-}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/effective-build/augmented.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/effective-build/augmented.yang
deleted file mode 100644 (file)
index 47ca018..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-module augmented {
-       namespace aug;
-       prefix aug;
-
-       container aug-parent1 {
-               container aug-parent2 {
-                       container cont-target {
-
-                       }
-               }
-       }
-
-       grouping grp {
-               container cont-grp {
-                       anyxml axml-grp;
-               }
-       }
-}
\ No newline at end of file