From 30c67c4d780e897d972d60bb79d546b512516f90 Mon Sep 17 00:00:00 2001 From: Peter Kajsa Date: Mon, 13 Jul 2015 14:51:21 +0200 Subject: [PATCH] Bug 2366 - Effective statments impl merge, retest & bugfix - rebase - integrated changes from https://git.opendaylight.org/gerrit/#/c/21310 - added some JavaDoc, minor fixes in null checking, unneeded code, refactoring etc. - minor fixes in hashCode(), equals(), getters etc. - list key relative path fix - list keys resolution fix - multiple modules and revisions fix - rebase on master - instance identifier type build fix - bug2649 test - re-sync of retest with old impl folder (old parser vs. new parser) - buildType qname fix - non YANG statement detection implemented - uses-augment module qname fix - uses-augment is augmenting fix - type constraints parsing and validation fix - Unique statement support added - identityRef validation simplification - typedef base type QName resolution fix - parse with context fix - typedef order unit test fix - invalid string patterns parsing fix - refine unknown statements fix - union types order fix - typedef in grouping fix - identityRef null identity fix - pick latest revision even when not reverse chronologicaly ordered in module fix - clean up of SourceSpecificContext & YangStatementParserListenerImpl classes, rebased on master - types, extended types and type definitions impl and bugfix - declared types resolution - statementSourceReference support implemented - basicType impl proposal - typeDefEffStmt impl as builder of ExtendedType - few decl. types resolution fixes done - identityRefs validation implemented - fixed tests dealing with unknown stmts - uses getRefine fix - load with context retest - ordering of statements and substatements fix - augment into unknown statement body fix - uses or augment in unknown statement body fix - extension identifier correctly passed to unknown statement for effective resolution phase - substatements of included submodules appendation fix - node name collision validation - refine target validation - added statement copy type by both Augment and Uses (when augmenting in uses statement) - some of negative scenarios (arguments/statements validation) fix - fix of module imports, revision - augmentation namespace and revision initialization fix - available augmentation impl fix - Case shorthand schema path fix - Case shorthand fix - Unsupported augment targets fix - Multiple augments to the same target - reactor fix - StackOverflowException on cyclic identity hierarchy fix - include vs. belongsTo linkage resolution fix - introduces replacement of old YANG parser by new statement parser in set of existing tests - some test methods adjusted for new parser data structure - Types & TypeDefs support & resolution implemented - BelongsTo namespace added to be able to resolve typedefs from parent modules - Identity, IdentityRef support & resolution preparation - Minor sonar issues fixed - Effective statements related to types implemented Bug 2366 - Effective statements implementation (2nd patch) - added further implementation of Module and Submodule Effective statements and initialization of submodules collection in Module effective statement - implementation of uses-refine - implementation of Constraints, etc... - effective statement fields initialization - added unit tests - fix of some issues in the parser (ModuleQName default revision date, Generics, etc..) Bug 2366 - Identity, Refine, ... effective statements impl. (3th patch) - implementation of Identity effective statement - implementation of Refine effective statement - initialization of some unitialized effective statments fields - augmentation process fix - unit tests Change-Id: I95cda640136c966bd1b1fd3b0bcb1e143675eac1 Signed-off-by: Peter Kajsa Signed-off-by: Martin Ciglan Signed-off-by: Gregor Zatko --- .../yang/common/SimpleDateFormatUtil.java | 20 + .../yang/model/api/Rfc6020Mapping.java | 19 +- .../model/api/meta/StatementDefinition.java | 6 +- .../yang/model/api/stmt/BitStatement.java | 12 +- .../yang/model/api/stmt/EnumStatement.java | 12 +- .../api/stmt/FractionDigitsStatement.java | 4 +- .../yang/model/api/stmt/LengthStatement.java | 10 +- .../model/api/stmt/MinElementsStatement.java | 4 +- .../yang/model/api/stmt/PatternStatement.java | 8 +- .../model/api/stmt/PositionStatement.java | 7 +- .../yang/model/api/stmt/RangeStatement.java | 10 +- .../model/api/stmt/RevisionDateStatement.java | 6 +- .../yang/model/api/stmt/StatusStatement.java | 6 +- .../yang/model/api/stmt/TypeStatement.java | 16 +- .../yang/model/api/stmt/ValueStatement.java | 4 +- .../model/api/type/IntegerTypeDefinition.java | 16 +- .../yang/model/export/ExtensionStatement.java | 3 +- .../model/util/RevisionAwareXPathImpl.java | 2 +- .../builder/impl/IdentityrefTypeBuilder.java | 4 +- .../impl/YangStatementParserListenerImpl.java | 65 +- .../yang/parser/spi/IdentityNamespace.java | 9 +- .../yang/parser/spi/ModuleNamespace.java | 7 +- .../spi/meta/AbstractStatementSupport.java | 2 +- .../spi/meta/DerivedIdentitiesNamespace.java | 24 + .../parser/spi/meta/ModelProcessingPhase.java | 3 +- .../parser/spi/meta/NamespaceBehaviour.java | 149 ++- .../parser/spi/meta/StatementNamespace.java | 13 +- .../yang/parser/spi/meta/StmtContext.java | 35 +- .../parser/spi/meta/StmtContextUtils.java | 135 ++- .../spi/source/BelongsToModuleContext.java | 17 + .../spi/source/DeclarationInTextSource.java | 2 +- .../IncludedSubmoduleNameToIdentifier.java | 21 + .../spi/source/ModuleCtxToModuleQName.java | 22 + .../spi/source/ModuleNameToModuleQName.java | 2 - .../source/ModuleNamespaceForBelongsTo.java | 21 + .../parser/spi/source/SourceException.java | 2 +- .../parser/spi/source/StatementWriter.java | 6 + .../ValidationBundlesNamespace.java | 48 + .../stmt/reactor/BuildGlobalContext.java | 32 +- .../parser/stmt/reactor/ContextBuilder.java | 58 + .../reactor/CrossSourceStatementReactor.java | 30 +- .../NamespaceBehaviourWithListeners.java | 7 + .../stmt/reactor/NamespaceStorageSupport.java | 19 +- .../stmt/reactor/RootStatementContext.java | 112 +- .../stmt/reactor/SourceSpecificContext.java | 209 +++- .../stmt/reactor/StatementContextBase.java | 336 ++++-- .../stmt/reactor/StatementContextWriter.java | 10 +- .../stmt/reactor/SubstatementContext.java | 38 +- .../stmt/rfc6020/AugmentStatementImpl.java | 13 +- .../parser/stmt/rfc6020/AugmentUtils.java | 165 ++- .../stmt/rfc6020/BaseStatementImpl.java | 51 +- .../stmt/rfc6020/BelongsToStatementImpl.java | 53 +- .../stmt/rfc6020/BinarySpecificationImpl.java | 65 ++ .../parser/stmt/rfc6020/BitStatementImpl.java | 36 +- .../stmt/rfc6020/BitsSpecificationImpl.java | 24 +- .../rfc6020/Decimal64SpecificationImpl.java | 35 +- .../stmt/rfc6020/EnumSpecificationImpl.java | 28 +- .../stmt/rfc6020/EnumStatementImpl.java | 38 +- .../stmt/rfc6020/ExtensionStatementImpl.java | 3 +- .../rfc6020/FractionDigitsStatementImpl.java | 43 +- .../stmt/rfc6020/GroupingStatementImpl.java | 7 +- .../parser/stmt/rfc6020/GroupingUtils.java | 201 +++- .../rfc6020/IdentityRefSpecificationImpl.java | 44 +- .../stmt/rfc6020/IdentityStatementImpl.java | 15 +- .../rfc6020/ImportStatementDefinition.java | 29 +- .../stmt/rfc6020/IncludeStatementImpl.java | 30 +- .../InstanceIdentifierSpecificationImpl.java | 11 +- .../parser/stmt/rfc6020/KeyStatementImpl.java | 9 +- .../rfc6020/LeafrefSpecificationImpl.java | 8 +- .../stmt/rfc6020/LengthStatementImpl.java | 33 +- .../rfc6020/MinElementsStatementImpl.java | 21 +- .../stmt/rfc6020/ModuleStatementSupport.java | 35 +- .../stmt/rfc6020/MustStatementImpl.java | 9 +- .../rfc6020/NumericalRestrictionsImpl.java | 34 +- .../stmt/rfc6020/PathStatementImpl.java | 60 ++ .../stmt/rfc6020/PatternStatementImpl.java | 48 +- .../stmt/rfc6020/PositionStatementImpl.java | 22 +- .../stmt/rfc6020/RangeStatementImpl.java | 39 +- .../rfc6020/RequireInstanceStatementImpl.java | 2 +- .../rfc6020/RevisionDateStatementImpl.java | 33 +- .../stmt/rfc6020/RevisionStatementImpl.java | 4 +- .../stmt/rfc6020/StatusStatementImpl.java | 22 +- .../stmt/rfc6020/StringRestrictionsImpl.java | 27 +- .../stmt/rfc6020/SubmoduleStatementImpl.java | 41 +- .../stmt/rfc6020/TypeStatementImpl.java | 80 +- .../yang/parser/stmt/rfc6020/TypeUtils.java | 329 ++++++ .../stmt/rfc6020/TypedefStatementImpl.java | 44 +- .../stmt/rfc6020/UnionSpecificationImpl.java | 12 +- .../stmt/rfc6020/UniqueStatementImpl.java | 63 ++ .../stmt/rfc6020/UnknownStatementImpl.java | 11 +- .../stmt/rfc6020/UsesStatementImpl.java | 10 +- .../yang/parser/stmt/rfc6020/Utils.java | 297 ++++-- .../stmt/rfc6020/ValueStatementImpl.java | 37 +- .../stmt/rfc6020/WhenStatementImpl.java | 4 +- .../stmt/rfc6020/YangInferencePipeline.java | 170 +-- .../stmt/rfc6020/YangStatementSourceImpl.java | 31 +- .../stmt/rfc6020/YangValidationBundles.java | 64 ++ ...tEffectiveDocumentedDataNodeContainer.java | 50 +- .../AbstractEffectiveDocumentedNode.java | 17 +- .../AnyXmlEffectiveStatementImpl.java | 38 +- .../AugmentEffectiveStatementImpl.java | 28 +- .../effective/CaseEffectiveStatementImpl.java | 25 +- .../rfc6020/effective/CaseShorthandImpl.java | 138 +++ .../ChoiceEffectiveStatementImpl.java | 76 +- .../ContainerEffectiveStatementImpl.java | 40 +- .../EffectiveConstraintDefinitionImpl.java | 157 +++ .../effective/EffectiveSchemaContext.java | 6 +- .../effective/EffectiveStatementBase.java | 76 +- .../rfc6020/effective/EffectiveStmtUtils.java | 27 + .../ExtendedTypeEffectiveStatementImpl.java | 325 ++++++ .../ExtensionEffectiveStatementImpl.java | 15 +- .../FeatureEffectiveStatementImpl.java | 126 ++- .../FractionDigitsEffectiveStatementImpl.java | 4 +- .../GroupingEffectiveStatementImpl.java | 31 +- .../IdentityEffectiveStatementImpl.java | 34 +- .../ImportEffectiveStatementImpl.java | 8 +- .../InputEffectiveStatementImpl.java | 42 +- .../effective/LeafEffectiveStatementImpl.java | 93 +- .../LeafListEffectiveStatementImpl.java | 84 +- .../effective/ListEffectiveStatementImpl.java | 107 +- .../MinElementsEffectiveStatementImpl.java | 4 +- .../ModuleEffectiveStatementImpl.java | 198 +++- .../effective/MustEffectiveStatementImpl.java | 123 ++- .../NotificationEffectiveStatementImpl.java | 1 - .../OutputEffectiveStatementImpl.java | 38 +- ...l.java => PathEffectiveStatementImpl.java} | 13 +- .../PositionEffectiveStatementImpl.java | 6 +- .../RefineEffectiveStatementImpl.java | 58 +- ...RequireInstanceEffectiveStatementImpl.java | 8 +- .../RevisionDateEffectiveStatementImpl.java | 6 +- .../RevisionEffectiveStatementImpl.java | 25 + .../StatusEffectiveStatementImpl.java | 6 +- .../SubmoduleEffectiveStatementImpl.java | 204 +++- .../TypeDefEffectiveStatementImpl.java | 215 ++++ .../UniqueEffectiveStatementImpl.java | 24 + .../UnitsEffectiveStatementImpl.java | 2 +- .../UnknownEffectiveStatementImpl.java | 207 ++++ .../effective/UsesEffectiveStatementImpl.java | 69 +- .../ValueEffectiveStatementImpl.java | 8 +- .../effective/WhenEffectiveStatementImpl.java | 2 +- .../type/BinaryEffectiveStatementImpl.java | 92 ++ .../type/BitEffectiveStatementImpl.java | 156 +++ ...tsSpecificationEffectiveStatementImpl.java | 179 ++++ .../type/BooleanEffectiveStatementImpl.java | 93 ++ ...64SpecificationEffectiveStatementImpl.java | 183 ++++ .../type/EmptyEffectiveStatementImpl.java | 84 ++ .../type/EnumEffectiveStatementImpl.java | 99 ++ ...umSpecificationEffectiveStatementImpl.java | 192 ++++ ...efSpecificationEffectiveStatementImpl.java | 130 +++ ...erSpecificationEffectiveStatementImpl.java | 130 +++ .../type/Int16EffectiveStatementImpl.java | 27 + .../type/Int32EffectiveStatementImpl.java | 27 + .../type/Int64EffectiveStatementImpl.java | 27 + .../type/Int8EffectiveStatementImpl.java | 27 + .../type/IntegerEffectiveImplBase.java | 178 ++++ ...efSpecificationEffectiveStatementImpl.java | 156 +++ .../type/LengthConstraintEffectiveImpl.java | 153 +++ .../LengthEffectiveStatementImpl.java | 12 +- ...calRestrictionsEffectiveStatementImpl.java | 19 + .../type/PatternConstraintEffectiveImpl.java | 141 +++ .../PatternEffectiveStatementImpl.java | 11 +- .../type/RangeConstraintEffectiveImpl.java | 146 +++ .../RangeEffectiveStatementImpl.java | 16 +- .../type/StringEffectiveStatementImpl.java | 164 +++ ...ngRestrictionsEffectiveStatementImpl.java} | 16 +- .../type/TypeDefinitionEffectiveBuilder.java | 14 + .../type/UInt16EffectiveStatementImpl.java | 26 + .../type/UInt32EffectiveStatementImpl.java | 26 + .../type/UInt64EffectiveStatementImpl.java | 28 + .../type/UInt8EffectiveStatementImpl.java | 26 + ...onSpecificationEffectiveStatementImpl.java | 153 +++ .../UnsignedIntegerEffectiveImplBase.java | 179 ++++ .../parser/impl/YangParserSimpleTest.java | 26 +- .../build/test/EffectiveBuildTest.java | 78 +- .../build/test/EffectiveIdentityTest.java | 123 +++ .../build/test/EffectiveModuleTest.java | 42 +- .../EffectiveModulesAndSubmodulesTest.java | 215 ++++ ...EffectiveUsesRefineAndConstraintsTest.java | 185 ++++ .../yang/stmt/retest/AugmentTest.java | 440 ++++++++ .../stmt/retest/AugmentToExtensionTest.java | 75 ++ .../AugmentationSchemaBuilderImplTest.java | 63 ++ .../yang/stmt/retest/Bug1412Test.java | 99 ++ .../yang/stmt/retest/Bug1413Test.java | 42 + .../yang/stmt/retest/Bug2219Test.java | 49 + .../yang/stmt/retest/Bug394Test.java | 48 + .../yang/stmt/retest/GroupingTest.java | 588 +++++++++++ .../yang/stmt/retest/ListKeysTest.java | 116 ++ .../stmt/retest/ModuleIdentifierTest.java | 82 ++ .../yang/stmt/retest/OrderingTest.java | 148 +++ .../retest/ParsingExtensionValueTest.java | 46 + .../stmt/retest/SameQNamesInChoiceTest.java | 58 + .../yang/stmt/retest/SchemaContextTest.java | 78 ++ .../yangtools/yang/stmt/retest/TestUtils.java | 192 ++++ .../yang/stmt/retest/TwoRevisionsTest.java | 25 + .../yang/stmt/retest/TypesResolutionTest.java | 391 +++++++ .../yang/stmt/retest/UsesAugmentTest.java | 650 ++++++++++++ .../retest/YangModelValidationListTest.java | 111 ++ .../retest/YangModelValidationModuleTest.java | 178 ++++ .../YangModelValidationSubModuleTest.java | 87 ++ .../stmt/retest/YangModelValidationTest.java | 270 +++++ .../stmt/retest/YangParserIdentityTest.java | 60 ++ .../stmt/retest/YangParserNegativeTest.java | 269 +++++ .../stmt/retest/YangParserSimpleTest.java | 210 ++++ .../yang/stmt/retest/YangParserTest.java | 988 ++++++++++++++++++ .../retest/YangParserWithContextTest.java | 568 ++++++++++ .../yang/stmt/retest/package-info.java | 13 + .../yang/stmt/test/AugmentProcessTest.java | 53 +- .../yang/stmt/test/AugmentSimplestTest.java | 14 +- .../yangtools/yang/stmt/test/AugmentTest.java | 16 +- .../test/ImportBasicTestStatementSource.java | 162 --- .../stmt/test/ImportResolutionBasicTest.java | 59 +- .../yang/stmt/test/ImportResolutionTest.java | 102 -- .../yang/stmt/test/ImportRevisionsTest.java | 109 -- .../yang/stmt/test/IncludeResolutionTest.java | 52 +- .../yang/stmt/test/IncludeRevisionsTest.java | 38 +- .../stmt/test/IncludeTestStatementSource.java | 157 --- .../yangtools/yang/stmt/test/KeyTest.java | 4 +- .../yang/stmt/test/MoreRevisionsTest.java | 121 +++ .../yang/stmt/test/StmtTestUtils.java | 82 ++ .../yang/stmt/test/TestStatementSource.java | 162 --- .../test/TestYangFileStatementSource.java | 79 -- .../yang/stmt/test/UsesResolutionTest.java | 125 --- .../stmt/test/UsesTestStatementSource.java | 298 ------ .../yang/stmt/test/YangFileStmtTest.java | 38 +- .../yang/stmt/test/YangTypes2StmtTest.java | 117 +++ .../yang/stmt/test/YangTypesStmtTest.java | 53 + .../bugs/bug394-retest/bug394-ext.yang | 24 + .../resources/bugs/bug394-retest/bug394.yang | 48 + .../ietf-yang-types@2010-09-24.yang | 396 +++++++ .../ietf/network-topology@2013-07-12.yang | 2 +- .../ietf/network-topology@2013-10-21.yang | 2 +- .../src/test/resources/model-new/bar.yang | 5 +- .../src/test/resources/model-new/foo.yang | 5 +- .../test/resources/revisions/equal-rev.yang | 10 +- .../test/resources/revisions/equal-root.yang | 12 +- .../resources/revisions/mod-1970-rev.yang | 8 +- .../resources/revisions/mod-1970-root.yang | 12 +- .../resources/revisions/mod-only-rev.yang | 8 +- .../resources/revisions/mod-only-root.yang | 12 +- .../test/resources/revisions/nowhere-rev.yang | 8 +- .../resources/revisions/nowhere-root.yang | 8 +- .../resources/revisions/submod-only-rev.yang | 10 +- .../resources/revisions/submod-only-root.yang | 8 +- .../test/resources/revisions/unequal-rev.yang | 10 +- .../resources/revisions/unequal-root.yang | 12 +- .../bug2649/foo.yang | 6 + .../bug2649/import-module.yang | 8 + .../effective-module/imported.yang | 8 +- .../effective-module/root.yang | 101 +- .../identityreftest.yang | 14 + .../import-arg-parsing/cycle-yang.yang | 8 + .../import-arg-parsing/cycle-yin.yang | 8 + .../import-arg-parsing/egocentric.yang | 8 + .../import-arg-parsing/human.yang | 8 + .../import-arg-parsing/mammal.yang | 8 + .../import-arg-parsing/nature.yang | 4 + .../include-arg-parsing/error-module.yang | 6 + .../include-arg-parsing/error-submodule.yang | 7 + .../include-arg-parsing/missing-parent.yang | 5 + .../include-arg-parsing/root-module.yang | 6 + .../include-arg-parsing/submodule-1.yang | 6 + .../include-arg-parsing/submodule-2.yang | 5 + .../semantic-statement-parser/model/bar.yang | 119 +++ .../semantic-statement-parser/model/baz.yang | 194 ++++ .../semantic-statement-parser/model/foo.yang | 204 ++++ .../model/subfoo.yang | 65 ++ .../revisions/more-revisions-test.yang | 14 + .../simple-types.yang | 103 ++ .../isis-topology@2013-07-12.yang | 143 +++ .../isis-topology@2013-10-21.yang | 143 +++ .../l3-unicast-igp-topology@2013-07-12.yang | 233 +++++ .../l3-unicast-igp-topology@2013-10-21.yang | 233 +++++ .../two-revisions/ted@2013-07-12.yang | 301 ++++++ .../two-revisions/ted@2013-10-21.yang | 306 ++++++ .../semantic-statement-parser/types.yang | 158 +++ .../semantic-statement-parser/types2.yang | 97 ++ .../resources/simple-test/simple-nodes.yang | 2 +- .../resources/stmt-test/extensions/mock.yang | 18 + .../stmt-test/extensions/yang-ext.yang | 79 ++ .../identity/cyclic-identity-test.yang | 34 + .../stmt-test/identity/identity-test.yang | 26 + .../stmt-test/submodules/imported-module.yang | 8 + .../stmt-test/submodules/root-module.yang | 13 + .../stmt-test/submodules/submodule-1.yang | 11 + .../stmt-test/submodules/submodule-2.yang | 9 + .../submodules/submodule-to-submodule-1.yang | 9 + .../resources/stmt-test/uses/refine-test.yang | 57 + 287 files changed, 18759 insertions(+), 2857 deletions(-) create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/DerivedIdentitiesNamespace.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/BelongsToModuleContext.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/IncludedSubmoduleNameToIdentifier.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModuleCtxToModuleQName.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModuleNamespaceForBelongsTo.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/validation/ValidationBundlesNamespace.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ContextBuilder.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BinarySpecificationImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/PathStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypeUtils.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UniqueStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangValidationBundles.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/CaseShorthandImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveConstraintDefinitionImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveStmtUtils.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ExtendedTypeEffectiveStatementImpl.java rename yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/{EnumEffectiveStatementImpl.java => PathEffectiveStatementImpl.java} (56%) create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/TypeDefEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UniqueEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UnknownEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BinaryEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BitEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BitsSpecificationEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BooleanEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Decimal64SpecificationEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/EmptyEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/EnumEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/EnumSpecificationEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/IdentityRefSpecificationEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/InstanceIdentifierSpecificationEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int16EffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int32EffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int64EffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int8EffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/IntegerEffectiveImplBase.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LeafrefSpecificationEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthConstraintEffectiveImpl.java rename yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/{ => type}/LengthEffectiveStatementImpl.java (56%) create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/NumericalRestrictionsEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternConstraintEffectiveImpl.java rename yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/{ => type}/PatternEffectiveStatementImpl.java (58%) create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeConstraintEffectiveImpl.java rename yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/{ => type}/RangeEffectiveStatementImpl.java (56%) create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/StringEffectiveStatementImpl.java rename yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/{BitEffectiveStatementImpl.java => type/StringRestrictionsEffectiveStatementImpl.java} (51%) create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/TypeDefinitionEffectiveBuilder.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt16EffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt32EffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt64EffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt8EffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UnionSpecificationEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UnsignedIntegerEffectiveImplBase.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveIdentityTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveModulesAndSubmodulesTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveUsesRefineAndConstraintsTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/AugmentTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/AugmentToExtensionTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/AugmentationSchemaBuilderImplTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug1412Test.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug1413Test.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug2219Test.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug394Test.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/GroupingTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/ListKeysTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/ModuleIdentifierTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/OrderingTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/ParsingExtensionValueTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/SameQNamesInChoiceTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/SchemaContextTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/TestUtils.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/TwoRevisionsTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/TypesResolutionTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/UsesAugmentTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationListTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationModuleTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationSubModuleTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserIdentityTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserNegativeTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserSimpleTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserWithContextTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/package-info.java delete mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportBasicTestStatementSource.java delete mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportResolutionTest.java delete mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportRevisionsTest.java delete mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/IncludeTestStatementSource.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/MoreRevisionsTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/StmtTestUtils.java delete mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/TestStatementSource.java delete mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/TestYangFileStatementSource.java delete mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/UsesResolutionTest.java delete mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/UsesTestStatementSource.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/YangTypes2StmtTest.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/YangTypesStmtTest.java create mode 100644 yang/yang-parser-impl/src/test/resources/bugs/bug394-retest/bug394-ext.yang create mode 100644 yang/yang-parser-impl/src/test/resources/bugs/bug394-retest/bug394.yang create mode 100644 yang/yang-parser-impl/src/test/resources/bugs/bug394-retest/ietf-yang-types@2010-09-24.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/bug2649/foo.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/bug2649/import-module.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/identityreftest.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/cycle-yang.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/cycle-yin.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/egocentric.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/human.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/mammal.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/nature.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/error-module.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/error-submodule.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/missing-parent.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/root-module.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/submodule-1.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/submodule-2.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/model/bar.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/model/baz.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/model/foo.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/model/subfoo.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/revisions/more-revisions-test.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/simple-types.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/isis-topology@2013-07-12.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/isis-topology@2013-10-21.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/l3-unicast-igp-topology@2013-07-12.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/l3-unicast-igp-topology@2013-10-21.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/ted@2013-07-12.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/ted@2013-10-21.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/types.yang create mode 100644 yang/yang-parser-impl/src/test/resources/semantic-statement-parser/types2.yang create mode 100644 yang/yang-parser-impl/src/test/resources/stmt-test/extensions/mock.yang create mode 100644 yang/yang-parser-impl/src/test/resources/stmt-test/extensions/yang-ext.yang create mode 100644 yang/yang-parser-impl/src/test/resources/stmt-test/identity/cyclic-identity-test.yang create mode 100644 yang/yang-parser-impl/src/test/resources/stmt-test/identity/identity-test.yang create mode 100644 yang/yang-parser-impl/src/test/resources/stmt-test/submodules/imported-module.yang create mode 100644 yang/yang-parser-impl/src/test/resources/stmt-test/submodules/root-module.yang create mode 100644 yang/yang-parser-impl/src/test/resources/stmt-test/submodules/submodule-1.yang create mode 100644 yang/yang-parser-impl/src/test/resources/stmt-test/submodules/submodule-2.yang create mode 100644 yang/yang-parser-impl/src/test/resources/stmt-test/submodules/submodule-to-submodule-1.yang create mode 100644 yang/yang-parser-impl/src/test/resources/stmt-test/uses/refine-test.yang diff --git a/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/SimpleDateFormatUtil.java b/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/SimpleDateFormatUtil.java index 9d11685a6d..0ffc0bec1d 100644 --- a/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/SimpleDateFormatUtil.java +++ b/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/SimpleDateFormatUtil.java @@ -14,18 +14,38 @@ import java.util.Date; public final class SimpleDateFormatUtil { + /** + * revision format according to Yang spec + */ private static final String REVISION_SIMPLE_DATE = "yyyy-MM-dd"; + + /** + * default Yang date that is used when date is not present + */ private static final String DEFAULT_DATE = "1970-01-01"; + /** + * {@link SimpleDateFormatUtil#DEFAULT_DATE} for revision statement + */ public static final Date DEFAULT_DATE_REV; + + /** + * {@link SimpleDateFormatUtil#DEFAULT_DATE} for import statement + */ public static final Date DEFAULT_DATE_IMP; + /** + * {@link SimpleDateFormatUtil#DEFAULT_DATE} for belongs-to statement + */ + public static final Date DEFAULT_BELONGS_TO_DATE; + static { final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(REVISION_SIMPLE_DATE); try { DEFAULT_DATE_REV = simpleDateFormat.parse(DEFAULT_DATE); DEFAULT_DATE_IMP = simpleDateFormat.parse(DEFAULT_DATE); + DEFAULT_BELONGS_TO_DATE = simpleDateFormat.parse(DEFAULT_DATE); } catch (final ParseException e) { throw new ExceptionInInitializerError(e); } diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/Rfc6020Mapping.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/Rfc6020Mapping.java index 1bf809567d..feb35e3573 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/Rfc6020Mapping.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/Rfc6020Mapping.java @@ -15,6 +15,7 @@ import javax.annotation.Nullable; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.YangConstants; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; import org.opendaylight.yangtools.yang.model.api.stmt.AnyxmlStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentStatement; @@ -152,27 +153,34 @@ public enum Rfc6020Mapping implements StatementDefinition { YIN_ELEMENT(YinElementStatement.class, "yin-element", "value"); private final Class> type; + private final Class> effectiveType; private final QName name; private final QName argument; private final boolean yinElement; - private Rfc6020Mapping(Class> clz, final String nameStr) { + Rfc6020Mapping(Class> clz, final String nameStr) { type = Preconditions.checkNotNull(clz); + //FIXME: fill up effective type correctly + effectiveType = null; name = yinQName(nameStr); argument = null; yinElement = false; } - private Rfc6020Mapping(Class> clz, final String nameStr, final String argumentStr) { + Rfc6020Mapping(Class> clz, final String nameStr, final String argumentStr) { type = Preconditions.checkNotNull(clz); + //FIXME: fill up effective type correctly + effectiveType = null; name = yinQName(nameStr); argument = yinQName(argumentStr); this.yinElement = false; } - private Rfc6020Mapping(Class> clz, final String nameStr, final String argumentStr, + Rfc6020Mapping(Class> clz, final String nameStr, final String argumentStr, final boolean yinElement) { type = Preconditions.checkNotNull(clz); + //FIXME: fill up effective type correctly + effectiveType = null; name = yinQName(nameStr); argument = yinQName(argumentStr); this.yinElement = yinElement; @@ -198,9 +206,8 @@ public enum Rfc6020Mapping implements StatementDefinition { } @Override - public Class> getEffectiveRepresentationClass() { - // FIXME: Add support once these interfaces are defined. - throw new UnsupportedOperationException("Not defined yet."); + public Class> getEffectiveRepresentationClass() { + return effectiveType; } public boolean isArgumentYinElement() { diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/StatementDefinition.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/StatementDefinition.java index 5d5d2da8e4..2f7fa56720 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/StatementDefinition.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/StatementDefinition.java @@ -63,15 +63,15 @@ public interface StatementDefinition extends Immutable { /** * - * Returns class which represents supplied statement. + * Returns class which represents derived behaviour from supplied statement. * * This class should be interface, which defines convenience access to * statement properties, namespace items and substatements. * - * @return class which represents declared version of statement associated + * @return class which represents effective version of statement associated * with this definition */ @Nonnull - Class> getEffectiveRepresentationClass(); + Class> getEffectiveRepresentationClass(); } diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BitStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BitStatement.java index 2b1862e361..058f8e85cc 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BitStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/BitStatement.java @@ -9,13 +9,15 @@ package org.opendaylight.yangtools.yang.model.api.stmt; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -public interface BitStatement extends DeclaredStatement, DocumentationGroup.WithStatus { +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; - @Nonnull String getName(); +public interface BitStatement extends DeclaredStatement, DocumentationGroup.WithStatus { - @Nullable PositionStatement getPosition(); + @Nonnull + String getName(); + @Nullable + PositionStatement getPosition(); } - diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/EnumStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/EnumStatement.java index a2e373d402..28373caadf 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/EnumStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/EnumStatement.java @@ -9,13 +9,15 @@ package org.opendaylight.yangtools.yang.model.api.stmt; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -public interface EnumStatement extends DeclaredStatement, DocumentationGroup.WithStatus { +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; - @Nonnull String getName(); +public interface EnumStatement extends DeclaredStatement, DocumentationGroup.WithStatus { - @Nullable ValueStatement getValue(); + @Nonnull + String getName(); + @Nullable + ValueStatement getValue(); } - diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FractionDigitsStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FractionDigitsStatement.java index 7e8d1f68f9..a8c6f312f4 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FractionDigitsStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FractionDigitsStatement.java @@ -10,8 +10,8 @@ package org.opendaylight.yangtools.yang.model.api.stmt; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -public interface FractionDigitsStatement extends DeclaredStatement { +public interface FractionDigitsStatement extends DeclaredStatement { - String getValue(); + Integer getValue(); } diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LengthStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LengthStatement.java index 490b67d6b1..803626ad34 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LengthStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/LengthStatement.java @@ -7,11 +7,15 @@ */ package org.opendaylight.yangtools.yang.model.api.stmt; +import java.util.List; + import javax.annotation.Nonnull; + import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; +import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; -public interface LengthStatement extends DeclaredStatement, DocumentedConstraintGroup { +public interface LengthStatement extends DeclaredStatement>, DocumentedConstraintGroup { - @Nonnull String getValue(); + @Nonnull + List getValue(); } - diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MinElementsStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MinElementsStatement.java index f355cc1b5c..d25dbb9c58 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MinElementsStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/MinElementsStatement.java @@ -10,8 +10,8 @@ package org.opendaylight.yangtools.yang.model.api.stmt; import javax.annotation.Nonnull; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -public interface MinElementsStatement extends DeclaredStatement { +public interface MinElementsStatement extends DeclaredStatement { - @Nonnull String getValue(); + @Nonnull Integer getValue(); } diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PatternStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PatternStatement.java index fe6d429e82..cbecac8043 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PatternStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PatternStatement.java @@ -8,10 +8,12 @@ package org.opendaylight.yangtools.yang.model.api.stmt; import javax.annotation.Nonnull; + import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; +import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; -public interface PatternStatement extends DeclaredStatement, DocumentedConstraintGroup { +public interface PatternStatement extends DeclaredStatement, DocumentedConstraintGroup { - @Nonnull String getValue(); + @Nonnull + PatternConstraint getValue(); } - diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PositionStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PositionStatement.java index 447590f046..1dc9ebe7c4 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PositionStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/PositionStatement.java @@ -8,10 +8,11 @@ package org.opendaylight.yangtools.yang.model.api.stmt; import javax.annotation.Nonnull; + import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -public interface PositionStatement extends DeclaredStatement { +public interface PositionStatement extends DeclaredStatement { - @Nonnull String getValue(); + @Nonnull + Long getValue(); } - diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RangeStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RangeStatement.java index f8ca4ff367..0c13727523 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RangeStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RangeStatement.java @@ -7,11 +7,15 @@ */ package org.opendaylight.yangtools.yang.model.api.stmt; +import java.util.List; + import javax.annotation.Nonnull; + import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; -public interface RangeStatement extends DeclaredStatement, DocumentedConstraintGroup { +public interface RangeStatement extends DeclaredStatement>, DocumentedConstraintGroup { - @Nonnull String getRange(); + @Nonnull + List getRange(); } - diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RevisionDateStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RevisionDateStatement.java index 96b7b125d7..1b91cb642a 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RevisionDateStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RevisionDateStatement.java @@ -7,10 +7,12 @@ */ package org.opendaylight.yangtools.yang.model.api.stmt; +import java.util.Date; + import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -public interface RevisionDateStatement extends DeclaredStatement { +public interface RevisionDateStatement extends DeclaredStatement { - String getDate(); + Date getDate(); } diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/StatusStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/StatusStatement.java index 44e8cb6d3c..5b9a023357 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/StatusStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/StatusStatement.java @@ -7,11 +7,13 @@ */ package org.opendaylight.yangtools.yang.model.api.stmt; +import org.opendaylight.yangtools.yang.model.api.Status; + import javax.annotation.Nonnull; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -public interface StatusStatement extends DeclaredStatement { +public interface StatusStatement extends DeclaredStatement { - @Nonnull String getValue(); + @Nonnull Status getValue(); } diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeStatement.java index 42b45c38b4..cfb9d13124 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeStatement.java @@ -51,28 +51,40 @@ public interface TypeStatement extends DeclaredStatement { @Rfc6020AbnfRule("leafref-specification") interface LeafrefSpecification extends TypeStatement { - @Nullable PathStatement getPath(); + @Nonnull PathStatement getPath(); } + @Rfc6020AbnfRule("instanceidentifier-specification") interface InstanceIdentifierSpecification extends TypeStatement { @Nullable RequireInstanceStatement getRequireInstance(); } - + @Rfc6020AbnfRule("identityref-specification") interface IdentityRefSpecification extends TypeStatement { + @Nonnull BaseStatement getBase(); + } + + @Rfc6020AbnfRule("bits-specification") interface BitsSpecification extends TypeStatement { @Nonnull Collection getBits(); } + @Rfc6020AbnfRule("union-specification") interface UnionSpecification extends TypeStatement { @Nonnull Collection getTypes(); } + + @Rfc6020AbnfRule("binary-specification") + interface BinarySpecification extends TypeStatement { + + @Nullable LengthStatement getLength(); + } } diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ValueStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ValueStatement.java index 1d2ef0c28c..7ad7c1e2ec 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ValueStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ValueStatement.java @@ -11,7 +11,7 @@ import javax.annotation.Nonnull; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -public interface ValueStatement extends DeclaredStatement { +public interface ValueStatement extends DeclaredStatement { - @Nonnull String getValue(); + @Nonnull Integer getValue(); } diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/type/IntegerTypeDefinition.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/type/IntegerTypeDefinition.java index bf1bc26873..3bc928cf58 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/type/IntegerTypeDefinition.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/type/IntegerTypeDefinition.java @@ -8,25 +8,19 @@ package org.opendaylight.yangtools.yang.model.api.type; import java.util.List; - import org.opendaylight.yangtools.yang.model.api.TypeDefinition; /** - * IntegerTypeDefinition is interface which represents SIGNED Integer values - * defined in Yang language.
- * The integer built-in types in Yang are int8, int16, int32, int64. They - * represent signed integers of different sizes:
+ * IntegerTypeDefinition is interface which represents SIGNED Integer values defined in Yang language.
+ * The integer built-in types in Yang are int8, int16, int32, int64. They represent signed integers of different sizes:
*
    *
  • int8 represents integer values between -128 and 127, inclusively.
  • *
  • int16 represents integer values between -32768 and 32767, inclusively.
  • - *
  • int32 represents integer values between -2147483648 and 2147483647, - * inclusively.
  • - *
  • int64 represents integer values between -9223372036854775808 and - * 9223372036854775807, inclusively.
  • + *
  • int32 represents integer values between -2147483648 and 2147483647, inclusively.
  • + *
  • int64 represents integer values between -9223372036854775808 and 9223372036854775807, inclusively.
  • *
* - * The Integer Built-In Types are defined in [RFC-6020] + * The Integer Built-In Types are defined in [RFC-6020] */ public interface IntegerTypeDefinition extends TypeDefinition { diff --git a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/ExtensionStatement.java b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/ExtensionStatement.java index 16b195e6bb..7a3f1a3bd3 100644 --- a/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/ExtensionStatement.java +++ b/yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/ExtensionStatement.java @@ -13,6 +13,7 @@ import java.util.Map; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; final class ExtensionStatement implements StatementDefinition { @@ -60,7 +61,7 @@ final class ExtensionStatement implements StatementDefinition { } @Override - public Class> getEffectiveRepresentationClass() { + public Class> getEffectiveRepresentationClass() { throw new UnsupportedOperationException("Not defined"); } diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/RevisionAwareXPathImpl.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/RevisionAwareXPathImpl.java index 3ef6d5a64e..93b3dfe2a0 100644 --- a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/RevisionAwareXPathImpl.java +++ b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/RevisionAwareXPathImpl.java @@ -64,7 +64,7 @@ public class RevisionAwareXPathImpl implements RevisionAwareXPath { if (absolute != other.absolute) { return false; } - return false; + return true; } @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/IdentityrefTypeBuilder.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/IdentityrefTypeBuilder.java index e79df80139..ca2982d84a 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/IdentityrefTypeBuilder.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/IdentityrefTypeBuilder.java @@ -112,7 +112,7 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple @Override public QName getQName() { - return null; + return qname; } @Override @@ -207,6 +207,8 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple @Override public String toString() { final StringBuilder result = new StringBuilder(IdentityrefTypeBuilder.class.getSimpleName()); + result.append("[qName="); + result.append(qname); result.append("["); result.append(", base="); result.append(baseIdentity); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangStatementParserListenerImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangStatementParserListenerImpl.java index b5b3cf0291..04f54c624c 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangStatementParserListenerImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangStatementParserListenerImpl.java @@ -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 @@ -9,35 +9,43 @@ package org.opendaylight.yangtools.yang.parser.impl; import java.util.ArrayList; import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; + +import javax.annotation.concurrent.Immutable; import org.antlr.v4.runtime.tree.ParseTree; import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser; import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParserBaseListener; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.YangConstants; +import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; +import org.opendaylight.yangtools.yang.parser.spi.source.DeclarationInTextSource; 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.StatementWriter; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; - -import javax.annotation.concurrent.Immutable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Immutable public class YangStatementParserListenerImpl extends YangStatementParserBaseListener { private StatementWriter writer; - private StatementSourceReference ref; + private String sourceName; private QNameToStatementDefinition stmtDef; private PrefixToModule prefixes; private List toBeSkipped = new ArrayList<>(); + private boolean isType = false; private static final Logger LOG = LoggerFactory.getLogger(YangStatementParserListenerImpl.class); - public YangStatementParserListenerImpl(StatementSourceReference ref) { - this.ref = ref; + public YangStatementParserListenerImpl(String sourceName) { + this.sourceName = sourceName; + // TODO + // this.sourceName = Preconditions.checkNotNull(sourceName, "YangStatementParserListenerImpl#sourceName cannot " + // + "be null"); } public void setAttributes(StatementWriter writer, QNameToStatementDefinition stmtDef) { @@ -53,25 +61,49 @@ public class YangStatementParserListenerImpl extends YangStatementParserBaseList @Override public void enterStatement(YangStatementParser.StatementContext ctx) { + final StatementSourceReference ref = DeclarationInTextSource.atPosition(sourceName, ctx.getStart().getLine(), + ctx.getStart().getCharPositionInLine()); boolean action = true; + QName identifier; for (int i = 0; i < ctx.getChildCount(); i++) { ParseTree child = ctx.getChild(i); if (child instanceof YangStatementParser.KeywordContext) { try { - QName identifier = new QName(YangConstants.RFC6020_YIN_NAMESPACE, + identifier = new QName(YangConstants.RFC6020_YIN_NAMESPACE, ((YangStatementParser.KeywordContext) child).children.get(0).getText()); - if (stmtDef != null && Utils.isValidStatementDefinition(prefixes, stmtDef, identifier) && toBeSkipped.isEmpty()) { - writer.startStatement(identifier, ref); + if (stmtDef != null && Utils.isValidStatementDefinition(prefixes, stmtDef, identifier) + && toBeSkipped.isEmpty()) { + if (identifier.equals(Rfc6020Mapping.TYPE.getStatementName())) { + isType = true; + } else { + writer.startStatement(identifier, ref); + } } else { - action = false; - toBeSkipped.add(((YangStatementParser.KeywordContext) child).children.get(0).getText()); + if (writer.getPhase().equals(ModelProcessingPhase.FULL_DECLARATION)) { + throw new IllegalArgumentException(identifier.getLocalName() + " is not a YANG statement " + + "or use of extension. Source: " + ref); + } + else { + action = false; + toBeSkipped.add(((YangStatementParser.KeywordContext) child).children.get(0).getText()); + } } } catch (SourceException e) { LOG.warn(e.getMessage(), e); } } else if (child instanceof YangStatementParser.ArgumentContext) { try { - if (action) { + final String argument = Utils.stringFromStringContext((YangStatementParser.ArgumentContext) child); + if (isType) { + if (TypeUtils.isYangTypeBodyStmt(argument)) { + writer.startStatement(new QName(YangConstants.RFC6020_YIN_NAMESPACE, argument), ref); + } else { + writer.startStatement(new QName(YangConstants.RFC6020_YIN_NAMESPACE, Rfc6020Mapping.TYPE + .getStatementName().getLocalName()), ref); + } + writer.argumentValue(argument, ref); + isType = false; + } else if (action) { writer.argumentValue( Utils.stringFromStringContext((YangStatementParser.ArgumentContext) child), ref); } else { @@ -87,13 +119,16 @@ public class YangStatementParserListenerImpl extends YangStatementParserBaseList @Override public void exitStatement(YangStatementParser.StatementContext ctx) { + final StatementSourceReference ref = DeclarationInTextSource.atPosition(sourceName, ctx.getStart().getLine(), + ctx.getStart().getCharPositionInLine()); for (int i = 0; i < ctx.getChildCount(); i++) { ParseTree child = ctx.getChild(i); if (child instanceof YangStatementParser.KeywordContext) { try { String statementName = ((YangStatementParser.KeywordContext) child).children.get(0).getText(); QName identifier = new QName(YangConstants.RFC6020_YIN_NAMESPACE, statementName); - if (stmtDef != null && Utils.isValidStatementDefinition(prefixes, stmtDef, identifier) && toBeSkipped.isEmpty()) { + if (stmtDef != null && Utils.isValidStatementDefinition(prefixes, stmtDef, identifier) + && toBeSkipped.isEmpty()) { writer.endStatement(ref); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/IdentityNamespace.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/IdentityNamespace.java index fc0e3783d8..39f287e37b 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/IdentityNamespace.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/IdentityNamespace.java @@ -8,17 +8,18 @@ package org.opendaylight.yangtools.yang.parser.spi; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StatementNamespace; /** * * Identity namespace * - * All identity names defined in a module and its submodules share the same - * identity identifier namespace. + * All identity names defined in a module and its submodules share the same identity identifier namespace. * */ -public interface IdentityNamespace extends IdentifierNamespace { +public interface IdentityNamespace extends + StatementNamespace> { } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/ModuleNamespace.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/ModuleNamespace.java index 16add17aaa..6dadd8aec5 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/ModuleNamespace.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/ModuleNamespace.java @@ -12,6 +12,9 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementNamespace; -public interface ModuleNamespace extends StatementNamespace> { - +/** + * namespace class for storing modules into Yang model storage keyed by {@link ModuleIdentifier} + */ +public interface ModuleNamespace extends + StatementNamespace> { } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractStatementSupport.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractStatementSupport.java index 583c0d821e..eb75d0c71f 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractStatementSupport.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractStatementSupport.java @@ -54,7 +54,7 @@ public abstract class AbstractStatementSupport } @Override - public final Class> getEffectiveRepresentationClass() { + public final Class> getEffectiveRepresentationClass() { return type.getEffectiveRepresentationClass(); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/DerivedIdentitiesNamespace.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/DerivedIdentitiesNamespace.java new file mode 100644 index 0000000000..d8e7d6db52 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/DerivedIdentitiesNamespace.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.parser.spi.meta; + +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; + +/** + * + * Identity namespace + * + * All identity names defined in a module and its submodules share the same + * identity identifier namespace. + * + */ +public interface DerivedIdentitiesNamespace extends IdentifierNamespace>> { + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelProcessingPhase.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelProcessingPhase.java index a559e48474..7896a17533 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelProcessingPhase.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelProcessingPhase.java @@ -23,7 +23,8 @@ public enum ModelProcessingPhase { * visibility of custom defined statements in following * phases. */ - SOURCE_LINKAGE(null), + INIT(null), + SOURCE_LINKAGE(INIT), STATEMENT_DEFINITION(SOURCE_LINKAGE), FULL_DECLARATION(STATEMENT_DEFINITION), EFFECTIVE_MODEL(FULL_DECLARATION); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java index 6522af9227..1d996d97e1 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java @@ -8,6 +8,7 @@ package org.opendaylight.yangtools.yang.parser.spi.meta; import com.google.common.base.Preconditions; +import java.util.Map; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.yangtools.concepts.Identifiable; @@ -16,22 +17,23 @@ import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; /** * Definition / implementation of specific Identifier Namespace behaviour. * - * Namespace behaviour is build on top of tree of {@link NamespaceStorageNode} - * which represents local context of one of types defined in {@link StorageNodeType}. + * Namespace behaviour is build on top of tree of {@link NamespaceStorageNode} which represents local context of one of + * types defined in {@link StorageNodeType}. * - * For common behaviour models please use static factories {@link #global(Class)}, - * {@link #sourceLocal(Class)} and {@link #treeScoped(Class)}. + * For common behaviour models please use static factories {@link #global(Class)}, {@link #sourceLocal(Class)} and + * {@link #treeScoped(Class)}. * - * @param Key type - * @param Value type - * @param Namespace Type + * @param + * Key type + * @param + * Value type + * @param + * Namespace Type */ -public abstract class NamespaceBehaviour> implements Identifiable>{ +public abstract class NamespaceBehaviour> implements Identifiable> { public enum StorageNodeType { - GLOBAL, - SOURCE_LOCAL_SPECIAL, - STATEMENT_LOCAL, + GLOBAL, SOURCE_LOCAL_SPECIAL, STATEMENT_LOCAL, } public interface Registry { @@ -42,11 +44,17 @@ public abstract class NamespaceBehaviour> V getFromLocalStorage(Class type, K key); + @Nullable + > V getFromLocalStorage(Class type, K key); - @Nullable > void addToLocalStorage(Class type, K key, V value); + @Nullable + > Map getAllFromLocalStorage(Class type); + + @Nullable + > void addToLocalStorage(Class type, K key, V value); } @@ -60,13 +68,15 @@ public abstract class NamespaceBehaviour> NamespaceBehaviour global(Class identifier) { + public static @Nonnull > NamespaceBehaviour global( + Class identifier) { return new StorageSpecific<>(identifier, StorageNodeType.GLOBAL); } @@ -74,34 +84,47 @@ public abstract class NamespaceBehaviour> NamespaceBehaviour sourceLocal(Class identifier) { + public static > NamespaceBehaviour sourceLocal( + Class identifier) { return new StorageSpecific<>(identifier, StorageNodeType.SOURCE_LOCAL_SPECIAL); } /** - * - * Creates tree-scoped namespace behaviour for supplied namespace type. - * - * Tree-scoped namespace behaviour search for value in all storage nodes - * up to the root and stores values in supplied node. - * - * @param identifier Namespace identifier. - * @return tree-scoped namespace behaviour for supplied namespace type. - */ - public static > NamespaceBehaviour treeScoped(Class identifier) { + * + * Creates tree-scoped namespace behaviour for supplied namespace type. + * + * Tree-scoped namespace behaviour search for value in all storage nodes up to the root and stores values in + * supplied node. + * + * @param identifier + * Namespace identifier. + * @return tree-scoped namespace behaviour for supplied namespace type. + */ + public static > NamespaceBehaviour treeScoped(Class identifier) { return new TreeScoped<>(identifier); } + /** + * returns value from model namespace storage according to key param class + */ public abstract V getFrom(NamespaceStorageNode storage, K key); - public abstract void addTo(NamespaceStorageNode storage,K key,V value); + /** + * returns all values of a keys of param class from model namespace storage + */ + public abstract Map getAllFrom(NamespaceStorageNode storage); + + /** + * adds key and value to corresponding namespace storage according to param class + */ + public abstract void addTo(NamespaceStorageNode storage, K key, V value); @Override public Class getIdentifier() { @@ -112,11 +135,15 @@ public abstract class NamespaceBehaviour getAllFromLocalStorage(NamespaceStorageNode storage) { + return storage.getAllFromLocalStorage(getIdentifier()); } - static class StorageSpecific> extends NamespaceBehaviour { + protected final void addToStorage(NamespaceStorageNode storage, K key, V value) { + storage.addToLocalStorage(getIdentifier(), key, value); + } + + static class StorageSpecific> extends NamespaceBehaviour { StorageNodeType storageType; @@ -128,16 +155,26 @@ public abstract class NamespaceBehaviour 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; - while(current.getStorageNodeType() != storageType) { + while (current.getStorageNodeType() != storageType) { current = current.getParentNamespaceStorage(); } addToStorage(current, key, value); @@ -145,7 +182,7 @@ public abstract class NamespaceBehaviour> extends NamespaceBehaviour { + static class TreeScoped> extends NamespaceBehaviour { public TreeScoped(Class identifier) { super(identifier); @@ -154,9 +191,9 @@ public abstract class NamespaceBehaviour getAllFrom(final NamespaceStorageNode storage) { -// NamespaceStorageNode current = storage; -// while(current != null) { -// final Map val = getAllFromLocalStorage(current); -// if(val != null) { -// return val; -// } -// current = current.getParentNamespaceStorage(); -// } -// return null; -// } + @Override + public Map getAllFrom(final NamespaceStorageNode storage) { + NamespaceStorageNode current = storage; + while (current != null) { + final Map val = getAllFromLocalStorage(current); + if (val != null) { + return val; + } + current = current.getParentNamespaceStorage(); + } + return null; + } @Override - public void addTo(NamespaceStorageNode storage,K key, V value) { + public void addTo(NamespaceStorageNode storage, K key, V value) { addToStorage(storage, key, value); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementNamespace.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementNamespace.java index 01b16e3252..defa69d95d 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementNamespace.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementNamespace.java @@ -12,15 +12,18 @@ import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; -public interface StatementNamespace,E extends EffectiveStatement> extends IdentifierNamespace { +public interface StatementNamespace, E extends EffectiveStatement> extends + IdentifierNamespace> { @Override - @Nullable E get(K key); + @Nullable + StmtContext get(K key); - interface TreeScoped,E extends EffectiveStatement> extends StatementNamespace { - TreeScoped getParentContext(); + interface TreeScoped, E extends EffectiveStatement> extends + StatementNamespace { + TreeScoped getParentContext(); } - interface TreeBased,E extends EffectiveStatement> { + interface TreeBased, E extends EffectiveStatement> { } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java index 1e24600932..d46e2716a7 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java @@ -45,16 +45,17 @@ public interface StmtContext, E extends Effect @Nullable List getArgumentsFromRoot(); - // > - // > VT - // getFromNamespace(Class type, K key) + List> getStmtContextsFromRoot(); + @Nonnull - > V getFromNamespace( - Class type, K key) throws NamespaceNotAvailableException; + > V getFromNamespace( + Class type, KT key) throws NamespaceNotAvailableException; - > Map getAllFromNamespace( + > Map getAllFromNamespace( Class type); + > Map getAllFromCurrentStmtCtxNamespace(Class type); + @Nonnull StmtContext getRoot(); @@ -67,12 +68,24 @@ public interface StmtContext, E extends Effect E buildEffective(); + boolean isSupportedToBuildEffective(); + + void setIsSupportedToBuildEffective(boolean isSupportedToBuild); + + Collection> getEffectOfStatement(); + + void addAsEffectOfStatement(StatementContextBase ctx); + + StatementContextBase createCopy( + StatementContextBase newParent, TypeOfCopy typeOfCopy) + throws SourceException; + StatementContextBase createCopy(QNameModule newQNameModule, StatementContextBase newParent, TypeOfCopy typeOfCopy) throws SourceException; - public static enum TypeOfCopy { - ORIGINAL, ADDED_BY_USES, ADDED_BY_AUGMENTATION + enum TypeOfCopy { + ORIGINAL, ADDED_BY_USES, ADDED_BY_AUGMENTATION, ADDED_BY_USES_AUGMENTATION } TypeOfCopy getTypeOfCopy(); @@ -95,10 +108,8 @@ public interface StmtContext, E extends Effect @Override StmtContext.Mutable getParentContext(); - // > void - // addToNs(Class type, K key, VT value) - > void addToNs( - Class type, K key, VT value) + > void addToNs( + Class type, KT key, VT value) throws NamespaceNotAvailableException; @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java index a410c197d9..eccbaca07d 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContextUtils.java @@ -8,26 +8,47 @@ package org.opendaylight.yangtools.yang.parser.spi.meta; import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.base.Splitter; import java.util.Collection; +import java.util.HashSet; +import java.util.List; +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.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.UnknownStatementImpl; public final class StmtContextUtils { - private static final Function, DeclaredStatement> BUILD_DECLARED = new Function, DeclaredStatement>() { + public static final char LIST_KEY_SEPARATOR = ' '; + private static final Splitter KEY_SPLITTER = Splitter.on(LIST_KEY_SEPARATOR).omitEmptyStrings().trimResults(); + + private static final Function, DeclaredStatement> BUILD_DECLARED = new Function, DeclaredStatement>() { @Override public DeclaredStatement apply(final StmtContext input) { return input.buildDeclared(); } }; - private static final Function, EffectiveStatement> BUILD_EFFECTIVE = new Function, EffectiveStatement>() { + private static final Function, EffectiveStatement> BUILD_EFFECTIVE = new Function, EffectiveStatement>() { @Override public EffectiveStatement apply(final StmtContext input) { return input.buildEffective(); } }; + public static final Predicate> IS_SUPPORTED_TO_BUILD_EFFECTIVE = new Predicate>() { + @Override + public boolean apply(StmtContext input) { + return input.isSupportedToBuildEffective(); + } + }; + private StmtContextUtils() { throw new UnsupportedOperationException("Utility class"); } @@ -38,14 +59,13 @@ public final class StmtContextUtils { } @SuppressWarnings("unchecked") - public static > Function, E> buildEffective() { + public static final > Function, E> buildEffective() { return Function.class.cast(BUILD_EFFECTIVE); } @SuppressWarnings("unchecked") - public static > AT firstAttributeOf( - final Iterable> contexts, - final Class
declaredType) { + public static final > AT firstAttributeOf( + final Iterable> contexts, final Class
declaredType) { for (StmtContext ctx : contexts) { if (producesDeclared(ctx, declaredType)) { return (AT) ctx.getStatementArgument(); @@ -55,8 +75,8 @@ public final class StmtContextUtils { } @SuppressWarnings("unchecked") - public static > AT firstAttributeOf( - final StmtContext ctx, final Class
declaredType) { + public static final > AT firstAttributeOf(final StmtContext ctx, + final Class
declaredType) { if (producesDeclared(ctx, declaredType)) { return (AT) ctx.getStatementArgument(); @@ -65,52 +85,48 @@ public final class StmtContextUtils { return null; } - public static
> StmtContext findFirstDeclaredSubstatement( - final StmtContext stmtContext, final Class
declaredType) { - Collection> declaredSubstatements = stmtContext - .declaredSubstatements(); + @SuppressWarnings("unchecked") + public static final > StmtContext findFirstDeclaredSubstatement( + StmtContext stmtContext, Class
declaredType) { + Collection> declaredSubstatements = stmtContext.declaredSubstatements(); for (StmtContext subStmtContext : declaredSubstatements) { - if (producesDeclared(subStmtContext,declaredType)) { - return subStmtContext; + if (producesDeclared(subStmtContext, declaredType)) { + return (StmtContext) subStmtContext; } } return null; } - public static StmtContext findFirstDeclaredSubstatement( - final StmtContext stmtContext, int startIndex, final Class>... types) { + public static final StmtContext findFirstDeclaredSubstatement(final StmtContext stmtContext, + int startIndex, final Class>... types) { if (startIndex >= types.length) { return null; } - Collection> declaredSubstatements = stmtContext - .declaredSubstatements(); + Collection> declaredSubstatements = stmtContext.declaredSubstatements(); for (StmtContext subStmtContext : declaredSubstatements) { - if (producesDeclared(subStmtContext,types[startIndex])) { + if (producesDeclared(subStmtContext, types[startIndex])) { if (startIndex + 1 == types.length) { return subStmtContext; } else { - return findFirstDeclaredSubstatement(subStmtContext, - ++startIndex, types); + return findFirstDeclaredSubstatement(subStmtContext, ++startIndex, types); } } } return null; } - public static
> StmtContext findFirstDeclaredSubstatementOnSublevel( - final StmtContext stmtContext, final Class
declaredType, - int sublevel) { - Collection> declaredSubstatements = stmtContext - .declaredSubstatements(); + public static final
> StmtContext findFirstDeclaredSubstatementOnSublevel( + final StmtContext stmtContext, final Class
declaredType, int sublevel) { + Collection> declaredSubstatements = stmtContext.declaredSubstatements(); for (StmtContext subStmtContext : declaredSubstatements) { - if (sublevel == 1 && producesDeclared(subStmtContext,declaredType)) { + if (sublevel == 1 && producesDeclared(subStmtContext, declaredType)) { return subStmtContext; } else { if (sublevel > 1) { - StmtContext result = findFirstDeclaredSubstatementOnSublevel( - subStmtContext, declaredType, --sublevel); + StmtContext result = findFirstDeclaredSubstatementOnSublevel(subStmtContext, declaredType, + --sublevel); if (result != null) { return result; } @@ -120,18 +136,16 @@ public final class StmtContextUtils { return null; } - public static
> StmtContext findDeepFirstDeclaredSubstatement( + public static final
> StmtContext findDeepFirstDeclaredSubstatement( final StmtContext stmtContext, final Class
declaredType) { - Collection> declaredSubstatements = stmtContext - .declaredSubstatements(); + Collection> declaredSubstatements = stmtContext.declaredSubstatements(); for (StmtContext subStmtContext : declaredSubstatements) { - if (producesDeclared(subStmtContext,declaredType)) { + if (producesDeclared(subStmtContext, declaredType)) { return subStmtContext; } else { - StmtContext result = findDeepFirstDeclaredSubstatement( - subStmtContext, declaredType); + StmtContext result = findDeepFirstDeclaredSubstatement(subStmtContext, declaredType); if (result != null) { return result; } @@ -141,9 +155,54 @@ public final class StmtContextUtils { return null; } - public static boolean producesDeclared(final StmtContext ctx, + public static final boolean producesDeclared(final StmtContext ctx, final Class> type) { - return type.isAssignableFrom(ctx.getPublicDefinition() - .getDeclaredRepresentationClass()); + return type.isAssignableFrom(ctx.getPublicDefinition().getDeclaredRepresentationClass()); + } + + public static boolean isInExtensionBody(StmtContext stmtCtx) { + + StmtContext current = stmtCtx; + while (!current.getParentContext().isRootContext()) { + current = current.getParentContext(); + if (producesDeclared(current, UnknownStatementImpl.class)) { + return true; + } + } + + return false; + } + + public static boolean isUnknownStatement(StmtContext stmtCtx) { + return producesDeclared(stmtCtx, UnknownStatementImpl.class); + } + + public static Set getCopyTypesFromOriginal(StmtContext ctx) { + + Set copyTypesFromOriginal = new HashSet<>(); + StmtContext current = ctx; + + while (current.getOriginalCtx() != null) { + copyTypesFromOriginal.add(current.getTypeOfCopy()); + current = current.getOriginalCtx(); + } + + return copyTypesFromOriginal; + } + + public static Collection replaceModuleQNameForKey( + StmtContext, KeyStatement, ?> keyStmtCtx, QNameModule newQNameModule) { + + List keyTokens = KEY_SPLITTER.splitToList(keyStmtCtx.rawStatementArgument()); + + Set newKeys = new HashSet<>(); + + for (String keyToken : keyTokens) { + QName keyQName = QName.create(newQNameModule, keyToken); + SchemaNodeIdentifier keyIdentifier = SchemaNodeIdentifier.create(false, keyQName); + newKeys.add(keyIdentifier); + } + + return newKeys; } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/BelongsToModuleContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/BelongsToModuleContext.java new file mode 100644 index 0000000000..99d2f5135f --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/BelongsToModuleContext.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.parser.spi.source; + +import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; +import org.opendaylight.yangtools.yang.parser.spi.meta.ImportedNamespaceContext; + +/** +* namespace key class for storing belongs-to statements in Yang model storage +*/ +public interface BelongsToModuleContext extends ImportedNamespaceContext { +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/DeclarationInTextSource.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/DeclarationInTextSource.java index 8f37fdf889..b782618065 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/DeclarationInTextSource.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/DeclarationInTextSource.java @@ -18,7 +18,7 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementSource; * of YANG / YIN statement stream sources. * * - * To create source reference use one of this static factiories: + * To create source reference use one of this static factories: *
    *
  • {@link #atPosition(String, int, int)} - provides most specific reference of statement location, * this is most prefered since it provides most context to debug YANG model. diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/IncludedSubmoduleNameToIdentifier.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/IncludedSubmoduleNameToIdentifier.java new file mode 100644 index 0000000000..34fd1da3ba --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/IncludedSubmoduleNameToIdentifier.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.parser.spi.source; + +import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; + +import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; + +/** + * + * Source-specific mapping of prefixes to namespaces + * + */ +public interface IncludedSubmoduleNameToIdentifier extends IdentifierNamespace { + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModuleCtxToModuleQName.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModuleCtxToModuleQName.java new file mode 100644 index 0000000000..2487afd3cb --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModuleCtxToModuleQName.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.parser.spi.source; + +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; + +import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; + +/** + * + * Source-specific mapping of prefixes to namespaces + * + */ +public interface ModuleCtxToModuleQName extends IdentifierNamespace, QNameModule> { + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModuleNameToModuleQName.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModuleNameToModuleQName.java index 0f32b25cd4..33fc7d6aab 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModuleNameToModuleQName.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModuleNameToModuleQName.java @@ -17,6 +17,4 @@ import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; */ public interface ModuleNameToModuleQName extends IdentifierNamespace { - - } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModuleNamespaceForBelongsTo.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModuleNamespaceForBelongsTo.java new file mode 100644 index 0000000000..786a151aa4 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModuleNamespaceForBelongsTo.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.parser.spi.source; + +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StatementNamespace; + +/** + * namespace class similar to {@link org.opendaylight.yangtools.yang.parser.spi.ModuleNamespace} for storing modules + * into Yang model storage but keyed by plain name + */ +public interface ModuleNamespaceForBelongsTo extends + StatementNamespace> { + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/SourceException.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/SourceException.java index de5228e258..aafaabf146 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/SourceException.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/SourceException.java @@ -15,7 +15,7 @@ import javax.annotation.Nonnull; * Thrown to indicate error in YANG model source. * */ -public class SourceException extends Exception { +public class SourceException extends RuntimeException { /** * diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/StatementWriter.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/StatementWriter.java index 543e06b4f0..40c67e358f 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/StatementWriter.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/StatementWriter.java @@ -9,6 +9,7 @@ package org.opendaylight.yangtools.yang.parser.spi.source; import javax.annotation.Nonnull; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; public interface StatementWriter { @@ -77,4 +78,9 @@ public interface StatementWriter { */ void endStatement(@Nonnull StatementSourceReference ref) throws SourceException; + /** + * + * @return current processing phase + */ + @Nonnull ModelProcessingPhase getPhase(); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/validation/ValidationBundlesNamespace.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/validation/ValidationBundlesNamespace.java new file mode 100644 index 0000000000..42505dea8f --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/validation/ValidationBundlesNamespace.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.yangtools.yang.parser.spi.validation; + +import java.util.Collection; +import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; + +/** + * namespace used for validating whether a node is of some type, e.g. usable target for some operation or has other + * significant properties + */ +public interface ValidationBundlesNamespace extends + IdentifierNamespace> { + + public static enum ValidationBundleType { + /** + * whether a node is suitable refine substatement + */ + SUPPORTED_REFINE_SUBSTATEMENTS, + + /** + * whether a node is suitable target for refine operation + */ + SUPPORTED_REFINE_TARGETS, + + /** + * whether a node is suitable target for augment operation + */ + SUPPORTED_AUGMENT_TARGETS, + + /** + * whether a case shorthand can be created for a + * node + */ + SUPPORTED_CASE_SHORTHANDS, + + /** + * whether a node is data node + */ + SUPPORTED_DATA_NODES + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java index 90b41b9912..b4c7bdd204 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java @@ -7,8 +7,13 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.reactor; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite; +import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace; +import java.util.Map.Entry; +import java.util.Collection; +import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import com.google.common.base.Preconditions; import com.google.common.base.Throwables; @@ -49,18 +54,28 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh .build(); private final Map> definitions = new HashMap<>(); - private final Map,NamespaceBehaviourWithListeners> namespaces = new HashMap<>(); + private final Map,NamespaceBehaviourWithListeners> supportedNamespaces = new HashMap<>(); private final Map supports; private final Set sources = new HashSet<>(); - private ModelProcessingPhase currentPhase; - private ModelProcessingPhase finishedPhase; + private ModelProcessingPhase currentPhase = ModelProcessingPhase.INIT; + private ModelProcessingPhase finishedPhase = ModelProcessingPhase.INIT; public BuildGlobalContext(Map supports) { super(); - this.supports = supports; + this.supports = Preconditions.checkNotNull(supports, "BuildGlobalContext#supports cannot be null"); + } + + public BuildGlobalContext(Map supports, Map> supportedValidation) { + super(); + this.supports = Preconditions.checkNotNull(supports, "BuildGlobalContext#supports cannot be null"); + + Set>> validationBundles = supportedValidation.entrySet(); + for (Entry> validationBundle : validationBundles) { + addToNs(ValidationBundlesNamespace.class, validationBundle.getKey(), validationBundle.getValue()); + } } public StatementSupportBundle getSupportsForPhase(ModelProcessingPhase currentPhase) { @@ -88,12 +103,12 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh @Override public > NamespaceBehaviourWithListeners getNamespaceBehaviour(Class type) { - NamespaceBehaviourWithListeners potential = namespaces.get(type); + NamespaceBehaviourWithListeners potential = supportedNamespaces.get(type); if (potential == null) { NamespaceBehaviour potentialRaw = supports.get(currentPhase).getNamespaceBehaviour(type); if(potentialRaw != null) { potential = new NamespaceBehaviourWithListeners<>(potentialRaw); - namespaces.put(type, potential); + supportedNamespaces.put(type, potential); } } if (potential != null) { @@ -191,7 +206,8 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh progressing = false; Iterator currentSource = sourcesToProgress.iterator(); while(currentSource.hasNext()) { - PhaseCompletionProgress sourceProgress = currentSource.next().tryToCompletePhase(currentPhase); + SourceSpecificContext nextSourceCtx = currentSource.next(); + PhaseCompletionProgress sourceProgress = nextSourceCtx.tryToCompletePhase(currentPhase); switch (sourceProgress) { case FINISHED: currentSource.remove(); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ContextBuilder.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ContextBuilder.java new file mode 100644 index 0000000000..8828881ab0 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ContextBuilder.java @@ -0,0 +1,58 @@ +/* + * 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.reactor; + +import com.google.common.base.Preconditions; +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; +import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference; + +abstract class ContextBuilder, E extends EffectiveStatement> { + + private final StatementDefinitionContext definition; + private final StatementSourceReference stmtRef; + private String rawArg; + private StatementSourceReference argRef; + + public ContextBuilder(StatementDefinitionContext 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."); + this.rawArg = Preconditions.checkNotNull(argument); + this.argRef = Preconditions.checkNotNull(argumentSource); + } + + public String getRawArgument() { + return rawArg; + } + + public StatementSourceReference getStamementSource() { + return stmtRef; + } + + public StatementSourceReference getArgumentSource() { + return argRef; + } + + public StatementDefinitionContext getDefinition() { + return definition; + } + + public StatementIdentifier createIdentifier() { + return new StatementIdentifier(definition.getStatementName(), rawArg); + } + + public abstract StatementContextBase build() throws SourceException; + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/CrossSourceStatementReactor.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/CrossSourceStatementReactor.java index 06ae43adce..c804080994 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/CrossSourceStatementReactor.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/CrossSourceStatementReactor.java @@ -7,8 +7,10 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.reactor; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext; +import java.util.Collection; +import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext; import com.google.common.collect.ImmutableMap; import java.util.EnumMap; import java.util.Map; @@ -21,9 +23,16 @@ import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource; public class CrossSourceStatementReactor { private final Map supportedTerminology; + private final Map> supportedValidation; CrossSourceStatementReactor(Map supportedTerminology) { this.supportedTerminology = ImmutableMap.copyOf(supportedTerminology); + this.supportedValidation = ImmutableMap.of(); + } + + CrossSourceStatementReactor(Map supportedTerminology, Map> supportedValidation) { + this.supportedTerminology = ImmutableMap.copyOf(supportedTerminology); + this.supportedValidation = ImmutableMap.copyOf(supportedValidation); } public static final Builder builder() { @@ -37,15 +46,24 @@ public class CrossSourceStatementReactor { public static class Builder implements org.opendaylight.yangtools.concepts.Builder{ final Map bundles = new EnumMap<>(ModelProcessingPhase.class); + final Map> validationBundles = new EnumMap<>(ValidationBundleType.class); public Builder setBundle(ModelProcessingPhase phase,StatementSupportBundle bundle) { bundles.put(phase, bundle); return this; } + + public Builder setValidationBundle( + ValidationBundleType type, + Collection validationBundle) { + validationBundles.put(type,validationBundle); + return this; + } + @Override public CrossSourceStatementReactor build() { - return new CrossSourceStatementReactor(bundles); + return new CrossSourceStatementReactor(bundles, validationBundles); } } @@ -55,13 +73,19 @@ public class CrossSourceStatementReactor { private final BuildGlobalContext context; public BuildAction() { - this.context = new BuildGlobalContext(supportedTerminology); + this.context = new BuildGlobalContext(supportedTerminology, supportedValidation); } public void addSource(StatementStreamSource source) { context.addSource(source); } + public void addSources(StatementStreamSource... sources) { + for (StatementStreamSource source : sources) { + context.addSource(source); + } + } + public EffectiveModelContext build() throws SourceException, ReactorException { return context.build(); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceBehaviourWithListeners.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceBehaviourWithListeners.java index 2a99e6e143..b05594466d 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceBehaviourWithListeners.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceBehaviourWithListeners.java @@ -10,6 +10,8 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import java.util.Iterator; +import java.util.Map; + import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour; @@ -63,4 +65,9 @@ final class NamespaceBehaviourWithListeners getAllFrom(final NamespaceStorageNode storage) { + return delegate.getAllFrom(storage); + } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceStorageSupport.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceStorageSupport.java index 8e6409f583..65dc89ab70 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceStorageSupport.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceStorageSupport.java @@ -36,16 +36,20 @@ abstract class NamespaceStorageSupport implements NamespaceStorageNode { //> V //public final > VT getFromNamespace(Class type, K key) - public final > V getFromNamespace(Class type, K key) + public final > V getFromNamespace(Class type, KT key) throws NamespaceNotAvailableException { return getBehaviourRegistry().getNamespaceBehaviour(type).getFrom(this,key); } - public final > Map getAllFromNamespace(Class type){ - return namespaces.get(type); + public final > Map getAllFromNamespace(Class type){ + return getBehaviourRegistry().getNamespaceBehaviour(type).getAllFrom(this); } - public final > void addToNs(Class type, K key, VT value) + public final > Map getAllFromCurrentStmtCtxNamespace(Class type){ + return (Map) namespaces.get(type); + } + + public final > void addToNs(Class type, KT key, VT value) throws NamespaceNotAvailableException { getBehaviourRegistry().getNamespaceBehaviour(type).addTo(this,key,value); } @@ -66,7 +70,12 @@ abstract class NamespaceStorageSupport implements NamespaceStorageNode { return null; } - + @Override + public > Map getAllFromLocalStorage(Class type) { + @SuppressWarnings("unchecked") + Map localNamespace = (Map) namespaces.get(type); + return localNamespace; + } @Override public > void addToLocalStorage(Class type, K key, V value) { diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java index d32b8cdee1..6b876c71f6 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java @@ -7,34 +7,33 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.reactor; -import java.util.List; - +import java.util.Collection; import java.util.LinkedList; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import java.util.List; import org.opendaylight.yangtools.yang.common.QNameModule; -import java.util.Collection; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; -class RootStatementContext, E extends EffectiveStatement> - extends StatementContextBase { +/** + * root statement class for a Yang source + */ +public class RootStatementContext, E extends EffectiveStatement> extends + StatementContextBase { private final SourceSpecificContext sourceContext; private final A argument; - RootStatementContext(ContextBuilder builder, - SourceSpecificContext sourceContext) throws SourceException { + RootStatementContext(ContextBuilder builder, SourceSpecificContext sourceContext) throws SourceException { super(builder); this.sourceContext = sourceContext; - this.argument = builder.getDefinition().parseArgumentValue(this, - builder.getRawArgument()); + this.argument = builder.getDefinition().parseArgumentValue(this, builder.getRawArgument()); } - RootStatementContext(RootStatementContext original, - QNameModule newQNameModule, TypeOfCopy typeOfCopy) + RootStatementContext(RootStatementContext original, QNameModule newQNameModule, TypeOfCopy typeOfCopy) throws SourceException { super(original); @@ -47,43 +46,63 @@ class RootStatementContext, E extends Effectiv } - private void copyDeclaredStmts(RootStatementContext original, - QNameModule newQNameModule, TypeOfCopy typeOfCopy) - throws SourceException { - Collection> originalDeclaredSubstatements = original - .declaredSubstatements(); + /** + * copies declared statements from original to this' substatements + * + * @param typeOfCopy + * determines whether copy is used by augmentation or uses + * @throws SourceException + */ + private void copyDeclaredStmts(RootStatementContext original, QNameModule newQNameModule, + TypeOfCopy typeOfCopy) throws SourceException { + Collection> originalDeclaredSubstatements = original.declaredSubstatements(); for (StmtContext stmtContext : originalDeclaredSubstatements) { - this.addEffectiveSubstatement(stmtContext.createCopy( - newQNameModule, this, typeOfCopy)); + this.addEffectiveSubstatement(stmtContext.createCopy(newQNameModule, this, typeOfCopy)); } } - private void copyEffectiveStmts(RootStatementContext original, - QNameModule newQNameModule, TypeOfCopy typeOfCopy) - throws SourceException { - Collection> originalEffectiveSubstatements = original - .effectiveSubstatements(); + /** + * copies effective statements from original to this' substatements + * + * @param typeOfCopy + * determines whether copy is used by augmentation or uses + * @throws SourceException + */ + private void copyEffectiveStmts(RootStatementContext original, QNameModule newQNameModule, + TypeOfCopy typeOfCopy) throws SourceException { + Collection> originalEffectiveSubstatements = original.effectiveSubstatements(); for (StmtContext stmtContext : originalEffectiveSubstatements) { - this.addEffectiveSubstatement(stmtContext.createCopy( - newQNameModule, this, typeOfCopy)); + this.addEffectiveSubstatement(stmtContext.createCopy(newQNameModule, this, typeOfCopy)); } } + /** + * @return null as root cannot have parent + */ @Override public StatementContextBase getParentContext() { return null; } + /** + * @return namespace storage of source context + */ @Override public NamespaceStorageNode getParentNamespaceStorage() { return sourceContext; } + /** + * @return registry of source context + */ @Override public Registry getBehaviourRegistry() { return sourceContext; } + /** + * @return this as its own root + */ @Override public RootStatementContext getRoot() { return this; @@ -98,26 +117,57 @@ class RootStatementContext, E extends Effectiv return argument; } + /** + * @return copy of this considering {@link TypeOfCopy} (augment, uses) + * + * @throws SourceException + */ @Override - public StatementContextBase createCopy(QNameModule newQNameModule, - StatementContextBase newParent, TypeOfCopy typeOfCopy) + public StatementContextBase createCopy(StatementContextBase newParent, TypeOfCopy typeOfCopy) throws SourceException { - RootStatementContext copy = new RootStatementContext<>(this, - newQNameModule, typeOfCopy); + return createCopy(null, newParent, typeOfCopy); + } + + /** + * @return copy of this considering {@link TypeOfCopy} (augment, uses) + * + * @throws SourceException + */ + @Override + public StatementContextBase createCopy(QNameModule newQNameModule, + StatementContextBase newParent, TypeOfCopy typeOfCopy) throws SourceException { + RootStatementContext copy = new RootStatementContext<>(this, newQNameModule, typeOfCopy); copy.setTypeOfCopy(typeOfCopy); copy.setOriginalCtx(this); return copy; } + /** + * @return this' argument as it is the only from root (this) + */ @Override public List getArgumentsFromRoot() { - List argumentList = new LinkedList(); + List argumentList = new LinkedList<>(); argumentList.add(argument); return argumentList; } + /** + * @return this as it is the only\context from root (this) + */ + @Override + public List> getStmtContextsFromRoot() { + List> stmtContextsList = new LinkedList<>(); + stmtContextsList.add(this); + return stmtContextsList; + } + + /** + * @return true + */ @Override public boolean isRootContext() { return true; } + } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java index ce245436ad..24315021f3 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java @@ -7,16 +7,14 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.reactor; +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.BinarySpecificationImpl; +import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import com.google.common.base.Preconditions; import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Multimap; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Objects; -import javax.annotation.Nullable; import org.opendaylight.yangtools.concepts.Mutable; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; @@ -41,9 +39,23 @@ import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinit 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.BitsSpecificationImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Decimal64SpecificationImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.EnumSpecificationImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.UnknownEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.IdentityRefSpecificationImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.InstanceIdentifierSpecificationImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.LeafrefSpecificationImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.UnionSpecificationImpl; import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.UnknownStatementImpl; import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Objects; public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBehaviour.Registry, Mutable { @@ -58,50 +70,99 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh private final Collection importedNamespaces = new ArrayList<>(); private final Multimap modifiers = HashMultimap.create(); - private RootStatementContext root; + private RootStatementContext root; private ModelProcessingPhase inProgressPhase; - private ModelProcessingPhase finishedPhase; - private final QNameToStatementDefinitionMap qNameToStmtDefMap = new QNameToStatementDefinitionMap(); - private final PrefixToModuleMap prefixToModuleMap = new PrefixToModuleMap(); + private ModelProcessingPhase finishedPhase = ModelProcessingPhase.INIT; + private QNameToStatementDefinitionMap qNameToStmtDefMap = new QNameToStatementDefinitionMap(); + private PrefixToModuleMap prefixToModuleMap = new PrefixToModuleMap(); - SourceSpecificContext(final BuildGlobalContext currentContext,final StatementStreamSource source) { + SourceSpecificContext(BuildGlobalContext currentContext, StatementStreamSource source) { this.source = source; this.currentContext = currentContext; } - StatementDefinitionContext getDefinition(final QName name) { + ModelProcessingPhase getInProgressPhase() { + return inProgressPhase; + } + + StatementDefinitionContext getDefinition(QName name) { return currentContext.getStatementDefinition(name); } - ContextBuilder createDeclaredChild(final StatementContextBase current, final QName name, final StatementSourceReference ref) { - StatementDefinitionContext def = getDefinition(name); + ContextBuilder createDeclaredChild(StatementContextBase current, QName name, StatementSourceReference ref) { + StatementDefinitionContext def = getDefinition(name); - //extensions if (def == null) { - if (Utils.isValidStatementDefinition(prefixToModuleMap, qNameToStmtDefMap, name)) { - def = new StatementDefinitionContext<>(new UnknownStatementImpl.Definition(qNameToStmtDefMap.get(Utils.trimPrefix(name)))); + //unknown-stmts (from import, include or local-scope) + if (qNameToStmtDefMap.get(Utils.trimPrefix(name)) != null) { + QName key = Utils.qNameFromArgument(current, name.getLocalName()); + if (key != null) { + final StatementContextBase extension = (StatementContextBase) currentContext + .getAllFromNamespace(ExtensionNamespace.class).get(key); + if (extension != null) { + final QName qName = QName.create(((QName) ((SubstatementContext) extension).getStatementArgument()) + .getModule().getNamespace(), ((QName) ((SubstatementContext) extension). + getStatementArgument()).getModule().getRevision(), extension.getIdentifier().getArgument()); + + def = new StatementDefinitionContext<>(new UnknownStatementImpl.Definition + (getNewStatementDefinition(qName))); + } else { + throw new IllegalArgumentException("Not found unknown statement: " + name); + } + } + } else { + //type-body-stmts + def = resolveTypeBodyStmts(name.getLocalName()); } } Preconditions.checkArgument(def != null, "Statement %s does not have type mapping defined.", name); - if(current == null) { - return createDeclaredRoot(def,ref); + if (current == null) { + return createDeclaredRoot(def, ref); } return current.substatementBuilder(def, ref); } - @SuppressWarnings({ "rawtypes", "unchecked" }) - private ContextBuilder createDeclaredRoot(final StatementDefinitionContext def, final StatementSourceReference ref) { - return new ContextBuilder(def,ref) { + StatementDefinition getNewStatementDefinition(final QName qName) { + return new StatementDefinition() { + @Nonnull + @Override + public QName getStatementName() { + return qName; + } + + @Nullable + @Override + public QName getArgumentName() { + return qName; + } + + @Nonnull + @Override + public Class> getDeclaredRepresentationClass() { + return UnknownStatementImpl.class; + } + + @Nonnull + @Override + public Class> getEffectiveRepresentationClass() { + return UnknownEffectiveStatementImpl.class; + } + }; + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + private ContextBuilder createDeclaredRoot(StatementDefinitionContext def, StatementSourceReference ref) { + return new ContextBuilder(def, ref) { @Override public StatementContextBase build() throws SourceException { - if(root == null) { + if (root == null) { root = new RootStatementContext(this, SourceSpecificContext.this); } else { - Preconditions.checkState(root.getIdentifier().equals(getIdentifier()), "Root statement was already defined as %s.", root.getIdentifier()); + Preconditions.checkState(root.getIdentifier().equals(createIdentifier()), "Root statement was already defined as %s.", root.getIdentifier()); } root.resetLists(); return root; @@ -110,7 +171,7 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh }; } - RootStatementContext getRoot() { + RootStatementContext getRoot() { return root; } @@ -118,7 +179,7 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh return root.buildDeclared(); } - EffectiveStatement buildEffective() { + EffectiveStatement buildEffective() { return root.buildEffective(); } @@ -131,7 +192,7 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh @Override public > void addToLocalStorage(final Class type, final K key, final V value) { - if(ImportedNamespaceContext.class.isAssignableFrom(type)) { + if (ImportedNamespaceContext.class.isAssignableFrom(type)) { importedNamespaces.add((NamespaceStorageNode) value); } getRoot().addToLocalStorage(type, key, value); @@ -145,12 +206,31 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh @Override public > V getFromLocalStorage(final Class type, final K key) { final V potentialLocal = getRoot().getFromLocalStorage(type, key); - if(potentialLocal != null) { + if (potentialLocal != null) { return potentialLocal; } - for(NamespaceStorageNode importedSource : importedNamespaces) { + for (NamespaceStorageNode importedSource : importedNamespaces) { V potential = importedSource.getFromLocalStorage(type, key); - if(potential != null) { + if (potential != null) { + return potential; + } + } + return null; + } + + @Nullable + @Override + public > Map getAllFromLocalStorage(final Class type) { + final Map potentialLocal = getRoot().getAllFromLocalStorage(type); + + if (potentialLocal != null) { + return potentialLocal; + } + + for (final NamespaceStorageNode importedSource : importedNamespaces) { + final Map potential = importedSource.getAllFromLocalStorage(type); + + if (potential != null) { return potential; } } @@ -176,12 +256,12 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh hasProgressed = (hasProgress(currentPhaseModifiers) | hasProgressed); - if(phaseCompleted && (currentPhaseModifiers.isEmpty())) { + if (phaseCompleted && (currentPhaseModifiers.isEmpty())) { finishedPhase = phase; return PhaseCompletionProgress.FINISHED; } - if(hasProgressed) { + if (hasProgressed) { return PhaseCompletionProgress.PROGRESS; } return PhaseCompletionProgress.NO_PROGRESS; @@ -192,8 +272,8 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh Iterator modifier = currentPhaseModifiers.iterator(); boolean hasProgressed = false; - while(modifier.hasNext()) { - if(modifier.next().isApplied()) { + while (modifier.hasNext()) { + if (modifier.next().isApplied()) { modifier.remove(); hasProgressed = true; } @@ -219,7 +299,7 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh InferenceException sourceEx = new InferenceException("Fail to infer source relationships", root.getStatementSourceReference()); - for(ModifierImpl mod : modifiers.get(identifier)) { + for (ModifierImpl mod : modifiers.get(identifier)) { try { mod.failModifier(); } catch (SourceException e) { @@ -232,21 +312,45 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh void loadStatements() throws SourceException { switch (inProgressPhase) { case SOURCE_LINKAGE: - source.writeLinkage(new StatementContextWriter(this, inProgressPhase),stmtDef()); - break; + source.writeLinkage(new StatementContextWriter(this, inProgressPhase), stmtDef()); + break; case STATEMENT_DEFINITION: - source.writeLinkageAndStatementDefinitions(new StatementContextWriter(this, inProgressPhase), stmtDef(), prefixes()); - break; + source.writeLinkageAndStatementDefinitions(new StatementContextWriter(this, inProgressPhase), stmtDef(), prefixes()); + break; case FULL_DECLARATION: - source.writeFull(new StatementContextWriter(this, inProgressPhase), stmtDef(), prefixes()); - break; - default: - break; + source.writeFull(new StatementContextWriter(this, inProgressPhase), stmtDef(), prefixes()); + break; + default: + break; } } + private StatementDefinitionContext resolveTypeBodyStmts(String typeArgument) { + switch (typeArgument) { + case TypeUtils.DECIMAL64: + return new StatementDefinitionContext<>(new Decimal64SpecificationImpl.Definition()); + case TypeUtils.UNION: + return new StatementDefinitionContext<>(new UnionSpecificationImpl.Definition()); + case TypeUtils.ENUMERATION: + return new StatementDefinitionContext<>(new EnumSpecificationImpl.Definition()); + case TypeUtils.LEAF_REF: + return new StatementDefinitionContext<>(new LeafrefSpecificationImpl.Definition()); + case TypeUtils.BITS: + return new StatementDefinitionContext<>(new BitsSpecificationImpl.Definition()); + case TypeUtils.IDENTITY_REF: + return new StatementDefinitionContext<>(new IdentityRefSpecificationImpl.Definition()); + case TypeUtils.INSTANCE_IDENTIFIER: + return new StatementDefinitionContext<>(new InstanceIdentifierSpecificationImpl.Definition()); + case TypeUtils.BINARY: + return new StatementDefinitionContext<>(new BinarySpecificationImpl.Definition()); + default: + return null; + } + } + + private PrefixToModule prefixes() { - Map prefixes = (Map) currentContext.getAllFromNamespace(PrefixToModule.class); + Map prefixes = currentContext.getAllFromNamespace(PrefixToModule.class); for (Map.Entry prefix : prefixes.entrySet()) { prefixToModuleMap.put(prefix.getKey(), prefix.getValue()); } @@ -257,16 +361,23 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh //regular YANG statements added ImmutableMap> definitions = currentContext.getSupportsForPhase( inProgressPhase).getDefinitions(); - for (Map.Entry> entry : definitions.entrySet()) { + for (Map.Entry> entry : definitions.entrySet()) { qNameToStmtDefMap.put(entry.getKey(), entry.getValue()); } //extensions added if (inProgressPhase.equals(ModelProcessingPhase.FULL_DECLARATION)) { - Map> extensions = (Map>) currentContext.getAllFromNamespace(ExtensionNamespace.class); + Map>> extensions = currentContext + .getAllFromNamespace(ExtensionNamespace.class); if (extensions != null) { - for (Map.Entry> extension : extensions.entrySet()) { - qNameToStmtDefMap.put(new QName(YangConstants.RFC6020_YIN_NAMESPACE, extension.getKey().getLocalName()), (StatementDefinition) extension.getValue().definition().getFactory()); + for (Map.Entry>> extension : extensions + .entrySet()) { + qNameToStmtDefMap + .put(new QName(YangConstants.RFC6020_YIN_NAMESPACE, + extension.getKey().getLocalName()), + (StatementDefinition) ((StatementContextBase) extension + .getValue()).definition() + .getFactory()); } } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java index 4ce2f5b9f3..02e37329d8 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java @@ -20,6 +20,7 @@ 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.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.IdentifierNamespace; @@ -30,83 +31,43 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; 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, E extends EffectiveStatement> - extends NamespaceStorageSupport implements - StmtContext.Mutable, Identifiable { + extends NamespaceStorageSupport implements StmtContext.Mutable, Identifiable { + /** + * event listener when an item is added to model namespace + */ interface OnNamespaceItemAdded extends EventListener { - void namespaceItemAdded(StatementContextBase context, - Class namespace, Object key, Object value) + void namespaceItemAdded(StatementContextBase context, Class namespace, Object key, Object value) throws SourceException; } + /** + * event listener when a parsing {@link ModelProcessingPhase} is completed + */ interface OnPhaseFinished extends EventListener { - boolean phaseFinished(StatementContextBase context, - ModelProcessingPhase phase) throws SourceException; + boolean phaseFinished(StatementContextBase context, ModelProcessingPhase phase) throws SourceException; } + /** + * interface for all mutations within an {@link ModelActionBuilder.InferenceAction} + */ interface ContextMutation { boolean isFinished(); } - abstract static class ContextBuilder, E extends EffectiveStatement> { - - private final StatementDefinitionContext definition; - private final StatementSourceReference stmtRef; - private String rawArg; - private StatementSourceReference argRef; - - public ContextBuilder(StatementDefinitionContext 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."); - this.rawArg = Preconditions.checkNotNull(argument); - this.argRef = Preconditions.checkNotNull(argumentSource); - } - - public String getRawArgument() { - return rawArg; - } - - public StatementSourceReference getStamementSource() { - return stmtRef; - } - - public StatementSourceReference getArgumentSource() { - return argRef; - } - - public StatementDefinitionContext getDefinition() { - return definition; - } - - public StatementIdentifier getIdentifier() { - return new StatementIdentifier(definition.getStatementName(), - rawArg); - } - - public abstract StatementContextBase build() - throws SourceException; - - } - private final StatementDefinitionContext definition; private final StatementIdentifier identifier; private final StatementSourceReference statementDeclSource; @@ -115,13 +76,20 @@ public abstract class StatementContextBase, E private Collection> declared = new ArrayList<>(); private Collection> effective = new ArrayList<>(); + private Collection> effectOfStatement = new ArrayList<>(); + + public Collection> getEffectOfStatement() { + return effectOfStatement; + } + + public void addAsEffectOfStatement(StatementContextBase ctx) { + effectOfStatement.add(ctx); + } private ModelProcessingPhase completedPhase; - private Multimap phaseListeners = HashMultimap - .create(); - private Multimap phaseMutation = HashMultimap - .create(); + private Multimap phaseListeners = HashMultimap.create(); + private Multimap phaseMutation = HashMultimap.create(); private D declaredInstance; private E effectiveInstance; @@ -129,6 +97,18 @@ public abstract class StatementContextBase, E private StatementContextBase originalCtx; private TypeOfCopy typeOfCopy = TypeOfCopy.ORIGINAL; + private boolean isSupportedToBuildEffective = true; + + @Override + public boolean isSupportedToBuildEffective() { + return isSupportedToBuildEffective; + } + + @Override + public void setIsSupportedToBuildEffective(boolean isSupportedToBuildEffective) { + this.isSupportedToBuildEffective = isSupportedToBuildEffective; + } + @Override public TypeOfCopy getTypeOfCopy() { return typeOfCopy; @@ -159,89 +139,160 @@ public abstract class StatementContextBase, E this.completedPhase = completedPhase; } - StatementContextBase(@Nonnull ContextBuilder builder) - throws SourceException { + StatementContextBase(@Nonnull ContextBuilder builder) throws SourceException { this.definition = builder.getDefinition(); - this.identifier = builder.getIdentifier(); + this.identifier = builder.createIdentifier(); this.statementDeclSource = builder.getStamementSource(); this.completedPhase = null; } StatementContextBase(StatementContextBase original) { - this.definition = original.definition; - this.identifier = original.identifier; - this.statementDeclSource = original.statementDeclSource; + this.definition = Preconditions + .checkNotNull(original.definition, "Statement context definition cannot be null"); + this.identifier = Preconditions + .checkNotNull(original.identifier, "Statement context identifier cannot be null"); + this.statementDeclSource = Preconditions.checkNotNull(original.statementDeclSource, + "Statement context statementDeclSource cannot be null"); this.completedPhase = null; } + /** + * @return context of parent of statement + */ @Override public abstract StatementContextBase getParentContext(); + /** + * @return root context of statement + */ @Override public abstract RootStatementContext getRoot(); + /** + * @return statement identifier + */ @Override public StatementIdentifier getIdentifier() { return identifier; } + /** + * @return origin of statement + */ @Override public StatementSource getStatementSource() { return statementDeclSource.getStatementSource(); } + /** + * @return reference of statement source + */ @Override public StatementSourceReference getStatementSourceReference() { return statementDeclSource; } + /** + * @return raw statement argument string + */ @Override public String rawStatementArgument() { return identifier.getArgument(); } + /** + * @return collection of declared substatements + */ @Override public Collection> declaredSubstatements() { return Collections.unmodifiableCollection(declared); } + /** + * @return collection of effective substatements + */ @Override public Collection> effectiveSubstatements() { return Collections.unmodifiableCollection(effective); } - public void addEffectiveSubstatement( - StatementContextBase substatement) { - effective.add(substatement); + public void removeStatementsFromEffectiveSubstatements(Collection> substatements) { + effective.removeAll(substatements); + } + + public void removeStatementFromEffectiveSubstatements(StatementDefinition refineSubstatementDef) { + Iterator> iterator = effective.iterator(); + while (iterator.hasNext()) { + StatementContextBase next = iterator.next(); + if (next.getPublicDefinition().equals(refineSubstatementDef)) { + iterator.remove(); + } + } + } + + /** + * adds effective statement to collection of substatements + * + * @throws IllegalStateException + * if added in declared phase + * @throws NullPointerException + * if statement parameter is null + */ + public void addEffectiveSubstatement(StatementContextBase substatement) { + + final ModelProcessingPhase inProgressPhase = getRoot().getSourceContext().getInProgressPhase(); + Preconditions.checkState(inProgressPhase == ModelProcessingPhase.FULL_DECLARATION + || inProgressPhase == ModelProcessingPhase.EFFECTIVE_MODEL, + "Effective statement cannot be added in declared phase"); + + effective.add(Preconditions.checkNotNull(substatement, + "StatementContextBase effective substatement cannot be null")); } - public void addDeclaredSubstatement( - StatementContextBase substatement) { - declared.add(substatement); + /** + * adds declared statement to collection of substatements + * + * @throws IllegalStateException + * if added in effective phase + * @throws NullPointerException + * if statement parameter is null + */ + public void addDeclaredSubstatement(StatementContextBase substatement) { + + final ModelProcessingPhase inProgressPhase = getRoot().getSourceContext().getInProgressPhase(); + Preconditions.checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL, + "Declared statement cannot be added in effective phase"); + + declared.add(Preconditions.checkNotNull(substatement, + "StatementContextBase declared substatement cannot be null")); } + /** + * builds new substatement from statement definition context and statement source reference + */ @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()); + StatementContextBase potential = null; + + if (getDefinition().getPublicView() != Rfc6020Mapping.AUGMENT) { + potential = substatements.get(createIdentifier()); + } if (potential == null) { - potential = new SubstatementContext( - StatementContextBase.this, this); - substatements.put(getIdentifier(), potential); + potential = new SubstatementContext(StatementContextBase.this, this); + substatements.put(createIdentifier(), potential); } potential.resetLists(); switch (this.getStamementSource().getStatementSource()) { case DECLARATION: - declared.add(potential); + addDeclaredSubstatement(potential); break; case CONTEXT: - effective.add(potential); + addEffectiveSubstatement(potential); break; } return potential; @@ -249,22 +300,30 @@ public abstract class StatementContextBase, E }; } + /** + * @return local namespace behaviour type {@link NamespaceBehaviour} + */ @Override public StorageNodeType getStorageNodeType() { return StorageNodeType.STATEMENT_LOCAL; } + /** + * builds {@link DeclaredStatement} for statement context + */ @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); } return declaredInstance; } + /** + * builds {@link EffectiveStatement} for statement context + */ @Override public E buildEffective() { if (effectiveInstance == null) { @@ -273,14 +332,32 @@ public abstract class StatementContextBase, E return effectiveInstance; } + /** + * clears collection of declared substatements + * + * @throws IllegalStateException + * if invoked in effective build phase + */ void resetLists() { + + final SourceSpecificContext sourceContext = getRoot().getSourceContext(); + Preconditions.checkState(sourceContext.getInProgressPhase() != ModelProcessingPhase.EFFECTIVE_MODEL, + "Declared statements list cannot be cleared in effective phase"); + declared.clear(); } - boolean tryToCompletePhase(ModelProcessingPhase phase) - throws SourceException { - Iterator openMutations = phaseMutation.get(phase) - .iterator(); + /** + * tries to execute current {@link ModelProcessingPhase} of source parsing + * + * @param phase + * to be executed (completed) + * @return if phase was successfully completed + * @throws SourceException + * when an error occured in source parsing + */ + boolean tryToCompletePhase(ModelProcessingPhase phase) throws SourceException { + Iterator openMutations = phaseMutation.get(phase).iterator(); boolean finished = true; while (openMutations.hasNext()) { ContextMutation current = openMutations.next(); @@ -304,66 +381,72 @@ public abstract class StatementContextBase, E return false; } - private void onPhaseCompleted(ModelProcessingPhase phase) - throws SourceException { + /** + * occurs on end of {@link ModelProcessingPhase} of source parsing + * + * @param phase + * that was to be completed (finished) + * @throws SourceException + * when an error occured in source parsing + */ + private void onPhaseCompleted(ModelProcessingPhase phase) throws SourceException { completedPhase = phase; - Iterator listener = phaseListeners.get(completedPhase) - .iterator(); + Iterator listener = phaseListeners.get(completedPhase).iterator(); while (listener.hasNext()) { OnPhaseFinished next = listener.next(); - if(next.phaseFinished(this, phase)) { - listener.remove(); + if (next.phaseFinished(this, phase)) { + listener.remove(); } } } /** - * * Ends declared section of current node. * * @param ref * @throws SourceException - * */ - void endDeclared(StatementSourceReference ref, ModelProcessingPhase phase) - throws SourceException { + void endDeclared(StatementSourceReference ref, ModelProcessingPhase phase) throws SourceException { definition().onDeclarationFinished(this, phase); } + /** + * @return statement definition + */ protected final StatementDefinitionContext definition() { return definition; } @Override - protected void checkLocalNamespaceAllowed( - Class> type) { + protected void checkLocalNamespaceAllowed(Class> type) { definition().checkNamespaceAllowed(type); } + /** + * occurs when an item is added to model namespace + * + * @throws SourceException + */ @Override - protected > void onNamespaceElementAdded( - Class type, K key, V value) { + protected > void onNamespaceElementAdded(Class type, K key, V value) { // definition().onNamespaceElementAdded(this, type, key, value); } - > void onNamespaceItemAddedAction( - final Class type, K key, final OnNamespaceItemAdded listener) - throws SourceException { + > void onNamespaceItemAddedAction(final Class type, K key, + final OnNamespaceItemAdded listener) throws SourceException { Object potential = getFromNamespace(type, key); if (potential != null) { listener.namespaceItemAdded(this, type, key, potential); return; } - NamespaceBehaviour behaviour = getBehaviourRegistry() - .getNamespaceBehaviour(type); + NamespaceBehaviour behaviour = getBehaviourRegistry().getNamespaceBehaviour(type); if (behaviour instanceof NamespaceBehaviourWithListeners) { NamespaceBehaviourWithListeners casted = (NamespaceBehaviourWithListeners) 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); } @@ -372,18 +455,32 @@ public abstract class StatementContextBase, E } } + /** + * @see StatementSupport#getPublicView() + */ @Override public StatementDefinition getPublicDefinition() { return definition().getPublicView(); } + /** + * @return new {@link ModelActionBuilder} for the phase + */ @Override public ModelActionBuilder newInferenceAction(ModelProcessingPhase phase) { return getRoot().getSourceContext().newInferenceAction(phase); } - void addPhaseCompletedListener(ModelProcessingPhase phase, - OnPhaseFinished listener) throws SourceException { + /** + * adds {@link OnPhaseFinished} listener for a {@link ModelProcessingPhase} end + * + * @throws SourceException + */ + void addPhaseCompletedListener(ModelProcessingPhase phase, OnPhaseFinished listener) throws SourceException { + + Preconditions.checkNotNull(phase, "Statement context processing phase cannot be null"); + Preconditions.checkNotNull(listener, "Statement context phase listener cannot be null"); + ModelProcessingPhase finishedPhase = completedPhase; while (finishedPhase != null) { if (phase.equals(finishedPhase)) { @@ -395,21 +492,36 @@ public abstract class StatementContextBase, E phaseListeners.put(phase, listener); } + /** + * adds {@link ContextMutation} to {@link ModelProcessingPhase} + * + * @throws IllegalStateException + * when the mutation was registered after phase was completed + */ 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."); + throw new IllegalStateException("Mutation registered after phase was completed."); } finishedPhase = finishedPhase.getPreviousPhase(); } phaseMutation.put(phase, mutation); } + /** + * adds statement to namespace map with the key + * + * @param namespace + * {@link StatementNamespace} child that determines namespace to be added to + * @param key + * of type according to namespace class specification + * @param stmt + * to be added to namespace map + */ @Override - public > void addContext( - Class namespace, KT key, StmtContext stmt) { + public > void addContext(Class namespace, KT key, + StmtContext stmt) { addContextToNamespace(namespace, (K) key, stmt); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextWriter.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextWriter.java index 3a1a8b787b..7ad0bae9a7 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextWriter.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextWriter.java @@ -8,12 +8,12 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor; import com.google.common.base.Preconditions; +import javax.annotation.Nonnull; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; 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.StatementWriter; -import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase.ContextBuilder; class StatementContextWriter implements StatementWriter { @@ -36,7 +36,7 @@ class StatementContextWriter implements StatementWriter { @Override public void argumentValue(String value, StatementSourceReference ref) { - Preconditions.checkState(current != null, "Could not two arguments for one statement."); + Preconditions.checkState(current != null, "Could not set two arguments for one statement."); current.setArgument(value, ref); } @@ -55,4 +55,10 @@ class StatementContextWriter implements StatementWriter { parent = parent.getParentContext(); } + @Nonnull + @Override + public ModelProcessingPhase getPhase() { + return phase; + } + } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java index f921e13b2a..76e3a45baa 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java @@ -7,6 +7,10 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.reactor; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; +import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import java.util.List; import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.GroupingUtils; import org.opendaylight.yangtools.yang.common.QNameModule; @@ -34,6 +38,7 @@ class SubstatementContext, E extends Effective builder.getRawArgument()); } + @SuppressWarnings("unchecked") SubstatementContext(SubstatementContext original, QNameModule newQNameModule, StatementContextBase newParent, TypeOfCopy typeOfCopy) @@ -41,10 +46,20 @@ class SubstatementContext, E extends Effective super(original); this.parent = newParent; - if (newQNameModule != null && original.argument instanceof QName) { - QName originalQName = (QName) original.argument; - this.argument = (A) QName.create(newQNameModule, - originalQName.getLocalName()); + if (newQNameModule != null) { + if (original.argument instanceof QName) { + QName originalQName = (QName) original.argument; + this.argument = (A) QName.create(newQNameModule, + originalQName.getLocalName()); + } else if (StmtContextUtils.producesDeclared(original, + KeyStatement.class)) { + this.argument = (A) StmtContextUtils + .replaceModuleQNameForKey( + (StmtContext, KeyStatement, ?>) original, + newQNameModule); + } else { + this.argument = original.argument; + } } else { this.argument = original.argument; } @@ -111,6 +126,13 @@ class SubstatementContext, E extends Effective return argument; } + @Override + public StatementContextBase createCopy( + StatementContextBase newParent, TypeOfCopy typeOfCopy) + throws SourceException { + return createCopy(null, newParent, typeOfCopy); + } + @Override public StatementContextBase createCopy(QNameModule newQNameModule, StatementContextBase newParent, TypeOfCopy typeOfCopy) @@ -129,6 +151,14 @@ class SubstatementContext, E extends Effective return argumentsFromRoot; } + @Override + public List> getStmtContextsFromRoot() { + List> stmtContextsList = parent + .getStmtContextsFromRoot(); + stmtContextsList.add(this); + return stmtContextsList; + } + @Override public boolean isRootContext() { return false; diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentStatementImpl.java index 43af34cde4..ec649af866 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentStatementImpl.java @@ -7,6 +7,7 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; import java.util.Collection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,6 +72,10 @@ public class AugmentStatementImpl extends final StmtContext.Mutable> augmentNode) throws SourceException { + if(StmtContextUtils.isInExtensionBody(augmentNode)) { + return; + } + final ModelActionBuilder augmentAction = augmentNode .newInferenceAction(ModelProcessingPhase.FULL_DECLARATION); final ModelActionBuilder.Prerequisite>> sourceCtxPrereq = augmentAction @@ -88,13 +93,17 @@ public class AugmentStatementImpl extends if (augmentTargetCtx == null) { throw new InferenceException("Augment target not found: "+augmentNode.getStatementArgument(), augmentNode.getStatementSourceReference()); } + if (StmtContextUtils.isInExtensionBody(augmentTargetCtx)) { + augmentNode.setIsSupportedToBuildEffective(false); + return; + } - final StatementContextBase augmentSourceCtx = (StatementContextBase) sourceCtxPrereq - .get(); + final StatementContextBase augmentSourceCtx = (StatementContextBase) augmentNode; try { AugmentUtils.copyFromSourceToTarget(augmentSourceCtx, augmentTargetCtx); + augmentTargetCtx.addEffectiveSubstatement(augmentSourceCtx); } catch (SourceException e) { LOG.warn(e.getMessage(), e); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java index 9d99af203a..46c2954b9d 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java @@ -7,34 +7,45 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import java.util.Iterator; -import javax.annotation.Nullable; +import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.google.common.collect.ImmutableList.Builder; import java.util.Collection; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; +import javax.annotation.Nullable; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; 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.DataDefinitionStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; 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.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.StmtContext.TypeOfCopy; 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.spi.validation.ValidationBundlesNamespace; +import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType; import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase; public final class AugmentUtils { + private static final Logger LOG = LoggerFactory.getLogger(AugmentUtils.class); + private static final String REGEX_PATH_REL1 = "\\.\\.?\\s*/(.+)"; private static final String REGEX_PATH_REL2 = "//.*"; @@ -56,23 +67,34 @@ public final class AugmentUtils { StatementContextBase sourceCtx, StatementContextBase targetCtx) throws SourceException { - QNameModule newQNameModule = getNewQNameModule(targetCtx, sourceCtx); - copyDeclaredStmts(sourceCtx, targetCtx, newQNameModule); - copyEffectiveStmts(sourceCtx, targetCtx, newQNameModule); - + copyDeclaredStmts(sourceCtx, targetCtx); + copyEffectiveStmts(sourceCtx, targetCtx); } public static void copyDeclaredStmts( StatementContextBase sourceCtx, - StatementContextBase targetCtx, QNameModule newQNameModule) - throws SourceException { - Collection> declaredSubstatements = sourceCtx + StatementContextBase targetCtx) throws SourceException { + + Collection> declaredSubStatements = sourceCtx .declaredSubstatements(); - for (StatementContextBase originalStmtCtx : declaredSubstatements) { + final List subStatements = new Builder() + .addAll(targetCtx.declaredSubstatements()) + .addAll(targetCtx.effectiveSubstatements()).build(); + boolean sourceAndTargetInSameModule = Utils.getRootModuleQName( + sourceCtx).equals(Utils.getRootModuleQName(targetCtx)); + + TypeOfCopy typeOfCopy = sourceCtx.getParentContext() + .getPublicDefinition().getDeclaredRepresentationClass() + .equals(UsesStatement.class) ? TypeOfCopy.ADDED_BY_USES_AUGMENTATION + : TypeOfCopy.ADDED_BY_AUGMENTATION; + + for (StatementContextBase originalStmtCtx : declaredSubStatements) { if (needToCopyByAugment(originalStmtCtx)) { + validateNodeCanBeCopiedByAugment(originalStmtCtx, + subStatements, sourceAndTargetInSameModule); + StatementContextBase copy = originalStmtCtx - .createCopy(newQNameModule, targetCtx, - TypeOfCopy.ADDED_BY_AUGMENTATION); + .createCopy(targetCtx, typeOfCopy); targetCtx.addEffectiveSubstatement(copy); } else if (isReusedByAugment(originalStmtCtx)) { targetCtx.addEffectiveSubstatement(originalStmtCtx); @@ -82,15 +104,28 @@ public final class AugmentUtils { public static void copyEffectiveStmts( StatementContextBase sourceCtx, - StatementContextBase targetCtx, QNameModule newQNameModule) - throws SourceException { + StatementContextBase targetCtx) throws SourceException { + Collection> effectiveSubstatements = sourceCtx .effectiveSubstatements(); + final List subStatements = new Builder() + .addAll(targetCtx.declaredSubstatements()) + .addAll(targetCtx.effectiveSubstatements()).build(); + boolean sourceAndTargetInSameModule = Utils.getRootModuleQName( + sourceCtx).equals(Utils.getRootModuleQName(targetCtx)); + + TypeOfCopy typeOfCopy = sourceCtx.getParentContext() + .getPublicDefinition().getDeclaredRepresentationClass() + .equals(UsesStatement.class) ? TypeOfCopy.ADDED_BY_USES_AUGMENTATION + : TypeOfCopy.ADDED_BY_AUGMENTATION; + for (StatementContextBase originalStmtCtx : effectiveSubstatements) { if (needToCopyByAugment(originalStmtCtx)) { + validateNodeCanBeCopiedByAugment(originalStmtCtx, + subStatements, sourceAndTargetInSameModule); + StatementContextBase copy = originalStmtCtx - .createCopy(newQNameModule, targetCtx, - TypeOfCopy.ADDED_BY_AUGMENTATION); + .createCopy(targetCtx, typeOfCopy); targetCtx.addEffectiveSubstatement(copy); } else if (isReusedByAugment(originalStmtCtx)) { targetCtx.addEffectiveSubstatement(originalStmtCtx); @@ -98,15 +133,63 @@ public final class AugmentUtils { } } + private static void validateNodeCanBeCopiedByAugment( + final StatementContextBase sourceCtx, + final List targetSubStatements, + boolean sourceAndTargetInSameModule) { + + if (sourceCtx.getPublicDefinition().getDeclaredRepresentationClass() + .equals(WhenStatement.class)) { + return; + } + + if (!sourceAndTargetInSameModule) { + final List sourceSubStatements = new Builder() + .addAll(sourceCtx.declaredSubstatements()) + .addAll(sourceCtx.effectiveSubstatements()).build(); + + for (final StatementContextBase sourceSubStatement : sourceSubStatements) { + if (sourceSubStatement.getPublicDefinition() + .getDeclaredRepresentationClass() + .equals(MandatoryStatement.class)) { + throw new IllegalArgumentException( + String.format( + "An augment cannot add node '%s' because it is mandatory and in module different from target", + sourceCtx.rawStatementArgument())); + } + } + } + + for (final StatementContextBase subStatement : targetSubStatements) { + + final boolean sourceIsDataNode = DataDefinitionStatement.class + .isAssignableFrom(sourceCtx.getPublicDefinition() + .getDeclaredRepresentationClass()); + final boolean targetIsDataNode = DataDefinitionStatement.class + .isAssignableFrom(subStatement.getPublicDefinition() + .getDeclaredRepresentationClass()); + boolean qNamesEqual = sourceIsDataNode + && targetIsDataNode + && Objects.equals(sourceCtx.getStatementArgument(), + subStatement.getStatementArgument()); + + if (qNamesEqual) { + throw new IllegalStateException( + String.format( + "An augment cannot add node named '%s' because this name is already used in target", + sourceCtx.rawStatementArgument())); + } + } + } + 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); + ModuleCtxToModuleQName.class, root); if (targetStmtArgument instanceof QName) { QName targetQName = (QName) targetStmtArgument; @@ -152,7 +235,6 @@ public final class AugmentUtils { } List> rootStatementCtxList = new LinkedList<>(); - if (augmentTargetNode.isAbsolute()) { QNameModule module = augmentTargetNode.getPathFromRoot().iterator() @@ -230,29 +312,50 @@ public final class AugmentUtils { allSubstatements.addAll(effectiveSubstatement); for (StatementContextBase substatement : allSubstatements) { - if (isAllowedAugmentTarget(substatement) - && nextPathQName - .equals(substatement.getStatementArgument())) { - return substatement; + Object substatementArgument = substatement.getStatementArgument(); + QName substatementQName; + if (substatementArgument instanceof QName) { + substatementQName = (QName) substatementArgument; + + if (isSupportedAugmentTarget(substatement) + && nextPathQName.getLocalName().equals( + substatementQName.getLocalName())) { + return substatement; + } + } // augment to extension + else if (StmtContextUtils.producesDeclared(substatement, + UnknownStatementImpl.class) + && substatementArgument instanceof String) { + if (nextPathQName.getLocalName().equals(substatementArgument)) { + String message = "Module '"+substatement.getRoot().getStatementArgument()+"': augment into extension '"+substatementArgument+"'."; + LOG.warn(message); + return substatement; + } } } return null; } - public static boolean isAllowedAugmentTarget( - StatementContextBase substatement) { + public static boolean isSupportedAugmentTarget( + StatementContextBase substatementCtx) { /* * :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. + * 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; + Collection allowedAugmentTargets = substatementCtx.getFromNamespace( + ValidationBundlesNamespace.class, + ValidationBundleType.SUPPORTED_AUGMENT_TARGETS); + + // if no allowed target is returned we consider all targets allowed + return allowedAugmentTargets == null || allowedAugmentTargets.isEmpty() + || allowedAugmentTargets.contains(substatementCtx.getPublicDefinition()); } @Nullable diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BaseStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BaseStatementImpl.java index 5460fd238f..aa4085a509 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BaseStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BaseStatementImpl.java @@ -7,8 +7,22 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.BaseEffectiveStatementImpl; +import java.util.Collection; +import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceAction; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite; +import org.opendaylight.yangtools.yang.parser.spi.IdentityNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; +import org.opendaylight.yangtools.yang.parser.spi.meta.DerivedIdentitiesNamespace; +import java.util.LinkedList; +import java.util.List; +import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement; +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.source.SourceException; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.BaseEffectiveStatementImpl; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; @@ -49,6 +63,41 @@ public class BaseStatementImpl extends AbstractDeclaredStatement return new BaseEffectiveStatementImpl(ctx); } + @Override + public void onStatementDefinitionDeclared( + final Mutable> baseStmtCtx) + throws SourceException { + final Mutable baseParentCtx = baseStmtCtx.getParentContext(); + if(StmtContextUtils.producesDeclared(baseParentCtx, IdentityStatement.class)) { + + final QName baseIdentityQName = baseStmtCtx.getStatementArgument(); + ModelActionBuilder baseIdentityAction = baseStmtCtx.newInferenceAction(ModelProcessingPhase.STATEMENT_DEFINITION); + final Prerequisite> requiresPrereq = baseIdentityAction.requiresCtx(baseStmtCtx, IdentityNamespace.class, baseIdentityQName, ModelProcessingPhase.STATEMENT_DEFINITION); + final Prerequisite mutatesPrereq = baseIdentityAction.mutatesCtx(baseParentCtx, ModelProcessingPhase.STATEMENT_DEFINITION); + + baseIdentityAction.apply( new InferenceAction() { + + @Override + public void apply() throws InferenceException { + List> derivedIdentities = baseStmtCtx.getFromNamespace(DerivedIdentitiesNamespace.class, baseStmtCtx.getStatementArgument()); + if(derivedIdentities == null) { + derivedIdentities = new LinkedList<>(); + baseStmtCtx.addToNs(DerivedIdentitiesNamespace.class, baseIdentityQName, derivedIdentities); + } + derivedIdentities.add(baseParentCtx); + } + + @Override + public void prerequisiteFailed( + Collection> failed) + throws InferenceException { + throw new InferenceException("Unable to resolve identity "+baseParentCtx.getStatementArgument()+" and base identity " + baseStmtCtx.getStatementArgument(), baseStmtCtx + .getStatementSourceReference()); + } + + }); + } + } } @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BelongsToStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BelongsToStatementImpl.java index ea73c8d341..ec6458d1ca 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BelongsToStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BelongsToStatementImpl.java @@ -1,21 +1,33 @@ -/** +/* * 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.parser.stmt.rfc6020.effective.BelongsEffectiveToStatementImpl; - -import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement; +import com.google.common.base.Optional; +import java.net.URI; +import java.util.Collection; +import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; +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.parser.builder.impl.ModuleIdentifierImpl; 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.ModelActionBuilder; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceAction; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToModuleContext; +import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNamespaceForBelongsTo; +import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.BelongsEffectiveToStatementImpl; public class BelongsToStatementImpl extends AbstractDeclaredStatement implements BelongsToStatement { @@ -50,6 +62,37 @@ public class BelongsToStatementImpl extends AbstractDeclaredStatement return new BelongsEffectiveToStatementImpl(ctx); } + @Override + public void onLinkageDeclared(final StmtContext.Mutable> belongsToCtx) throws SourceException { + ModelActionBuilder belongsToAction = belongsToCtx.newInferenceAction(ModelProcessingPhase.SOURCE_LINKAGE); + + final ModuleIdentifier belongsToModuleIdentifier = getModuleIdentifier(belongsToCtx); + final ModelActionBuilder.Prerequisite> belongsToPrereq = belongsToAction.requiresCtx(belongsToCtx, ModuleNamespaceForBelongsTo.class, belongsToModuleIdentifier.getName(), ModelProcessingPhase.SOURCE_LINKAGE); + + belongsToAction.apply(new InferenceAction() { + + @Override + public void apply() throws InferenceException { + StmtContext belongsToModuleCtx = belongsToPrereq.get(); + + belongsToCtx.addToNs(BelongsToModuleContext.class, belongsToModuleIdentifier, + belongsToModuleCtx); + } + + @Override + public void prerequisiteFailed(Collection> failed) throws InferenceException { + if (failed.contains(belongsToPrereq)) { + throw new InferenceException("Module from belongs-to was not found: " + belongsToCtx.getStatementArgument(), belongsToCtx + .getStatementSourceReference()); + } + } + }); + } + + private ModuleIdentifier getModuleIdentifier(StmtContext.Mutable> belongsToCtx) { + String moduleName = belongsToCtx.getStatementArgument(); + return new ModuleIdentifierImpl(moduleName, Optional. absent(), Optional.of(SimpleDateFormatUtil.DEFAULT_BELONGS_TO_DATE)); + } } @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BinarySpecificationImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BinarySpecificationImpl.java new file mode 100644 index 0000000000..6410b05fa4 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BinarySpecificationImpl.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +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.LengthStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +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 org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.BinaryEffectiveStatementImpl; + +public class BinarySpecificationImpl extends AbstractDeclaredStatement implements + TypeStatement.BinarySpecification { + + protected BinarySpecificationImpl(StmtContext context) { + super(context); + } + + public static class Definition extends + AbstractStatementSupport> { + + public Definition() { + super(Rfc6020Mapping.TYPE); + } + + @Override + public String parseArgumentValue(StmtContext ctx, String value) throws SourceException { + return value; + } + + @Override + public BinarySpecification createDeclared(StmtContext ctx) { + return new BinarySpecificationImpl(ctx); + } + + @Override + public EffectiveStatement createEffective( + StmtContext> ctx) { + return new BinaryEffectiveStatementImpl(ctx); + } + } + + @Nullable + @Override + public LengthStatement getLength() { + return firstDeclared(LengthStatement.class); + } + + @Nonnull + @Override + public String getName() { + return argument(); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BitStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BitStatementImpl.java index 93e227ac00..1bce3556dd 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BitStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BitStatementImpl.java @@ -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 @@ -7,49 +7,45 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.BitEffectiveStatementImpl; - +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.BitStatement; import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionStatement; import org.opendaylight.yangtools.yang.model.api.stmt.PositionStatement; 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.Rfc6020Mapping; -import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.BitStatement; 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.stmt.rfc6020.effective.type.BitEffectiveStatementImpl; -public class BitStatementImpl extends AbstractDeclaredStatement - implements BitStatement { +public class BitStatementImpl extends AbstractDeclaredStatement implements BitStatement { - protected BitStatementImpl( - StmtContext context) { + protected BitStatementImpl(StmtContext context) { super(context); } - public static class Definition - extends - AbstractStatementSupport> { + public static class Definition extends + AbstractStatementSupport> { public Definition() { super(Rfc6020Mapping.BIT); } @Override - public String parseArgumentValue(StmtContext ctx, String value) { - return value; + public QName parseArgumentValue(StmtContext ctx, String value) { + return Utils.qNameFromArgument(ctx, value); } @Override - public BitStatement createDeclared( - StmtContext ctx) { + public BitStatement createDeclared(StmtContext ctx) { return new BitStatementImpl(ctx); } @Override - public EffectiveStatement createEffective( - StmtContext> ctx) { + public EffectiveStatement createEffective( + StmtContext> ctx) { return new BitEffectiveStatementImpl(ctx); } @@ -72,7 +68,7 @@ public class BitStatementImpl extends AbstractDeclaredStatement @Override public String getName() { - return argument(); + return argument().getLocalName(); } @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BitsSpecificationImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BitsSpecificationImpl.java index 53215e76f7..32718f215c 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BitsSpecificationImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/BitsSpecificationImpl.java @@ -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 @@ -8,21 +8,20 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; import java.util.Collection; -import org.opendaylight.yangtools.yang.model.api.stmt.BitStatement; -import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; 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.BitStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +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 org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.BitsSpecificationEffectiveStatementImpl; -public class BitsSpecificationImpl extends AbstractDeclaredStatement - implements TypeStatement.BitsSpecification { +public class BitsSpecificationImpl extends AbstractDeclaredStatement implements TypeStatement.BitsSpecification { - protected BitsSpecificationImpl( - StmtContext context) { + protected BitsSpecificationImpl(StmtContext context) { super(context); } @@ -35,8 +34,7 @@ public class BitsSpecificationImpl extends AbstractDeclaredStatement } @Override - public String parseArgumentValue(StmtContext ctx, String value) - throws SourceException { + public String parseArgumentValue(StmtContext ctx, String value) throws SourceException { return value; } @@ -49,7 +47,7 @@ public class BitsSpecificationImpl extends AbstractDeclaredStatement @Override public EffectiveStatement createEffective( StmtContext> ctx) { - throw new UnsupportedOperationException(); + return new BitsSpecificationEffectiveStatementImpl(ctx); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Decimal64SpecificationImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Decimal64SpecificationImpl.java index 985b18d1a0..ebd7bce344 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Decimal64SpecificationImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Decimal64SpecificationImpl.java @@ -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 @@ -7,42 +7,47 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.model.api.stmt.FractionDigitsStatement; - -import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; 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.FractionDigitsStatement; import org.opendaylight.yangtools.yang.model.api.stmt.RangeStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +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 org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.Decimal64SpecificationEffectiveStatementImpl; -public class Decimal64SpecificationImpl extends AbstractDeclaredStatement implements TypeStatement.Decimal64Specification{ +public class Decimal64SpecificationImpl extends AbstractDeclaredStatement implements + TypeStatement.Decimal64Specification { protected Decimal64SpecificationImpl(StmtContext context) { super(context); } - public static class Definition extends AbstractStatementSupport> { + public static class Definition + extends + AbstractStatementSupport> { public Definition() { - super(Rfc6020Mapping.FRACTION_DIGITS); + super(Rfc6020Mapping.TYPE); } - @Override public String parseArgumentValue(StmtContext ctx, - String value) throws SourceException { + @Override + public String parseArgumentValue(StmtContext ctx, String value) throws SourceException { return value; } - @Override public TypeStatement.Decimal64Specification createDeclared( + @Override + public TypeStatement.Decimal64Specification createDeclared( StmtContext ctx) { return new Decimal64SpecificationImpl(ctx); } - @Override public EffectiveStatement createEffective( + @Override + public EffectiveStatement createEffective( StmtContext> ctx) { - throw new UnsupportedOperationException(); + return new Decimal64SpecificationEffectiveStatementImpl(ctx); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/EnumSpecificationImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/EnumSpecificationImpl.java index 8a1a9738e3..0b8b6d6d67 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/EnumSpecificationImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/EnumSpecificationImpl.java @@ -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 @@ -7,22 +7,21 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.model.api.stmt.EnumStatement; - import java.util.Collection; -import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; + 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.EnumStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +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 org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.EnumSpecificationEffectiveStatementImpl; -public class EnumSpecificationImpl extends AbstractDeclaredStatement - implements TypeStatement.EnumSpecification { +public class EnumSpecificationImpl extends AbstractDeclaredStatement implements TypeStatement.EnumSpecification { - protected EnumSpecificationImpl( - StmtContext context) { + protected EnumSpecificationImpl(StmtContext context) { super(context); } @@ -31,12 +30,11 @@ public class EnumSpecificationImpl extends AbstractDeclaredStatement AbstractStatementSupport> { public Definition() { - super(Rfc6020Mapping.ENUM); + super(Rfc6020Mapping.TYPE); } @Override - public String parseArgumentValue(StmtContext ctx, String value) - throws SourceException { + public String parseArgumentValue(StmtContext ctx, String value) throws SourceException { return value; } @@ -49,7 +47,7 @@ public class EnumSpecificationImpl extends AbstractDeclaredStatement @Override public EffectiveStatement createEffective( StmtContext> ctx) { - throw new UnsupportedOperationException(); + return new EnumSpecificationEffectiveStatementImpl(ctx); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/EnumStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/EnumStatementImpl.java index 3fa1b1ce7f..40f8454b19 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/EnumStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/EnumStatementImpl.java @@ -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 @@ -7,49 +7,45 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EnumEffectiveStatementImpl; - -import org.opendaylight.yangtools.yang.model.api.stmt.ValueStatement; -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.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.DescriptionStatement; import org.opendaylight.yangtools.yang.model.api.stmt.EnumStatement; +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.ValueStatement; 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.stmt.rfc6020.effective.type.EnumEffectiveStatementImpl; -public class EnumStatementImpl extends AbstractDeclaredStatement - implements EnumStatement { +public class EnumStatementImpl extends AbstractDeclaredStatement implements EnumStatement { - protected EnumStatementImpl( - StmtContext context) { + protected EnumStatementImpl(StmtContext context) { super(context); } - public static class Definition - extends - AbstractStatementSupport> { + public static class Definition extends + AbstractStatementSupport> { public Definition() { super(Rfc6020Mapping.ENUM); } @Override - public String parseArgumentValue(StmtContext ctx, String value) { - return value; + public QName parseArgumentValue(StmtContext ctx, String value) { + return Utils.qNameFromArgument(ctx, value); } @Override - public EnumStatement createDeclared( - StmtContext ctx) { + public EnumStatement createDeclared(StmtContext ctx) { return new EnumStatementImpl(ctx); } @Override - public EffectiveStatement createEffective( - StmtContext> ctx) { + public EffectiveStatement createEffective( + StmtContext> ctx) { return new EnumEffectiveStatementImpl(ctx); } @@ -72,7 +68,7 @@ public class EnumStatementImpl extends AbstractDeclaredStatement @Override public String getName() { - return argument(); + return argument().getLocalName(); } @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ExtensionStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ExtensionStatementImpl.java index e3ff0d39fb..e7bebeee0e 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ExtensionStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ExtensionStatementImpl.java @@ -19,7 +19,6 @@ 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; @@ -51,7 +50,7 @@ public class ExtensionStatementImpl extends AbstractDeclaredStatement imp } @Override - public void onStatementDefinitionDeclared(final StmtContext.Mutable> stmt) throws InferenceException, SourceException { + public void onStatementDefinitionDeclared(final StmtContext.Mutable> stmt) throws SourceException { stmt.addContext(ExtensionNamespace.class, stmt.getStatementArgument(), stmt); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/FractionDigitsStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/FractionDigitsStatementImpl.java index 94e1017f4b..047ef86478 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/FractionDigitsStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/FractionDigitsStatementImpl.java @@ -13,44 +13,61 @@ import org.opendaylight.yangtools.yang.model.api.stmt.FractionDigitsStatement; 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.stmt.rfc6020.effective.FractionDigitsEffectiveStatementImpl; -public class FractionDigitsStatementImpl extends - AbstractDeclaredStatement implements FractionDigitsStatement { +import com.google.common.collect.Range; - protected FractionDigitsStatementImpl( - StmtContext context) { +public class FractionDigitsStatementImpl extends AbstractDeclaredStatement implements FractionDigitsStatement { + + private static final Range FRAC_DIGITS_ALLOWED = Range.closed(1, 18); + + protected FractionDigitsStatementImpl(StmtContext context) { super(context); } public static class Definition extends - AbstractStatementSupport> { + AbstractStatementSupport> { public Definition() { super(Rfc6020Mapping.FRACTION_DIGITS); } @Override - public String parseArgumentValue(StmtContext ctx, String value) { - return value; + public Integer parseArgumentValue(StmtContext ctx, String value) { + + int fractionDigits; + + try { + fractionDigits = Integer.parseInt(value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(String.format("%s is not valid fraction-digits integer argument", + value), e); + } + + if (!FRAC_DIGITS_ALLOWED.contains(fractionDigits)) { + throw new IllegalArgumentException(String.format("fraction-digits argument should be integer within %s", + FRAC_DIGITS_ALLOWED)); + } + + return fractionDigits; } @Override - public FractionDigitsStatement createDeclared( - StmtContext ctx) { + public FractionDigitsStatement createDeclared(StmtContext ctx) { return new FractionDigitsStatementImpl(ctx); } @Override - public EffectiveStatement createEffective( - StmtContext> ctx) { - throw new UnsupportedOperationException(); + public EffectiveStatement createEffective( + StmtContext> ctx) { + return new FractionDigitsEffectiveStatementImpl(ctx); } } @Override - public String getValue() { + public Integer getValue() { return argument(); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingStatementImpl.java index 30d6ef0769..98a5667df0 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingStatementImpl.java @@ -60,9 +60,10 @@ public class GroupingStatementImpl extends AbstractDeclaredStatement } @Override - public void onFullDefinitionDeclared( - Mutable> stmt) throws SourceException { - stmt.getParentContext().addContext(GroupingNamespace.class, stmt.getStatementArgument(),stmt); + public void onFullDefinitionDeclared(Mutable> stmt) throws SourceException { + if (stmt != null && stmt.getParentContext() != null) { + stmt.getParentContext().addContext(GroupingNamespace.class, stmt.getStatementArgument(), stmt); + } } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java index 9802db52b3..e6f496b0a4 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java @@ -7,8 +7,13 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName; +import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName; +import org.opendaylight.yangtools.yang.parser.stmt.reactor.RootStatementContext; +import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType; +import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace; +import java.util.Iterator; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; import java.util.Collection; import java.util.HashSet; @@ -18,10 +23,8 @@ import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; 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.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.StmtContext.Mutable; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; @@ -38,52 +41,82 @@ public final class GroupingUtils { * @param targetCtx * @throws SourceException */ - public static void copyFromSourceToTarget(StatementContextBase sourceGrpStmtCtx, - StatementContextBase targetCtx) throws SourceException { + public static void copyFromSourceToTarget( + StatementContextBase sourceGrpStmtCtx, + StatementContextBase targetCtx, + StmtContext.Mutable> usesNode) + throws SourceException { - QNameModule newQNameModule = getNewQNameModule(targetCtx, sourceGrpStmtCtx); - copyDeclaredStmts(sourceGrpStmtCtx, targetCtx, newQNameModule); - copyEffectiveStmts(sourceGrpStmtCtx, targetCtx, newQNameModule); + QNameModule newQNameModule = getNewQNameModule(targetCtx, + sourceGrpStmtCtx); + copyDeclaredStmts(sourceGrpStmtCtx, targetCtx, usesNode, newQNameModule); + copyEffectiveStmts(sourceGrpStmtCtx, targetCtx, usesNode, + newQNameModule); } - public static void copyDeclaredStmts(StatementContextBase sourceGrpStmtCtx, - StatementContextBase targetCtx, QNameModule newQNameModule) throws SourceException { + public static void copyDeclaredStmts( + StatementContextBase sourceGrpStmtCtx, + StatementContextBase targetCtx, + StmtContext.Mutable> usesNode, + QNameModule newQNameModule) throws SourceException { Collection> declaredSubstatements = sourceGrpStmtCtx .declaredSubstatements(); for (StatementContextBase originalStmtCtx : declaredSubstatements) { if (needToCopyByUses(originalStmtCtx)) { - StatementContextBase copy = originalStmtCtx.createCopy(newQNameModule, targetCtx, TypeOfCopy.ADDED_BY_USES); + StatementContextBase copy = originalStmtCtx + .createCopy(newQNameModule, targetCtx, + TypeOfCopy.ADDED_BY_USES); targetCtx.addEffectiveSubstatement(copy); + usesNode.addAsEffectOfStatement(copy); } else if (isReusedByUses(originalStmtCtx)) { targetCtx.addEffectiveSubstatement(originalStmtCtx); + usesNode.addAsEffectOfStatement(originalStmtCtx); } } } - public static void copyEffectiveStmts(StatementContextBase sourceGrpStmtCtx, - StatementContextBase targetCtx, QNameModule newQNameModule) throws SourceException { + public static void copyEffectiveStmts( + StatementContextBase sourceGrpStmtCtx, + StatementContextBase targetCtx, + StmtContext.Mutable> usesNode, + QNameModule newQNameModule) throws SourceException { Collection> effectiveSubstatements = sourceGrpStmtCtx .effectiveSubstatements(); for (StatementContextBase originalStmtCtx : effectiveSubstatements) { if (needToCopyByUses(originalStmtCtx)) { - StatementContextBase copy = originalStmtCtx.createCopy(newQNameModule, targetCtx, TypeOfCopy.ADDED_BY_USES); + StatementContextBase copy = originalStmtCtx + .createCopy(newQNameModule, targetCtx, + TypeOfCopy.ADDED_BY_USES); targetCtx.addEffectiveSubstatement(copy); + usesNode.addAsEffectOfStatement(copy); } else if (isReusedByUses(originalStmtCtx)) { targetCtx.addEffectiveSubstatement(originalStmtCtx); + usesNode.addAsEffectOfStatement(originalStmtCtx); } } } - 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()); + if (targetCtx.isRootContext()) { + return targetCtx.getFromNamespace( + ModuleCtxToModuleQName.class, + targetCtx); } + if(targetCtx.getPublicDefinition() == Rfc6020Mapping.AUGMENT) { + RootStatementContext root = targetCtx.getRoot(); + return targetCtx.getFromNamespace( + ModuleCtxToModuleQName.class, + root); + } + 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(); @@ -103,14 +136,17 @@ public final class GroupingUtils { } } - public static boolean needToCreateNewQName(StatementDefinition publicDefinition) { + public static boolean needToCreateNewQName( + StatementDefinition publicDefinition) { return true; } public static boolean needToCopyByUses(StmtContext stmtContext) { - Set noCopyDefSet = new HashSet(); + Set noCopyDefSet = new HashSet<>(); noCopyDefSet.add(Rfc6020Mapping.USES); + noCopyDefSet.add(Rfc6020Mapping.TYPEDEF); + noCopyDefSet.add(Rfc6020Mapping.TYPE); StatementDefinition def = stmtContext.getPublicDefinition(); return !noCopyDefSet.contains(def); @@ -118,8 +154,9 @@ public final class GroupingUtils { public static boolean isReusedByUses(StmtContext stmtContext) { - Set reusedDefSet = new HashSet(); + Set reusedDefSet = new HashSet<>(); reusedDefSet.add(Rfc6020Mapping.TYPEDEF); + reusedDefSet.add(Rfc6020Mapping.TYPE); StatementDefinition def = stmtContext.getPublicDefinition(); return reusedDefSet.contains(def); @@ -127,22 +164,122 @@ public final class GroupingUtils { public static void resolveUsesNode( Mutable> usesNode, - StatementContextBase targetNodeStmtCtx) throws SourceException { + StatementContextBase targetNodeStmtCtx) + throws SourceException { - Collection> declaredSubstatements = usesNode.declaredSubstatements(); + Collection> declaredSubstatements = usesNode + .declaredSubstatements(); for (StatementContextBase subStmtCtx : declaredSubstatements) { - 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)) { + performRefine(subStmtCtx, targetNodeStmtCtx); } - if (StmtContextUtils.producesDeclared(subStmtCtx, RefineStatement.class)) { - // :TODO resolve and perform refine statement - } - if (StmtContextUtils.producesDeclared(subStmtCtx, AugmentStatement.class)) { - // :TODO find target node and perform augmentation + } + } + + private static void performRefine(StatementContextBase refineCtx, + StatementContextBase usesParentCtx) { + + Object refineArgument = refineCtx.getStatementArgument(); + + SchemaNodeIdentifier refineTargetNodeIdentifier; + if (refineArgument instanceof SchemaNodeIdentifier) { + refineTargetNodeIdentifier = (SchemaNodeIdentifier) refineArgument; + } else { + throw new IllegalArgumentException( + "Invalid refine argument. It must be instance of SchemaNodeIdentifier"); + } + + StatementContextBase refineTargetNodeCtx = Utils.findNode( + usesParentCtx, refineTargetNodeIdentifier); + + if (refineTargetNodeCtx == null) { + throw new IllegalArgumentException( + "Refine target node not found. Path: " + + refineTargetNodeIdentifier); + } + + addOrReplaceNodes(refineCtx, refineTargetNodeCtx); + refineCtx.addAsEffectOfStatement(refineTargetNodeCtx); + + } + + private static void addOrReplaceNodes( + StatementContextBase refineCtx, + StatementContextBase refineTargetNodeCtx) { + + Collection> declaredSubstatements = refineCtx + .declaredSubstatements(); + for (StatementContextBase refineSubstatementCtx : declaredSubstatements) { + if (isSupportedRefineSubstatement(refineSubstatementCtx)) { + addOrReplaceNode(refineSubstatementCtx, refineTargetNodeCtx); } - // :TODO resolve other uses substatements } } + private static void addOrReplaceNode( + StatementContextBase refineSubstatementCtx, + StatementContextBase refineTargetNodeCtx) { + + StatementDefinition refineSubstatementDef = refineSubstatementCtx + .getPublicDefinition(); + StatementDefinition refineTargetNodeDef = refineTargetNodeCtx + .getPublicDefinition(); + + if (!isSupportedRefineTarget(refineSubstatementCtx, refineTargetNodeCtx)) { + throw new SourceException("Error in module '" + + refineSubstatementCtx.getRoot().getStatementArgument() + + "' in the refine of uses '" + + refineSubstatementCtx.getParentContext() + .getStatementArgument() + + "': can not perform refine of '" + + refineSubstatementCtx.getPublicDefinition() + + "' for the target '" + + refineTargetNodeCtx.getPublicDefinition() + "'.", + refineSubstatementCtx.getStatementSourceReference()); + } + + if (isAllowedToAddByRefine(refineSubstatementDef)) { + refineTargetNodeCtx.addEffectiveSubstatement(refineSubstatementCtx); + } else { + refineTargetNodeCtx.removeStatementFromEffectiveSubstatements(refineSubstatementDef); + refineTargetNodeCtx.addEffectiveSubstatement(refineSubstatementCtx); + } + } + + private static boolean isAllowedToAddByRefine( + StatementDefinition publicDefinition) { + Set allowedToAddByRefineDefSet = new HashSet<>(); + allowedToAddByRefineDefSet.add(Rfc6020Mapping.MUST); + + return allowedToAddByRefineDefSet.contains(publicDefinition); + } + + private static boolean isSupportedRefineSubstatement( + StatementContextBase refineSubstatementCtx) { + + Collection supportedRefineSubstatements = refineSubstatementCtx + .getFromNamespace(ValidationBundlesNamespace.class, + ValidationBundleType.SUPPORTED_REFINE_SUBSTATEMENTS); + + return supportedRefineSubstatements == null + || supportedRefineSubstatements.isEmpty() + || supportedRefineSubstatements.contains(refineSubstatementCtx + .getPublicDefinition()) + || StmtContextUtils.isUnknownStatement(refineSubstatementCtx); + } + + private static boolean isSupportedRefineTarget( + StatementContextBase refineSubstatementCtx, + StatementContextBase refineTargetNodeCtx) { + + Collection supportedRefineTargets = YangValidationBundles.SUPPORTED_REFINE_TARGETS + .get(refineSubstatementCtx.getPublicDefinition()); + + return supportedRefineTargets == null + || supportedRefineTargets.isEmpty() + || supportedRefineTargets.contains(refineTargetNodeCtx + .getPublicDefinition()); + } + } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/IdentityRefSpecificationImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/IdentityRefSpecificationImpl.java index bd2b1e7c0a..18ec2111f0 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/IdentityRefSpecificationImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/IdentityRefSpecificationImpl.java @@ -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 @@ -7,6 +7,12 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; +import com.google.common.base.Preconditions; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.stmt.BaseStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement; +import org.opendaylight.yangtools.yang.parser.spi.IdentityNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement; @@ -14,10 +20,11 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; 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.TypeStatement; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.IdentityRefSpecificationEffectiveStatementImpl; -public class IdentityRefSpecificationImpl extends - AbstractDeclaredStatement implements - TypeStatement.IdentityRefSpecification { +import javax.annotation.Nonnull; + +public class IdentityRefSpecificationImpl extends AbstractDeclaredStatement implements TypeStatement.IdentityRefSpecification { protected IdentityRefSpecificationImpl( StmtContext context) { @@ -29,7 +36,7 @@ public class IdentityRefSpecificationImpl extends AbstractStatementSupport> { public Definition() { - super(Rfc6020Mapping.BASE); + super(Rfc6020Mapping.TYPE); } @Override @@ -46,8 +53,25 @@ public class IdentityRefSpecificationImpl extends @Override public EffectiveStatement createEffective( - StmtContext> ctx) { - throw new UnsupportedOperationException(); + StmtContext> ctx) { + return new IdentityRefSpecificationEffectiveStatementImpl(ctx); + } + + @Override + public void onFullDefinitionDeclared(StmtContext.Mutable> stmt) throws SourceException { + final StmtContext baseStmt = StmtContextUtils.findFirstDeclaredSubstatement(stmt, + BaseStatement.class); + Preconditions.checkArgument(baseStmt != null, "The \"base\" statement, which is a substatement to the " + + "\"type\"\n statement, MUST be present if the type is \"identityref\" in source '%s'", stmt + .getStatementSourceReference()); + final QName baseIdentity = baseStmt.getStatementArgument(); + final StmtContext> stmtCtx = stmt + .getFromNamespace(IdentityNamespace.class, baseIdentity); + Preconditions.checkArgument(stmtCtx != null, "Referenced base identity '%s' doesn't exist " + + "in " + "given scope " + "(module, imported submodules), source: '%s'", baseIdentity + .getLocalName(), stmt.getStatementSourceReference()); } } @@ -56,4 +80,10 @@ public class IdentityRefSpecificationImpl extends return argument(); } + @Nonnull + @Override + public BaseStatement getBase() { + return firstDeclared(BaseStatement.class); + } + } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/IdentityStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/IdentityStatementImpl.java index 092cc411e3..ada4c73095 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/IdentityStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/IdentityStatementImpl.java @@ -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 @@ -7,8 +7,11 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; +import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser; +import org.opendaylight.yangtools.yang.parser.spi.IdentityNamespace; +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.IdentityEffectiveStatementImpl; - import org.opendaylight.yangtools.yang.model.api.stmt.BaseStatement; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; @@ -29,9 +32,7 @@ public class IdentityStatementImpl extends AbstractDeclaredStatement super(context); } - public static class Definition - extends - AbstractStatementSupport> { + public static class Definition extends AbstractStatementSupport> { public Definition() { super(Rfc6020Mapping.IDENTITY); @@ -54,6 +55,10 @@ public class IdentityStatementImpl extends AbstractDeclaredStatement return new IdentityEffectiveStatementImpl(ctx); } + @Override + public void onStatementDefinitionDeclared(final StmtContext.Mutable> stmt) throws SourceException { + stmt.addToNs(IdentityNamespace.class, stmt.getStatementArgument(), stmt); + } } @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ImportStatementDefinition.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ImportStatementDefinition.java index 6863486d68..c1fc892c0e 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ImportStatementDefinition.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ImportStatementDefinition.java @@ -9,14 +9,8 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; import static org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase.SOURCE_LINKAGE; import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf; - -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ImportEffectiveStatementImpl; - -import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToModuleIdentifier; -import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement; import com.google.common.base.Optional; import java.net.URI; -import java.text.ParseException; import java.util.Collection; import java.util.Date; import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; @@ -24,6 +18,7 @@ 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.ImportStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement; import org.opendaylight.yangtools.yang.model.api.stmt.RevisionDateStatement; import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl; import org.opendaylight.yangtools.yang.parser.spi.ModuleNamespace; @@ -34,7 +29,9 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Infere import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite; 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.SourceException; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ImportEffectiveStatementImpl; public class ImportStatementDefinition extends AbstractStatementSupport> { @@ -84,7 +81,8 @@ public class ImportStatementDefinition extends @Override public void prerequisiteFailed(Collection> failed) throws InferenceException { if (failed.contains(imported)) { - throw new InferenceException("Imported module was not found.", stmt.getStatementSourceReference()); + throw new InferenceException(String.format("Imported module [%s] was not found.", impIdentifier), + stmt.getStatementSourceReference()); } } }); @@ -94,19 +92,12 @@ public class ImportStatementDefinition extends throws SourceException { String moduleName = stmt.getStatementArgument(); - String revisionArg = firstAttributeOf(stmt.declaredSubstatements(), RevisionDateStatement.class); - final Optional revision; - if (revisionArg != null) { - try { - revision = Optional.of(SimpleDateFormatUtil.getRevisionFormat().parse(revisionArg)); - } catch (ParseException e) { - throw new SourceException(String.format("Revision value %s is not in required format yyyy-MM-dd", - revisionArg), stmt.getStatementSourceReference(), e); - } - } else { - revision = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_IMP); + Date revision = firstAttributeOf(stmt.declaredSubstatements(), RevisionDateStatement.class); + if (revision == null) { + revision = SimpleDateFormatUtil.DEFAULT_DATE_IMP; } - return new ModuleIdentifierImpl(moduleName, Optional. absent(), revision); + + return new ModuleIdentifierImpl(moduleName, Optional. absent(), Optional. of(revision)); } } \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/IncludeStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/IncludeStatementImpl.java index 509f462975..929634c14c 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/IncludeStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/IncludeStatementImpl.java @@ -10,10 +10,10 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; import static org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase.SOURCE_LINKAGE; import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.IncludeEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.spi.source.IncludedSubmoduleNameToIdentifier; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.IncludeEffectiveStatementImpl; import java.net.URI; -import java.text.ParseException; import java.util.Collection; import java.util.Date; import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; @@ -74,17 +74,17 @@ public class IncludeStatementImpl extends AbstractDeclaredStatement impl ModelActionBuilder includeAction = stmt.newInferenceAction(SOURCE_LINKAGE); final Prerequisite> requiresCtxPrerequisite = includeAction.requiresCtx(stmt, SubmoduleNamespace.class, includeSubmoduleIdentifier, SOURCE_LINKAGE); - final Prerequisite> mutatesCtxPrerequisite = includeAction.mutatesCtx(stmt.getRoot(), - SOURCE_LINKAGE); includeAction.apply(new InferenceAction() { @Override public void apply() throws InferenceException { - StmtContext includedSubmoduleStmt = requiresCtxPrerequisite.get(); + StmtContext includedSubModuleContext = requiresCtxPrerequisite.get(); - mutatesCtxPrerequisite.get().addToNs(IncludedModuleContext.class, includeSubmoduleIdentifier, - includedSubmoduleStmt); + stmt.addToNs(IncludedModuleContext.class, includeSubmoduleIdentifier, + includedSubModuleContext); + stmt.addToNs(IncludedSubmoduleNameToIdentifier.class, + stmt.getStatementArgument(), includeSubmoduleIdentifier); } @Override @@ -100,19 +100,13 @@ public class IncludeStatementImpl extends AbstractDeclaredStatement impl private static ModuleIdentifier getIncludeSubmoduleIdentifier(Mutable stmt) { String subModuleName = stmt.getStatementArgument(); - String revisionArg = firstAttributeOf(stmt.declaredSubstatements(), RevisionDateStatement.class); - final Optional revision; - if (revisionArg != null) { - try { - revision = Optional.of(SimpleDateFormatUtil.getRevisionFormat().parse(revisionArg)); - } catch (ParseException e) { - throw new IllegalArgumentException(e); - } - } else { - revision = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_IMP); + + Date revisionDate = firstAttributeOf(stmt.declaredSubstatements(), RevisionDateStatement.class); + if (revisionDate == null) { + revisionDate = SimpleDateFormatUtil.DEFAULT_DATE_IMP; } - return new ModuleIdentifierImpl(subModuleName, Optional. absent(), revision); + return new ModuleIdentifierImpl(subModuleName, Optional. absent(), Optional. of(revisionDate)); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/InstanceIdentifierSpecificationImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/InstanceIdentifierSpecificationImpl.java index 504498db34..b3b30cecad 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/InstanceIdentifierSpecificationImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/InstanceIdentifierSpecificationImpl.java @@ -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 @@ -16,14 +16,15 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; 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.TypeStatement; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.InstanceIdentifierSpecificationEffectiveStatementImpl; public class InstanceIdentifierSpecificationImpl extends AbstractDeclaredStatement implements TypeStatement.InstanceIdentifierSpecification { protected InstanceIdentifierSpecificationImpl( - StmtContext context) { - super(context); + StmtContext ctx) { + super(ctx); } public static class Definition @@ -31,7 +32,7 @@ public class InstanceIdentifierSpecificationImpl extends AbstractStatementSupport> { public Definition() { - super(Rfc6020Mapping.REQUIRE_INSTANCE); + super(Rfc6020Mapping.TYPE); } @Override @@ -49,7 +50,7 @@ public class InstanceIdentifierSpecificationImpl extends @Override public EffectiveStatement createEffective( StmtContext> ctx) { - throw new UnsupportedOperationException(); + return new InstanceIdentifierSpecificationEffectiveStatementImpl(ctx); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/KeyStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/KeyStatementImpl.java index d0ec799c51..48f29b08f0 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/KeyStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/KeyStatementImpl.java @@ -7,8 +7,9 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.KeyEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.KeyEffectiveStatementImpl; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -34,8 +35,6 @@ public class KeyStatementImpl extends AbstractDeclaredStatement, KeyStatement, EffectiveStatement, KeyStatement>> { - public static final char SEPARATOR = ' '; - public Definition() { super(Rfc6020Mapping.KEY); } @@ -44,7 +43,7 @@ public class KeyStatementImpl extends AbstractDeclaredStatement parseArgumentValue(StmtContext ctx, String value) throws SourceException { - Splitter keySplitter = Splitter.on(SEPARATOR).omitEmptyStrings().trimResults(); + Splitter keySplitter = Splitter.on(StmtContextUtils.LIST_KEY_SEPARATOR).omitEmptyStrings().trimResults(); List keyTokens = keySplitter.splitToList(value); // to detect if key contains duplicates @@ -57,7 +56,7 @@ public class KeyStatementImpl extends AbstractDeclaredStatement implements TypeStatement.LeafrefSpecification { @@ -30,7 +30,7 @@ public class LeafrefSpecificationImpl extends AbstractDeclaredStatement AbstractStatementSupport> { public Definition() { - super(Rfc6020Mapping.PATH); + super(Rfc6020Mapping.TYPE); } @Override @@ -48,7 +48,7 @@ public class LeafrefSpecificationImpl extends AbstractDeclaredStatement @Override public EffectiveStatement createEffective( StmtContext> ctx) { - throw new UnsupportedOperationException(); + return new LeafrefSpecificationEffectiveStatementImpl(ctx); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/LengthStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/LengthStatementImpl.java index 1c698397c2..faf07270c6 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/LengthStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/LengthStatementImpl.java @@ -7,52 +7,50 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.LengthEffectiveStatementImpl; +import java.util.List; +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.DescriptionStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ErrorAppTagStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ErrorMessageStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement; -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.LengthStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement; +import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; 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.stmt.rfc6020.effective.type.LengthEffectiveStatementImpl; -public class LengthStatementImpl extends AbstractDeclaredStatement - implements LengthStatement { +public class LengthStatementImpl extends AbstractDeclaredStatement> implements LengthStatement { - protected LengthStatementImpl( - StmtContext context) { + protected LengthStatementImpl(StmtContext, LengthStatement, ?> context) { super(context); } public static class Definition extends - AbstractStatementSupport> { + AbstractStatementSupport, LengthStatement, EffectiveStatement, LengthStatement>> { public Definition() { super(Rfc6020Mapping.LENGTH); } @Override - public String parseArgumentValue(StmtContext ctx, String value) { - return value; + public List parseArgumentValue(StmtContext ctx, String value) { + return TypeUtils.parseLengthListFromString(value); } @Override - public LengthStatement createDeclared( - StmtContext ctx) { + public LengthStatement createDeclared(StmtContext, LengthStatement, ?> ctx) { return new LengthStatementImpl(ctx); } @Override - public EffectiveStatement createEffective( - StmtContext> ctx) { + public EffectiveStatement, LengthStatement> createEffective( + StmtContext, LengthStatement, EffectiveStatement, LengthStatement>> ctx) { return new LengthEffectiveStatementImpl(ctx); } - } @Override @@ -76,8 +74,7 @@ public class LengthStatementImpl extends AbstractDeclaredStatement } @Override - public String getValue() { + public List getValue() { return argument(); } - } \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/MinElementsStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/MinElementsStatementImpl.java index bb66ed69e5..c3dbe62ce8 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/MinElementsStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/MinElementsStatementImpl.java @@ -16,43 +16,42 @@ 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; -public class MinElementsStatementImpl extends AbstractDeclaredStatement - implements MinElementsStatement { +public class MinElementsStatementImpl extends + AbstractDeclaredStatement implements MinElementsStatement { protected MinElementsStatementImpl( - StmtContext context) { + StmtContext context) { super(context); } public static class Definition extends - AbstractStatementSupport> { + AbstractStatementSupport> { public Definition() { super(Rfc6020Mapping.MIN_ELEMENTS); } @Override - public String parseArgumentValue(StmtContext ctx, String value) { - return value; + public Integer parseArgumentValue(StmtContext ctx, String value) { + return Integer.parseInt(value); } @Override public MinElementsStatement createDeclared( - StmtContext ctx) { + StmtContext ctx) { return new MinElementsStatementImpl(ctx); } @Override - public EffectiveStatement createEffective( - StmtContext> ctx) { + public EffectiveStatement createEffective( + StmtContext> ctx) { return new MinElementsEffectiveStatementImpl(ctx); } - } @Override - public String getValue() { + public Integer getValue() { return argument(); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ModuleStatementSupport.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ModuleStatementSupport.java index b34c5eef76..2dd4cb0d40 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ModuleStatementSupport.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ModuleStatementSupport.java @@ -9,10 +9,13 @@ 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.spi.source.ModuleCtxToModuleQName; + +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.common.SimpleDateFormatUtil; 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; @@ -29,13 +32,12 @@ 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.ModuleNamespaceForBelongsTo; 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> { @@ -72,16 +74,17 @@ public class ModuleStatementSupport extends + "] is missing."); } - // FIXME: this is wrong, it has to select the newest revision statement, not the first it encounters. - // YANG files are not required to order revisions - Optional revisionDate = Optional.fromNullable(firstAttributeOf(stmt.declaredSubstatements(), - RevisionStatement.class)); + Optional revisionDate = Optional.fromNullable(getLatestRevision(stmt.declaredSubstatements())); + if (!revisionDate.isPresent()) { + revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV); + } qNameModule = QNameModule.cachedReference(QNameModule.create(moduleNs.get(), revisionDate.orNull())); ModuleIdentifier moduleIdentifier = new ModuleIdentifierImpl(stmt.getStatementArgument(), Optional. absent(), revisionDate); stmt.addContext(ModuleNamespace.class, moduleIdentifier, stmt); + stmt.addContext(ModuleNamespaceForBelongsTo.class, moduleIdentifier.getName(), stmt); stmt.addContext(NamespaceToModule.class, qNameModule, stmt); String modulePrefix = firstAttributeOf(stmt.declaredSubstatements(), PrefixStatement.class); @@ -91,6 +94,7 @@ public class ModuleStatementSupport extends stmt.addToNs(PrefixToModule.class, modulePrefix, qNameModule); stmt.addToNs(ModuleNameToModuleQName.class, stmt.getStatementArgument(), qNameModule); + stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule); stmt.addToNs(ModuleQNameToModuleName.class, qNameModule, stmt.getStatementArgument()); stmt.addToNs(ModuleIdentifierToModuleQName.class, moduleIdentifier, qNameModule); @@ -104,4 +108,21 @@ public class ModuleStatementSupport extends stmt.addContext(NamespaceToModule.class, qNameModule, stmt); } + + private static Date getLatestRevision(Iterable> subStmts) { + Date revision = null; + for (StmtContext subStmt : subStmts) { + if (subStmt.getPublicDefinition().getDeclaredRepresentationClass().isAssignableFrom(RevisionStatement + .class)) { + if (revision == null && subStmt.getStatementArgument() != null) { + revision = (Date) subStmt.getStatementArgument(); + } else if (subStmt.getStatementArgument() != null && ((Date) subStmt.getStatementArgument()).compareTo + (revision) > 0) { + revision = (Date) subStmt.getStatementArgument(); + } + } + } + return revision; + } + } \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/MustStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/MustStatementImpl.java index 5df5575050..0db8c69f41 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/MustStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/MustStatementImpl.java @@ -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.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.MustEffectiveStatementImpl; @@ -34,7 +41,7 @@ public class MustStatementImpl extends AbstractDeclaredStatement ctx, String value) throws SourceException { - return new RevisionAwareXPathImpl(value, false); + return new RevisionAwareXPathImpl(value, Utils.isXPathAbsolute(value)); } @Override public MustStatement createDeclared( diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/NumericalRestrictionsImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/NumericalRestrictionsImpl.java index 2415db62d8..32af347b77 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/NumericalRestrictionsImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/NumericalRestrictionsImpl.java @@ -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 @@ -9,38 +9,44 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; -import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement; import org.opendaylight.yangtools.yang.model.api.stmt.RangeStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +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 org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.NumericalRestrictionsEffectiveStatementImpl; -public class NumericalRestrictionsImpl extends AbstractDeclaredStatement implements TypeStatement.NumericalRestrictions{ +public class NumericalRestrictionsImpl extends AbstractDeclaredStatement implements + TypeStatement.NumericalRestrictions { protected NumericalRestrictionsImpl(StmtContext context) { super(context); } - public static class Definition extends AbstractStatementSupport> { + public static class Definition + extends + AbstractStatementSupport> { public Definition() { - super(Rfc6020Mapping.RANGE); + super(Rfc6020Mapping.TYPE); } - @Override public String parseArgumentValue(StmtContext ctx, - String value) throws SourceException { + @Override + public String parseArgumentValue(StmtContext ctx, String value) throws SourceException { return value; } - @Override public TypeStatement.NumericalRestrictions createDeclared( + @Override + public TypeStatement.NumericalRestrictions createDeclared( StmtContext ctx) { return new NumericalRestrictionsImpl(ctx); } - @Override public EffectiveStatement createEffective( + @Override + public EffectiveStatement createEffective( StmtContext> ctx) { - throw new UnsupportedOperationException(); + return new NumericalRestrictionsEffectiveStatementImpl(ctx); } } @@ -51,7 +57,7 @@ public class NumericalRestrictionsImpl extends AbstractDeclaredStatement @Override public RangeStatement getRange() { - return firstDeclared(RangeStatement.class); + return firstDeclared(RangeStatement.class); } } \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/PathStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/PathStatementImpl.java new file mode 100644 index 0000000000..990d33ac24 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/PathStatementImpl.java @@ -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.parser.stmt.rfc6020; + +import javax.annotation.Nonnull; + +import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; +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.PathStatement; +import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl; +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 org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.PathEffectiveStatementImpl; + +public class PathStatementImpl extends AbstractDeclaredStatement implements PathStatement { + + protected PathStatementImpl(StmtContext context) { + super(context); + } + + public static class Definition + extends + AbstractStatementSupport> { + + public Definition() { + super(Rfc6020Mapping.PATH); + } + + @Override + public RevisionAwareXPath parseArgumentValue(StmtContext ctx, String value) throws SourceException { + return new RevisionAwareXPathImpl(value, Utils.isXPathAbsolute(value)); + } + + @Override + public PathStatement createDeclared(StmtContext ctx) { + return new PathStatementImpl(ctx); + } + + @Override + public EffectiveStatement createEffective( + StmtContext> ctx) { + return new PathEffectiveStatementImpl(ctx); + } + } + + @Nonnull + @Override + public String getValue() { + return rawArgument(); + } + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/PatternStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/PatternStatementImpl.java index 41c2875486..0d35ec52d6 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/PatternStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/PatternStatementImpl.java @@ -7,52 +7,64 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.PatternEffectiveStatementImpl; - +import com.google.common.base.Optional; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; +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.DescriptionStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ErrorAppTagStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ErrorMessageStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement; -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.PatternStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement; +import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; 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.stmt.rfc6020.effective.type.PatternConstraintEffectiveImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.PatternEffectiveStatementImpl; -public class PatternStatementImpl extends AbstractDeclaredStatement - implements PatternStatement { +public class PatternStatementImpl extends AbstractDeclaredStatement implements PatternStatement { - protected PatternStatementImpl( - StmtContext context) { + protected PatternStatementImpl(StmtContext context) { super(context); } public static class Definition extends - AbstractStatementSupport> { + AbstractStatementSupport> { public Definition() { super(Rfc6020Mapping.PATTERN); } @Override - public String parseArgumentValue(StmtContext ctx, String value) { - return value; + public PatternConstraint parseArgumentValue(StmtContext ctx, String value) { + + final StringBuilder wrapPatternBuilder = new StringBuilder(value.length() + 2); + wrapPatternBuilder.append('^'); + wrapPatternBuilder.append(value); + wrapPatternBuilder.append('$'); + final String pattern = wrapPatternBuilder.toString(); + + try { + Pattern.compile(pattern); + return new PatternConstraintEffectiveImpl(pattern, Optional.of(""), Optional.of("")); + } catch (PatternSyntaxException e) { + return null; + } } @Override - public PatternStatement createDeclared( - StmtContext ctx) { + public PatternStatement createDeclared(StmtContext ctx) { return new PatternStatementImpl(ctx); } @Override - public EffectiveStatement createEffective( - StmtContext> ctx) { + public EffectiveStatement createEffective( + StmtContext> ctx) { return new PatternEffectiveStatementImpl(ctx); } - } @Override @@ -76,7 +88,7 @@ public class PatternStatementImpl extends AbstractDeclaredStatement } @Override - public String getValue() { + public PatternConstraint getValue() { return argument(); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/PositionStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/PositionStatementImpl.java index 9496c69b75..2a92fd5440 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/PositionStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/PositionStatementImpl.java @@ -16,43 +16,47 @@ 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; -public class PositionStatementImpl extends AbstractDeclaredStatement +public class PositionStatementImpl extends AbstractDeclaredStatement implements PositionStatement { protected PositionStatementImpl( - StmtContext context) { + StmtContext context) { super(context); } public static class Definition extends - AbstractStatementSupport> { + AbstractStatementSupport> { public Definition() { super(Rfc6020Mapping.POSITION); } @Override - public String parseArgumentValue(StmtContext ctx, String value) { - return value; + public Long parseArgumentValue(StmtContext ctx, String value) { + try { + return Long.parseLong(value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(String.format("Position value %s is not valid integer", value), e); + } } @Override public PositionStatement createDeclared( - StmtContext ctx) { + StmtContext ctx) { return new PositionStatementImpl(ctx); } @Override - public EffectiveStatement createEffective( - StmtContext> ctx) { + public EffectiveStatement createEffective( + StmtContext> ctx) { return new PositionEffectiveStatementImpl(ctx); } } @Override - public String getValue() { + public Long getValue() { return argument(); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RangeStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RangeStatementImpl.java index bd16e1fc94..467517f9e7 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RangeStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RangeStatementImpl.java @@ -7,52 +7,56 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.RangeEffectiveStatementImpl; +import java.math.BigDecimal; +import java.util.List; +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.DescriptionStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ErrorAppTagStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ErrorMessageStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement; -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.RangeStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement; +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; 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.stmt.rfc6020.effective.type.RangeEffectiveStatementImpl; + +public class RangeStatementImpl extends AbstractDeclaredStatement> implements RangeStatement { -public class RangeStatementImpl extends AbstractDeclaredStatement - implements RangeStatement { + // these objects are to compare whether range has MAX or MIN value + // none of these values should appear as Yang number according to spec so they are safe to use + public static final BigDecimal YANG_MIN_NUM = BigDecimal.valueOf(-Double.MAX_VALUE); + public static final BigDecimal YANG_MAX_NUM = BigDecimal.valueOf(Double.MAX_VALUE); - protected RangeStatementImpl( - StmtContext context) { + protected RangeStatementImpl(StmtContext, RangeStatement, ?> context) { super(context); } public static class Definition extends - AbstractStatementSupport> { + AbstractStatementSupport, RangeStatement, EffectiveStatement, RangeStatement>> { public Definition() { super(Rfc6020Mapping.RANGE); } @Override - public String parseArgumentValue(StmtContext ctx, String value) { - return value; + public List parseArgumentValue(StmtContext ctx, String value) { + return TypeUtils.parseRangeListFromString(value); } @Override - public RangeStatement createDeclared( - StmtContext ctx) { + public RangeStatement createDeclared(StmtContext, RangeStatement, ?> ctx) { return new RangeStatementImpl(ctx); } @Override - public EffectiveStatement createEffective( - StmtContext> ctx) { + public EffectiveStatement, RangeStatement> createEffective( + StmtContext, RangeStatement, EffectiveStatement, RangeStatement>> ctx) { return new RangeEffectiveStatementImpl(ctx); } - } @Override @@ -76,8 +80,7 @@ public class RangeStatementImpl extends AbstractDeclaredStatement } @Override - public String getRange() { + public List getRange() { return argument(); } - } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RequireInstanceStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RequireInstanceStatementImpl.java index 0573fc310d..cd192b9f9a 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RequireInstanceStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RequireInstanceStatementImpl.java @@ -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 diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RevisionDateStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RevisionDateStatementImpl.java index 301978546c..f376f73735 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RevisionDateStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RevisionDateStatementImpl.java @@ -7,8 +7,12 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.RevisionDateEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; +import java.text.ParseException; +import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; +import java.util.Date; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.RevisionDateEffectiveStatementImpl; 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.RevisionDateStatement; @@ -17,42 +21,51 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; public class RevisionDateStatementImpl extends - AbstractDeclaredStatement implements RevisionDateStatement { + AbstractDeclaredStatement implements RevisionDateStatement { protected RevisionDateStatementImpl( - StmtContext context) { + StmtContext context) { super(context); } public static class Definition extends - AbstractStatementSupport> { + AbstractStatementSupport> { public Definition() { super(Rfc6020Mapping.REVISION_DATE); } @Override - public String parseArgumentValue(StmtContext ctx, String value) { - return value; + public Date parseArgumentValue(StmtContext ctx, String value) throws SourceException { + Date revision; + try { + revision = SimpleDateFormatUtil.getRevisionFormat() + .parse(value); + } catch (ParseException e) { + throw new SourceException(String.format("Revision value %s is not in required format yyyy-MM-dd", + value), ctx.getStatementSourceReference(), e); + } + + return revision; } @Override public RevisionDateStatement createDeclared( - StmtContext ctx) { + StmtContext ctx) { return new RevisionDateStatementImpl(ctx); } @Override - public EffectiveStatement createEffective( - StmtContext> ctx) { + public EffectiveStatement createEffective( + StmtContext> ctx) { return new RevisionDateEffectiveStatementImpl(ctx); } } @Override - public String getDate() { + public Date getDate() { return argument(); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RevisionStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RevisionStatementImpl.java index 8297e15674..d8cc62c8c1 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RevisionStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/RevisionStatementImpl.java @@ -8,7 +8,6 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.RevisionEffectiveStatementImpl; - import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; import java.text.ParseException; import java.util.Date; @@ -47,7 +46,8 @@ public class RevisionStatementImpl extends AbstractDeclaredStatement revision = SimpleDateFormatUtil.getRevisionFormat() .parse(value); } catch (ParseException e) { - throw new IllegalArgumentException(e); + throw new SourceException(String.format("Revision value %s is not in required format yyyy-MM-dd", + value), ctx.getStatementSourceReference(), e); } return revision; diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/StatusStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/StatusStatementImpl.java index b7401e56d2..26878d737a 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/StatusStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/StatusStatementImpl.java @@ -7,8 +7,9 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.StatusEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.StatusEffectiveStatementImpl; 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.StatusStatement; @@ -16,43 +17,42 @@ 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; -public class StatusStatementImpl extends AbstractDeclaredStatement +public class StatusStatementImpl extends AbstractDeclaredStatement implements StatusStatement { protected StatusStatementImpl( - StmtContext context) { + StmtContext context) { super(context); } public static class Definition extends - AbstractStatementSupport> { + AbstractStatementSupport> { public Definition() { super(Rfc6020Mapping.STATUS); } @Override - public String parseArgumentValue(StmtContext ctx, String value) { - return value; + public Status parseArgumentValue(StmtContext ctx, String value) { + return Utils.parseStatus(value); } @Override public StatusStatement createDeclared( - StmtContext ctx) { + StmtContext ctx) { return new StatusStatementImpl(ctx); } @Override - public EffectiveStatement createEffective( - StmtContext> ctx) { + public EffectiveStatement createEffective( + StmtContext> ctx) { return new StatusEffectiveStatementImpl(ctx); } - } @Override - public String getValue() { + public Status getValue() { return argument(); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/StringRestrictionsImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/StringRestrictionsImpl.java index 7a85c17778..a98487e4cf 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/StringRestrictionsImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/StringRestrictionsImpl.java @@ -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 @@ -8,22 +8,22 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; import java.util.Collection; -import org.opendaylight.yangtools.yang.model.api.stmt.LengthStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.PatternStatement; -import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; 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.LengthStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.PatternStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +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 org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.StringRestrictionsEffectiveStatementImpl; -public class StringRestrictionsImpl extends AbstractDeclaredStatement - implements TypeStatement.StringRestrictions { +public class StringRestrictionsImpl extends AbstractDeclaredStatement implements + TypeStatement.StringRestrictions { - protected StringRestrictionsImpl( - StmtContext context) { + protected StringRestrictionsImpl(StmtContext context) { super(context); } @@ -36,8 +36,7 @@ public class StringRestrictionsImpl extends AbstractDeclaredStatement } @Override - public String parseArgumentValue(StmtContext ctx, String value) - throws SourceException { + public String parseArgumentValue(StmtContext ctx, String value) throws SourceException { return value; } @@ -50,7 +49,7 @@ public class StringRestrictionsImpl extends AbstractDeclaredStatement @Override public EffectiveStatement createEffective( StmtContext> ctx) { - throw new UnsupportedOperationException(); + return new StringRestrictionsEffectiveStatementImpl(ctx); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/SubmoduleStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/SubmoduleStatementImpl.java index 19f77ecd0e..9a3b134615 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/SubmoduleStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/SubmoduleStatementImpl.java @@ -9,10 +9,8 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.findFirstDeclaredSubstatement; import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf; - 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; @@ -29,16 +27,18 @@ 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.parser.stmt.rfc6020.effective.SubmoduleEffectiveStatementImpl; - import com.google.common.base.Optional; -public class SubmoduleStatementImpl extends AbstractRootStatement implements SubmoduleStatement { +public class SubmoduleStatementImpl extends + AbstractRootStatement implements SubmoduleStatement { - protected SubmoduleStatementImpl(StmtContext context) { + protected SubmoduleStatementImpl( + StmtContext context) { super(context); } - public static class Definition extends + public static class Definition + extends AbstractStatementSupport> { public Definition() { @@ -51,7 +51,8 @@ public class SubmoduleStatementImpl extends AbstractRootStatement ctx) { + public SubmoduleStatement createDeclared( + StmtContext ctx) { return new SubmoduleStatementImpl(ctx); } @@ -66,26 +67,32 @@ public class SubmoduleStatementImpl extends AbstractRootStatement> stmt) throws SourceException { - Optional revisionDate = Optional.fromNullable(firstAttributeOf(stmt.declaredSubstatements(), - RevisionStatement.class)); + Optional revisionDate = Optional + .fromNullable(firstAttributeOf( + stmt.declaredSubstatements(), + RevisionStatement.class)); - ModuleIdentifier submoduleIdentifier = new ModuleIdentifierImpl(stmt.getStatementArgument(), - Optional. absent(), revisionDate); + ModuleIdentifier submoduleIdentifier = new ModuleIdentifierImpl( + stmt.getStatementArgument(), Optional. 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) { - throw new IllegalArgumentException("Prefix of belongsTo statement is missing in submodule [" - + stmt.getStatementArgument() + "]."); + 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); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypeStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypeStatementImpl.java index e96db5e9d8..199c6ee897 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypeStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypeStatementImpl.java @@ -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 @@ -7,6 +7,11 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; +import java.util.Collection; +import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase; + +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ExtendedTypeEffectiveStatementImpl; +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.TypeStatement; @@ -14,38 +19,91 @@ 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 org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.BooleanEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.EmptyEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.Int16EffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.Int32EffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.Int64EffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.Int8EffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.StringEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.UInt16EffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.UInt32EffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.UInt64EffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.UInt8EffectiveStatementImpl; -import javax.annotation.Nonnull; - -public class TypeStatementImpl extends AbstractDeclaredStatement implements TypeStatement { +public class TypeStatementImpl extends AbstractDeclaredStatement + implements TypeStatement { protected TypeStatementImpl(StmtContext context) { super(context); } - public static class Definition extends AbstractStatementSupport> { + public static class Definition + extends + AbstractStatementSupport> { public Definition() { super(Rfc6020Mapping.TYPE); } - @Override public String parseArgumentValue(StmtContext ctx, - String value) throws SourceException { + @Override + public String parseArgumentValue(StmtContext ctx, String value) + throws SourceException { return value; } - @Override public TypeStatement createDeclared( + @Override + public TypeStatement createDeclared( StmtContext ctx) { return new TypeStatementImpl(ctx); } - @Override public EffectiveStatement createEffective( + @Override + public EffectiveStatement createEffective( StmtContext> ctx) { - throw new UnsupportedOperationException(); + + // :FIXME improve the test of isExtended - e.g. unknown statements, + // etc.. + Collection> declaredSubstatements = ctx + .declaredSubstatements(); + boolean isExtended = declaredSubstatements.isEmpty() ? false + : true; + if (isExtended) + return new ExtendedTypeEffectiveStatementImpl(ctx, true); + + switch (ctx.getStatementArgument()) { + case TypeUtils.INT8: + return new Int8EffectiveStatementImpl(ctx); + case TypeUtils.INT16: + return new Int16EffectiveStatementImpl(ctx); + case TypeUtils.INT32: + return new Int32EffectiveStatementImpl(ctx); + case TypeUtils.INT64: + return new Int64EffectiveStatementImpl(ctx); + case TypeUtils.UINT8: + return new UInt8EffectiveStatementImpl(ctx); + case TypeUtils.UINT16: + return new UInt16EffectiveStatementImpl(ctx); + case TypeUtils.UINT32: + return new UInt32EffectiveStatementImpl(ctx); + case TypeUtils.UINT64: + return new UInt64EffectiveStatementImpl(ctx); + case TypeUtils.STRING: + return new StringEffectiveStatementImpl(ctx); + case TypeUtils.BOOLEAN: + return new BooleanEffectiveStatementImpl(ctx); + case TypeUtils.EMPTY: + return new EmptyEffectiveStatementImpl(ctx); + default: + // :FIXME try to resolve original typedef context here and + // return buildEffective of original typedef context + return new ExtendedTypeEffectiveStatementImpl(ctx, false); + } } } - @Nonnull @Override + @Nonnull + @Override public String getName() { return argument(); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypeUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypeUtils.java new file mode 100644 index 0000000000..9aa2e1d360 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypeUtils.java @@ -0,0 +1,329 @@ +/* + * 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 com.google.common.base.Optional; +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; +import org.opendaylight.yangtools.yang.model.util.BinaryType; +import org.opendaylight.yangtools.yang.model.util.BooleanType; +import org.opendaylight.yangtools.yang.model.util.EmptyType; +import org.opendaylight.yangtools.yang.model.util.Int16; +import org.opendaylight.yangtools.yang.model.util.Int32; +import org.opendaylight.yangtools.yang.model.util.Int64; +import org.opendaylight.yangtools.yang.model.util.Int8; +import org.opendaylight.yangtools.yang.model.util.StringType; +import org.opendaylight.yangtools.yang.model.util.Uint16; +import org.opendaylight.yangtools.yang.model.util.Uint32; +import org.opendaylight.yangtools.yang.model.util.Uint64; +import org.opendaylight.yangtools.yang.model.util.Uint8; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.LengthConstraintEffectiveImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.RangeConstraintEffectiveImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.TypeDefinitionEffectiveBuilder; +import org.opendaylight.yangtools.yang.parser.util.UnknownBoundaryNumber; + +/** +* util class for manipulating YANG base and extended types implementation +*/ +public final class TypeUtils { + + public static final String BINARY = "binary"; + public static final String BITS = "bits"; + public static final String BOOLEAN = "boolean"; + public static final String DECIMAL64 = "decimal64"; + public static final String EMPTY = "empty"; + public static final String ENUMERATION = "enumeration"; + public static final String IDENTITY_REF = "identityref"; + public static final String INSTANCE_IDENTIFIER = "instance-identifier"; + public static final String INT8 = "int8"; + public static final String INT16 = "int16"; + public static final String INT32 = "int32"; + public static final String INT64 = "int64"; + public static final String LEAF_REF = "leafref"; + public static final String STRING = "string"; + public static final String UINT8 = "uint8"; + public static final String UINT16 = "uint16"; + public static final String UINT32 = "uint32"; + public static final String UINT64 = "uint64"; + public static final String UNION = "union"; + + private static final ImmutableSet BUILT_IN_TYPES = initBuiltInTypesSet(); + private static final ImmutableSet TYPE_BODY_STMTS = initTypeBodyStmtsSet(); + private static final ImmutableMap BASE_TYPES_MAP = initBaseTypesMap(); + + private static final Comparator> TYPE_SORT_COMPARATOR = new Comparator>() { + @Override + public int compare(TypeDefinition o1, TypeDefinition o2) { + if (isBuiltInType(o1) && !isBuiltInType(o2)) { + return -1; + } + if (!isBuiltInType(o1) && isBuiltInType(o2)) { + return 1; + } + return 0; + } + }; + + private static ImmutableSet initBuiltInTypesSet() { + + final Set builtInTypesInit = new HashSet<>(); + builtInTypesInit.add(BINARY); + builtInTypesInit.add(BITS); + builtInTypesInit.add(BOOLEAN); + builtInTypesInit.add(DECIMAL64); + builtInTypesInit.add(EMPTY); + builtInTypesInit.add(ENUMERATION); + builtInTypesInit.add(IDENTITY_REF); + builtInTypesInit.add(INSTANCE_IDENTIFIER); + builtInTypesInit.add(INT8); + builtInTypesInit.add(INT16); + builtInTypesInit.add(INT32); + builtInTypesInit.add(INT64); + builtInTypesInit.add(LEAF_REF); + builtInTypesInit.add(STRING); + builtInTypesInit.add(UINT8); + builtInTypesInit.add(UINT16); + builtInTypesInit.add(UINT32); + builtInTypesInit.add(UINT64); + builtInTypesInit.add(UNION); + + return ImmutableSet.copyOf(builtInTypesInit); + } + + private static ImmutableSet initTypeBodyStmtsSet() { + + final Set typeBodyStmtsInit = new HashSet<>(); + typeBodyStmtsInit.add(DECIMAL64); + typeBodyStmtsInit.add(ENUMERATION); + typeBodyStmtsInit.add(LEAF_REF); + typeBodyStmtsInit.add(IDENTITY_REF); + typeBodyStmtsInit.add(INSTANCE_IDENTIFIER); + typeBodyStmtsInit.add(BITS); + typeBodyStmtsInit.add(UNION); + typeBodyStmtsInit.add(BINARY); + + return ImmutableSet.copyOf(typeBodyStmtsInit); + } + + private static ImmutableMap initBaseTypesMap() { + + final Map baseTypesMapInit = new HashMap<>(); + baseTypesMapInit.put(BINARY, BinaryType.getInstance()); + baseTypesMapInit.put(BOOLEAN, BooleanType.getInstance()); + baseTypesMapInit.put(EMPTY, EmptyType.getInstance()); + baseTypesMapInit.put(INT8, Int8.getInstance()); + baseTypesMapInit.put(INT16, Int16.getInstance()); + baseTypesMapInit.put(INT32, Int32.getInstance()); + baseTypesMapInit.put(INT64, Int64.getInstance()); + baseTypesMapInit.put(STRING, StringType.getInstance()); + baseTypesMapInit.put(UINT8, Uint8.getInstance()); + baseTypesMapInit.put(UINT16, Uint16.getInstance()); + baseTypesMapInit.put(UINT32, Uint32.getInstance()); + baseTypesMapInit.put(UINT64, Uint64.getInstance()); + + return ImmutableMap.copyOf(baseTypesMapInit); + } + + private TypeUtils() { + } + + private static final Splitter PIPE_SPLITTER = Splitter.on('|').trimResults(); + private static final Splitter TWO_DOTS_SPLITTER = Splitter.on("..").trimResults(); + + private static BigDecimal yangConstraintToBigDecimal(Number number) { + if (number instanceof UnknownBoundaryNumber) { + if (number.toString().equals("min")) { + return RangeStatementImpl.YANG_MIN_NUM; + } else { + return RangeStatementImpl.YANG_MAX_NUM; + } + } else { + return new BigDecimal(number.toString()); + } + } + + private static int compareNumbers(Number n1, Number n2) { + + final BigDecimal num1 = yangConstraintToBigDecimal(n1); + final BigDecimal num2 = yangConstraintToBigDecimal(n2); + + return new BigDecimal(num1.toString()).compareTo(new BigDecimal(num2.toString())); + } + + private static Number parseIntegerConstraintValue(final String value) { + Number result; + + if (isMinOrMaxString(value)) { + result = new UnknownBoundaryNumber(value); + } else { + try { + result = new BigInteger(value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(String.format("Value %s is not a valid integer", value), e); + } + } + return result; + } + + private static Number parseDecimalConstraintValue(final String value) { + final Number result; + + if (isMinOrMaxString(value)) { + result = new UnknownBoundaryNumber(value); + } else { + try { + if (value.indexOf('.') != -1) { + result = new BigDecimal(value); + } else { + result = new BigInteger(value); + } + } catch (NumberFormatException e) { + throw new IllegalArgumentException(String.format("Value %s is not a valid decimal number", value), e); + } + } + return result; + } + + private static boolean isMinOrMaxString(final String value) { + return "min".equals(value) || "max".equals(value); + } + + public static List parseRangeListFromString(String rangeArgument) { + + Optional description = Optional.absent(); + Optional reference = Optional.absent(); + + List rangeConstraints = new ArrayList<>(); + + for (final String singleRange : PIPE_SPLITTER.split(rangeArgument)) { + final Iterator boundaries = TWO_DOTS_SPLITTER.splitToList(singleRange).iterator(); + final Number min = parseDecimalConstraintValue(boundaries.next()); + + final Number max; + if (boundaries.hasNext()) { + max = parseDecimalConstraintValue(boundaries.next()); + + // if min larger than max then error + if (compareNumbers(min, max) == 1) { + throw new IllegalArgumentException(String.format( + "Range constraint %s has descending order of boundaries; should be ascending", singleRange)); + } + if (boundaries.hasNext()) { + throw new IllegalArgumentException("Wrong number of boundaries in range constraint " + singleRange); + } + } else { + max = min; + } + + // some of intervals overlapping + if (rangeConstraints.size() > 1 && compareNumbers(min, Iterables.getLast(rangeConstraints).getMax()) != 1) { + throw new IllegalArgumentException(String.format("Some of the ranges in %s are not disjoint", + rangeArgument)); + } + + rangeConstraints.add(new RangeConstraintEffectiveImpl(min, max, description, reference)); + } + + return rangeConstraints; + } + + public static List parseLengthListFromString(String rangeArgument) { + + Optional description = Optional.absent(); + Optional reference = Optional.absent(); + + List rangeConstraints = new ArrayList<>(); + + for (final String singleRange : PIPE_SPLITTER.split(rangeArgument)) { + final Iterator boundaries = TWO_DOTS_SPLITTER.splitToList(singleRange).iterator(); + final Number min = parseIntegerConstraintValue(boundaries.next()); + + final Number max; + if (boundaries.hasNext()) { + max = parseIntegerConstraintValue(boundaries.next()); + + // if min larger than max then error + if (compareNumbers(min, max) == 1) { + throw new IllegalArgumentException( + String.format( + "Length constraint %s has descending order of boundaries; should be ascending", + singleRange)); + } + if (boundaries.hasNext()) { + throw new IllegalArgumentException("Wrong number of boundaries in length constraint " + singleRange); + } + } else { + max = min; + } + + // some of intervals overlapping + if (rangeConstraints.size() > 1 && compareNumbers(min, Iterables.getLast(rangeConstraints).getMax()) != 1) { + throw new IllegalArgumentException(String.format("Some of the length ranges in %s are not disjoint", + rangeArgument)); + } + + rangeConstraints.add(new LengthConstraintEffectiveImpl(min, max, description, reference)); + } + + return rangeConstraints; + } + + public static boolean isYangBaseTypeString(String typeName) { + return BUILT_IN_TYPES.contains(typeName); + } + + public static boolean isYangTypeBodyStmt(String typeName) { + return TYPE_BODY_STMTS.contains(typeName); + } + + public static TypeDefinition getTypeFromEffectiveStatement(EffectiveStatement effectiveStatement) { + if (effectiveStatement instanceof TypeDefinitionEffectiveBuilder) { + TypeDefinitionEffectiveBuilder typeDefEffectiveBuilder = (TypeDefinitionEffectiveBuilder) effectiveStatement; + return typeDefEffectiveBuilder.buildType(); + } else { + final String typeName = ((TypeDefinition) effectiveStatement).getQName().getLocalName(); + return BASE_TYPES_MAP.get(typeName); + } + } + + public static TypeDefinition getYangBaseTypeFromString(String typeName) { + + if (BASE_TYPES_MAP.containsKey(typeName)) { + return BASE_TYPES_MAP.get(typeName); + } + + return null; + } + + public static void sortTypes(List> typesInit) { + Collections.sort(typesInit, TYPE_SORT_COMPARATOR); + } + + public static boolean isBuiltInType(TypeDefinition o1) { + return BUILT_IN_TYPES.contains(o1.getQName().getLocalName()); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypedefStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypedefStatementImpl.java index 595c280e87..5ab0e3cb52 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypedefStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypedefStatementImpl.java @@ -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 @@ -7,32 +7,30 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.UnitsStatement; - -import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement; +import javax.annotation.Nullable; 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.DescriptionStatement; 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.TypeStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.UnitsStatement; +import org.opendaylight.yangtools.yang.parser.spi.TypeNamespace; 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; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.TypeDefEffectiveStatementImpl; -public class TypedefStatementImpl extends AbstractDeclaredStatement - implements TypedefStatement { +public class TypedefStatementImpl extends AbstractDeclaredStatement implements TypedefStatement { - protected TypedefStatementImpl( - StmtContext context) { + protected TypedefStatementImpl(StmtContext context) { super(context); } - public static class Definition - extends + public static class Definition extends AbstractStatementSupport> { public Definition() { @@ -40,21 +38,33 @@ public class TypedefStatementImpl extends AbstractDeclaredStatement } @Override - public QName parseArgumentValue(StmtContext ctx, String value) - throws SourceException { + public QName parseArgumentValue(StmtContext ctx, String value) throws SourceException { return Utils.qNameFromArgument(ctx, value); } @Override - public TypedefStatement createDeclared( - StmtContext ctx) { + public TypedefStatement createDeclared(StmtContext ctx) { return new TypedefStatementImpl(ctx); } @Override public EffectiveStatement createEffective( StmtContext> ctx) { - throw new UnsupportedOperationException(); + return new TypeDefEffectiveStatementImpl(ctx); + } + + @Override + public void onStatementDefinitionDeclared( + StmtContext.Mutable> stmt) + throws SourceException { + if (stmt != null && stmt.getParentContext() != null) { + if (stmt.getParentContext().getFromNamespace(TypeNamespace.class, stmt.getStatementArgument()) != null) { + throw new IllegalArgumentException(String.format("Duplicate name for typedef %s", + stmt.getStatementArgument())); + } + + stmt.getParentContext().addContext(TypeNamespace.class, stmt.getStatementArgument(), stmt); + } } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UnionSpecificationImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UnionSpecificationImpl.java index 36ca6f5854..13df3b4d0f 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UnionSpecificationImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UnionSpecificationImpl.java @@ -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 @@ -8,13 +8,15 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; import java.util.Collection; + +import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -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.TypeStatement; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.UnionSpecificationEffectiveStatementImpl; public class UnionSpecificationImpl extends AbstractDeclaredStatement implements TypeStatement.UnionSpecification { @@ -24,9 +26,7 @@ public class UnionSpecificationImpl extends AbstractDeclaredStatement super(context); } - public static class Definition - extends - AbstractStatementSupport> { + public static class Definition extends AbstractStatementSupport> { public Definition() { super(Rfc6020Mapping.TYPE); @@ -47,7 +47,7 @@ public class UnionSpecificationImpl extends AbstractDeclaredStatement @Override public EffectiveStatement createEffective( StmtContext> ctx) { - throw new UnsupportedOperationException(); + return new UnionSpecificationEffectiveStatementImpl(ctx); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UniqueStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UniqueStatementImpl.java new file mode 100644 index 0000000000..ed95fbf06b --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UniqueStatementImpl.java @@ -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.parser.stmt.rfc6020; + +import java.util.Collection; +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.SchemaNodeIdentifier; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Relative; +import org.opendaylight.yangtools.yang.model.api.stmt.UniqueStatement; +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 org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.UniqueEffectiveStatementImpl; + +public class UniqueStatementImpl extends AbstractDeclaredStatement> implements UniqueStatement { + + protected UniqueStatementImpl(StmtContext, UniqueStatement, ?> context) { + super(context); + } + + public static class Definition + extends + AbstractStatementSupport, UniqueStatement, + EffectiveStatement, UniqueStatement>> { + + public Definition() { + super(Rfc6020Mapping.UNIQUE); + } + + @Override + public Collection parseArgumentValue(StmtContext ctx, String value) throws + SourceException { + return Utils.transformKeysStringToKeyNodes(ctx, value); + } + + @Override + public UniqueStatement createDeclared(StmtContext, UniqueStatement, ?> ctx) { + return new UniqueStatementImpl(ctx); + } + + @Override + public EffectiveStatement, UniqueStatement> createEffective + (StmtContext, UniqueStatement, EffectiveStatement, + UniqueStatement>> ctx) { + return new UniqueEffectiveStatementImpl(ctx); + } + } + + @Nonnull + @Override + public Collection getTag() { + return argument(); + } +} 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 index 86f24219ec..7b9dccf828 100644 --- 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 @@ -15,6 +15,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 org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.UnknownEffectiveStatementImpl; public class UnknownStatementImpl extends AbstractDeclaredStatement implements UnknownStatement { @@ -22,8 +23,9 @@ public class UnknownStatementImpl extends AbstractDeclaredStatement impl super(context); } - public static class Definition extends AbstractStatementSupport, EffectiveStatement>> { - + public static class Definition + extends + AbstractStatementSupport, EffectiveStatement>> { public Definition(final StatementDefinition publicDefinition) { super(publicDefinition); @@ -40,8 +42,9 @@ public class UnknownStatementImpl extends AbstractDeclaredStatement impl } @Override - public EffectiveStatement> createEffective(final StmtContext, EffectiveStatement>> ctx) { - throw new UnsupportedOperationException(); + public EffectiveStatement> createEffective( + final StmtContext, EffectiveStatement>> ctx) { + return new UnknownEffectiveStatementImpl(ctx); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UsesStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UsesStatementImpl.java index 102ad007ff..514b9f0408 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UsesStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UsesStatementImpl.java @@ -9,8 +9,9 @@ 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.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; +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; @@ -62,6 +63,10 @@ public class UsesStatementImpl extends AbstractDeclaredStatement implemen final StmtContext.Mutable> usesNode) throws SourceException { + if(StmtContextUtils.isInExtensionBody(usesNode)) { + return; + } + ModelActionBuilder usesAction = usesNode.newInferenceAction(FULL_DECLARATION); final QName groupingName = usesNode.getStatementArgument(); @@ -78,10 +83,11 @@ public class UsesStatementImpl extends AbstractDeclaredStatement implemen StatementContextBase sourceGrpStmtCtx = (StatementContextBase) sourceGroupingPre.get(); try { - GroupingUtils.copyFromSourceToTarget(sourceGrpStmtCtx, targetNodeStmtCtx); + GroupingUtils.copyFromSourceToTarget(sourceGrpStmtCtx, targetNodeStmtCtx, usesNode); GroupingUtils.resolveUsesNode(usesNode, targetNodeStmtCtx); } catch (SourceException e) { LOG.warn(e.getMessage(), e); + throw e; } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java index d55f99deda..1d6a8e84ff 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java @@ -9,36 +9,39 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf; -import java.util.Collection; +import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName; -import java.net.URI; -import java.net.URISyntaxException; +import com.google.common.base.CharMatcher; +import com.google.common.base.Splitter; import java.util.ArrayList; import java.util.Arrays; -import java.util.Date; +import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Objects; +import java.util.Set; 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.SimpleDateFormatUtil; import org.opendaylight.yangtools.yang.common.YangConstants; +import org.opendaylight.yangtools.yang.model.api.Deviation; import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement; import org.opendaylight.yangtools.yang.model.api.stmt.BelongsToStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Relative; import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; @@ -48,7 +51,11 @@ import org.opendaylight.yangtools.yang.parser.spi.source.ModuleIdentifierToModul 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.spi.validation.ValidationBundlesNamespace; +import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType; import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class Utils { @@ -57,13 +64,39 @@ public final class Utils { private static final CharMatcher SINGLE_QUOTE_MATCHER = CharMatcher .is('\''); + public static final QName EMPTY_QNAME = QName.create("empty", "empty"); + private static final char SEPARATOR_NODENAME = '/'; private static final String REGEX_PATH_ABS = "/[^/].*"; + public static final char SEPARATOR = ' '; + private Utils() { } + public static Collection transformKeysStringToKeyNodes(StmtContext ctx, String + value) { + Splitter keySplitter = Splitter.on(SEPARATOR).omitEmptyStrings().trimResults(); + List keyTokens = keySplitter.splitToList(value); + + // to detect if key contains duplicates + if ((new HashSet<>(keyTokens)).size() < keyTokens.size()) { + throw new IllegalArgumentException(); + } + + Set keyNodes = new HashSet<>(); + + for (String keyToken : keyTokens) { + + SchemaNodeIdentifier.Relative keyNode = (Relative) SchemaNodeIdentifier.Relative + .create(false, Utils.qNameFromArgument(ctx, keyToken)); + keyNodes.add(keyNode); + } + + return keyNodes; + } + public static List splitPathToNodeNames(String path) { Splitter keySplitter = Splitter.on(SEPARATOR_NODENAME) @@ -102,6 +135,14 @@ public final class Utils { return identifier; } + public static String getPrefixFromArgument(String prefixedLocalName) { + String[] namesParts = prefixedLocalName.split(":"); + if (namesParts.length == 2) { + return namesParts[0]; + } + return null; + } + public static boolean isValidStatementDefinition(PrefixToModule prefixes, QNameToStatementDefinition stmtDef, QName identifier) { if (stmtDef.get(identifier) != null) { @@ -120,6 +161,11 @@ public final class Utils { YangConstants.RFC6020_YIN_NAMESPACE, localName)) != null) { return true; + } else { + if (stmtDef.get(new QName( + YangConstants.RFC6020_YIN_NAMESPACE, localName)) != null) { + return true; + } } } } @@ -172,64 +218,100 @@ public final class Utils { public static QName qNameFromArgument(StmtContext ctx, String value) { + if (value == null || value.equals("")) { + return EMPTY_QNAME; + } + String prefix; QNameModule qNameModule = null; - try { - qNameModule = QNameModule.create(new URI(""), new Date(0)); - } catch (URISyntaxException e) { - LOG.warn(e.getMessage(), e); - } String localName = null; String[] namesParts = value.split(":"); switch (namesParts.length) { 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); - } + qNameModule = getRootModuleQName(ctx); 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); + qNameModule = getModuleQNameByPrefix(ctx, prefix); + //in case of unknown statement argument, we're not going to parse it + if (qNameModule == null && ctx.getPublicDefinition().getDeclaredRepresentationClass().isAssignableFrom + (UnknownStatementImpl.class)) { + localName = value; + qNameModule = getRootModuleQName(ctx); + } + //:FIXME test and verify this... + if(qNameModule == null && ctx.getTypeOfCopy() == StmtContext.TypeOfCopy.ADDED_BY_AUGMENTATION) { + ctx = ctx.getOriginalCtx(); + qNameModule = getModuleQNameByPrefix(ctx, prefix); } - break; default: break; } - return QName.create(qNameModule, localName); + if (qNameModule == null) { + throw new IllegalArgumentException("Error in module '" + + ctx.getRoot().rawStatementArgument() + + "': can not resolve QNameModule for '" + value + "'."); + } + + QNameModule resultQNameModule = qNameModule.getRevision() == null ? QNameModule + .create(qNameModule.getNamespace(), + SimpleDateFormatUtil.DEFAULT_DATE_REV) : qNameModule; + + return QName.create(resultQNameModule, localName); + } + + public static QNameModule getModuleQNameByPrefix(StmtContext ctx, + String prefix) { + QNameModule qNameModule; + 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); + } + return qNameModule; + } + + public static QNameModule getRootModuleQName(StmtContext ctx) { + + if (ctx == null) { + return null; + } + + StmtContext rootCtx = ctx.getRoot(); + QNameModule qNameModule = null; + + if (StmtContextUtils.producesDeclared(rootCtx, ModuleStatement.class)) { + qNameModule = rootCtx.getFromNamespace( + ModuleCtxToModuleQName.class, + rootCtx); + } else if (StmtContextUtils.producesDeclared(rootCtx, + SubmoduleStatement.class)) { + String belongsToModuleName = firstAttributeOf(ctx.getRoot() + .declaredSubstatements(), BelongsToStatement.class); + qNameModule = rootCtx.getFromNamespace( + ModuleNameToModuleQName.class, belongsToModuleName); + } + + return qNameModule.getRevision() == null ? QNameModule.create( + qNameModule.getNamespace(), + SimpleDateFormatUtil.DEFAULT_DATE_REV) : qNameModule; } @Nullable - public static StatementContextBase findCtxOfNodeInSubstatements( + public static StatementContextBase findNode( StatementContextBase rootStmtCtx, final Iterable path) { @@ -276,45 +358,122 @@ public final class Utils { } @Nullable - public static StatementContextBase findCtxOfNodeInRoot( + public static StatementContextBase findNode( StatementContextBase rootStmtCtx, final SchemaNodeIdentifier node) { - return findCtxOfNodeInSubstatements(rootStmtCtx, node.getPathFromRoot()); + return findNode(rootStmtCtx, node.getPathFromRoot()); } public static SchemaPath getSchemaPath(StmtContext ctx) { - Iterator argumentsIterator = ctx.getArgumentsFromRoot() - .iterator(); - argumentsIterator.next(); // skip root argument + if(ctx == null) { + return null; + } - List qNamesFromRoot = new LinkedList<>(); + Iterator> iteratorFromRoot = ctx + .getStmtContextsFromRoot().iterator(); + + if (iteratorFromRoot.hasNext()) { + iteratorFromRoot.next(); // skip root argument + } - while (argumentsIterator.hasNext()) { - Object argument = argumentsIterator.next(); - if (argument instanceof QName) { - QName qname = (QName) argument; + List qNamesFromRoot = new LinkedList<>(); + while (iteratorFromRoot.hasNext()) { + StmtContext nextStmtCtx = iteratorFromRoot.next(); + Object nextStmtArgument = nextStmtCtx.getStatementArgument(); + if (nextStmtArgument instanceof QName) { + QName qname = (QName) nextStmtArgument; + if (StmtContextUtils.producesDeclared( + nextStmtCtx.getParentContext(), ChoiceStatement.class) + && isSupportedAsShorthandCase(nextStmtCtx)) { + qNamesFromRoot.add(qname); + } qNamesFromRoot.add(qname); + } else if (nextStmtArgument instanceof String) { + final QName qName = qNameFromArgument(ctx, (String) nextStmtArgument); + qNamesFromRoot.add(qName); + } + else if (StmtContextUtils.producesDeclared(nextStmtCtx, + AugmentStatement.class) + && nextStmtArgument instanceof SchemaNodeIdentifier) { + addQNamesFromSchemaNodeIdentifierToList(qNamesFromRoot, + (SchemaNodeIdentifier) nextStmtArgument); + } else if (nextStmtCtx.getPublicDefinition().getDeclaredRepresentationClass().isAssignableFrom + (UnknownStatementImpl.class)) { + qNamesFromRoot.add(nextStmtCtx.getPublicDefinition().getStatementName()); } else { return SchemaPath.SAME; } } - return SchemaPath.create(qNamesFromRoot, true); + final SchemaPath schemaPath = SchemaPath.create(qNamesFromRoot, true); + return schemaPath; + } + + private static boolean isSupportedAsShorthandCase( + StmtContext statementCtx) { + + Collection supportedCaseShorthands = statementCtx.getFromNamespace( + ValidationBundlesNamespace.class, + ValidationBundleType.SUPPORTED_CASE_SHORTHANDS); + + return supportedCaseShorthands == null + || supportedCaseShorthands.contains(statementCtx + .getPublicDefinition()); + } + + private static void addQNamesFromSchemaNodeIdentifierToList( + List qNamesFromRoot, SchemaNodeIdentifier augmentTargetPath) { + Iterator augmentTargetPathIterator = augmentTargetPath + .getPathFromRoot().iterator(); + while (augmentTargetPathIterator.hasNext()) { + qNamesFromRoot.add(augmentTargetPathIterator.next()); + } } 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"); + + // Yang constants should be lowercase so we have throw if value does not + // suit this + String deviateUpper = deviate.toUpperCase(); + if (Objects.equals(deviate, deviateUpper)) { + throw new IllegalArgumentException(String.format( + "String %s is not valid deviate argument", deviate)); + } + + // but Java enum is uppercase so we cannot use lowercase here + try { + return Deviation.Deviate.valueOf(deviateUpper); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(String.format( + "String %s is not valid deviate argument", deviate), e); } } + + public static Status parseStatus(String value) { + + Status status = null; + switch (value) { + case "current": + status = Status.CURRENT; + break; + case "deprecated": + status = Status.DEPRECATED; + break; + case "obsolete": + status = Status.OBSOLETE; + break; + default: + LOG.warn("Invalid 'status' statement: " + value); + } + + return status; + } + + public static SchemaPath SchemaNodeIdentifierToSchemaPath( + SchemaNodeIdentifier identifier) { + return SchemaPath.create(identifier.getPathFromRoot(), + identifier.isAbsolute()); + } + } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ValueStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ValueStatementImpl.java index 558f4c0796..de57f4c946 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ValueStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ValueStatementImpl.java @@ -7,51 +7,58 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ValueEffectiveStatementImpl; - 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.ValueStatement; 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.stmt.rfc6020.effective.ValueEffectiveStatementImpl; -public class ValueStatementImpl extends AbstractDeclaredStatement - implements ValueStatement { +public class ValueStatementImpl extends AbstractDeclaredStatement implements ValueStatement { - protected ValueStatementImpl(StmtContext context) { + protected ValueStatementImpl(StmtContext context) { super(context); } - public static class Definition - extends - AbstractStatementSupport> { + public static class Definition extends + AbstractStatementSupport> { public Definition() { super(Rfc6020Mapping.VALUE); } @Override - public String parseArgumentValue(StmtContext ctx, String value) { - return value; + public Integer parseArgumentValue(StmtContext ctx, String value) { + int valueNum; + + try { + valueNum = Integer.parseInt(value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException( + String.format( + "%s is not valid value statement integer argument in a range of -2147483648..2147483647", + value), e); + } + + return valueNum; } @Override - public ValueStatement createDeclared( - StmtContext ctx) { + public ValueStatement createDeclared(StmtContext ctx) { return new ValueStatementImpl(ctx); } @Override - public EffectiveStatement createEffective( - StmtContext> ctx) { + public EffectiveStatement createEffective( + StmtContext> ctx) { return new ValueEffectiveStatementImpl(ctx); } } @Override - public String getValue() { + public Integer getValue() { return argument(); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/WhenStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/WhenStatementImpl.java index 7e5fc5646f..78d60b1932 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/WhenStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/WhenStatementImpl.java @@ -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 @@ -39,7 +39,7 @@ public class WhenStatementImpl extends AbstractDeclaredStatement ctx, String value) throws SourceException { - return new RevisionAwareXPathImpl(value, false); + return new RevisionAwareXPathImpl(value, Utils.isXPathAbsolute(value)); } @Override public WhenStatement createDeclared( diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java index 933cf31f40..ddf81a8292 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java @@ -10,101 +10,137 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; import static org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.global; import static org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.sourceLocal; import static org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.treeScoped; +import static org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType; -import java.util.Map; +import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName; +import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition; +import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.DerivedIdentitiesNamespace; +import org.opendaylight.yangtools.yang.parser.spi.IdentityNamespace; +import org.opendaylight.yangtools.yang.parser.spi.source.IncludedSubmoduleNameToIdentifier; import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace; +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.TypeNamespace; +import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToModuleContext; +import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNamespaceForBelongsTo; 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()) + public static final StatementSupportBundle INIT_BUNDLE = StatementSupportBundle + .builder().addSupport(global(ValidationBundlesNamespace.class)) + .build(); + + public static final StatementSupportBundle LINKAGE_BUNDLE = StatementSupportBundle + .derivedFrom(INIT_BUNDLE) + .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(ModuleNamespaceForBelongsTo.class)) .addSupport(global(SubmoduleNamespace.class)) .addSupport(global(NamespaceToModule.class)) .addSupport(global(ModuleNameToModuleQName.class)) + .addSupport(global(ModuleCtxToModuleQName.class)) .addSupport(global(ModuleQNameToModuleName.class)) .addSupport(global(PrefixToModule.class)) .addSupport(global(ModuleIdentifierToModuleQName.class)) .addSupport(sourceLocal(ImportedModuleContext.class)) .addSupport(sourceLocal(IncludedModuleContext.class)) + .addSupport(sourceLocal(IncludedSubmoduleNameToIdentifier.class)) .addSupport(sourceLocal(ImpPrefixToModuleIdentifier.class)) - .addSupport(sourceLocal(BelongsToPrefixToModuleName.class)) - .addSupport(sourceLocal(QNameToStatementDefinition.class)).build(); + .addSupport(sourceLocal(BelongsToModuleContext.class)) + .addSupport(sourceLocal(QNameToStatementDefinition.class)) + .addSupport(sourceLocal(BelongsToPrefixToModuleName.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()).addSupport(global(ExtensionNamespace.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()) + .addSupport(global(ExtensionNamespace.class)) + .addSupport(new TypedefStatementImpl.Definition()) + .addSupport(treeScoped(TypeNamespace.class)) + .addSupport(new IdentityStatementImpl.Definition()) + .addSupport(global(IdentityNamespace.class)) + .addSupport(new DefaultStatementImpl.Definition()) + .addSupport(new StatusStatementImpl.Definition()) + .addSupport(new TypeStatementImpl.Definition()) + .addSupport(new UnitsStatementImpl.Definition()) + .addSupport(new RequireInstanceStatementImpl.Definition()) + .addSupport(new BitStatementImpl.Definition()) + .addSupport(new PathStatementImpl.Definition()) + .addSupport(new EnumStatementImpl.Definition()) + .addSupport(new LengthStatementImpl.Definition()) + .addSupport(new PatternStatementImpl.Definition()) + .addSupport(new RangeStatementImpl.Definition()) + .addSupport(new ContainerStatementImpl.Definition()) + .addSupport(new GroupingStatementImpl.Definition()) + .addSupport(new ListStatementImpl.Definition()) + .addSupport(new UniqueStatementImpl.Definition()) + .addSupport(new RpcStatementImpl.Definition()) + .addSupport(new InputStatementImpl.Definition()) + .addSupport(new OutputStatementImpl.Definition()) + .addSupport(new NotificationStatementImpl.Definition()) + .addSupport(new FractionDigitsStatementImpl.Definition()) + .addSupport(new BaseStatementImpl.Definition()) + .addSupport(global(DerivedIdentitiesNamespace.class)) + .build(); private static final StatementSupportBundle FULL_DECL_BUNDLE = StatementSupportBundle .derivedFrom(STMT_DEF_BUNDLE) - .addSupport(new ContainerStatementImpl.Definition()) .addSupport(new LeafStatementImpl.Definition()) - .addSupport(new TypeStatementImpl.Definition()) .addSupport(new ConfigStatementImpl.Definition()) .addSupport(new DeviationStatementImpl.Definition()) .addSupport(new DeviateStatementImpl.Definition()) .addSupport(new ChoiceStatementImpl.Definition()) .addSupport(new CaseStatementImpl.Definition()) - .addSupport(new DefaultStatementImpl.Definition()) .addSupport(new MustStatementImpl.Definition()) .addSupport(new MandatoryStatementImpl.Definition()) - .addSupport(new TypedefStatementImpl.Definition()) .addSupport(new AnyxmlStatementImpl.Definition()) .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(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()) + .addSupport(treeScoped(GroupingNamespace.class)) //treeScoped + .addSupport(new ErrorMessageStatementImpl.Definition()) + .addSupport(new ErrorAppTagStatementImpl.Definition()) + .addSupport(new LeafListStatementImpl.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 FeatureStatementImpl.Definition()) + .addSupport(new PositionStatementImpl.Definition()) + .addSupport(new ValueStatementImpl.Definition()) .build(); public static final Map RFC6020_BUNDLES = ImmutableMap @@ -112,13 +148,27 @@ public final class YangInferencePipeline { .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.EFFECTIVE_MODEL, FULL_DECL_BUNDLE) + .build(); - public static final CrossSourceStatementReactor RFC6020_REACTOR = CrossSourceStatementReactor.builder() + public static final CrossSourceStatementReactor RFC6020_REACTOR = CrossSourceStatementReactor + .builder() + .setBundle(ModelProcessingPhase.INIT, INIT_BUNDLE) .setBundle(ModelProcessingPhase.SOURCE_LINKAGE, LINKAGE_BUNDLE) - .setBundle(ModelProcessingPhase.STATEMENT_DEFINITION, STMT_DEF_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.EFFECTIVE_MODEL, FULL_DECL_BUNDLE) + .setValidationBundle( + ValidationBundleType.SUPPORTED_REFINE_SUBSTATEMENTS, + YangValidationBundles.SUPPORTED_REFINE_SUBSTATEMENTS) + .setValidationBundle(ValidationBundleType.SUPPORTED_AUGMENT_TARGETS, + YangValidationBundles.SUPPORTED_AUGMENT_TARGETS) + .setValidationBundle(ValidationBundleType.SUPPORTED_CASE_SHORTHANDS, + YangValidationBundles.SUPPORTED_CASE_SHORTHANDS) + .setValidationBundle(ValidationBundleType.SUPPORTED_DATA_NODES, + YangValidationBundles.SUPPORTED_DATA_NODES) + .build(); private YangInferencePipeline() { throw new UnsupportedOperationException("Utility class"); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangStatementSourceImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangStatementSourceImpl.java index 85b9df00b2..96746e8b51 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangStatementSourceImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangStatementSourceImpl.java @@ -18,13 +18,11 @@ 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.model.parser.api.YangSyntaxErrorException; 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 org.slf4j.Logger; @@ -36,27 +34,29 @@ import org.slf4j.LoggerFactory; * in order to emit YANG statements using supplied StatementWriter * */ - public final class YangStatementSourceImpl implements StatementStreamSource { private YangStatementParserListenerImpl yangStatementModelParser; private YangStatementParser.StatementContext statementContext; private ParseTreeWalker walker; + private String sourceName; private static final Logger LOG = LoggerFactory.getLogger(YangStatementSourceImpl.class); - private static final StatementSourceReference REF = new StatementSourceReference() { - - @Override - public StatementSource getStatementSource() { - return StatementSource.DECLARATION; + public YangStatementSourceImpl(final String fileName, boolean isAbsolute) { + try { + statementContext = parseYangSource(loadFile(fileName, isAbsolute)); + walker = new ParseTreeWalker(); + yangStatementModelParser = new YangStatementParserListenerImpl(fileName); + } catch (Exception e) { + LOG.warn(e.getMessage(), e); } - }; + } - public YangStatementSourceImpl(final String fileName) { + public YangStatementSourceImpl(final InputStream inputStream) { try { - statementContext = parseYangSource(loadFile(fileName)); + statementContext = parseYangSource(inputStream); walker = new ParseTreeWalker(); - yangStatementModelParser = new YangStatementParserListenerImpl(REF); + yangStatementModelParser = new YangStatementParserListenerImpl(sourceName); } catch (Exception e) { LOG.warn(e.getMessage(), e); } @@ -80,14 +80,15 @@ public final class YangStatementSourceImpl implements StatementStreamSource { walker.walk(yangStatementModelParser, statementContext); } - private FileInputStream loadFile(final String fileName) throws URISyntaxException, FileNotFoundException { - return new FileInputStream(new File(getClass().getResource(fileName).toURI())); + private FileInputStream loadFile(final String fileName, boolean isAbsolute) throws URISyntaxException, FileNotFoundException { + return isAbsolute ? new FileInputStream(new File(fileName)) : new FileInputStream(new File(getClass().getResource(fileName).toURI())); } - private static YangStatementParser.StatementContext parseYangSource(final InputStream stream) throws IOException, YangSyntaxErrorException { + private YangStatementParser.StatementContext parseYangSource(final InputStream stream) throws IOException, YangSyntaxErrorException { final YangStatementLexer lexer = new YangStatementLexer(new ANTLRInputStream(stream)); final CommonTokenStream tokens = new CommonTokenStream(lexer); final YangStatementParser parser = new YangStatementParser(tokens); + sourceName = parser.getSourceName(); return parser.statement(); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangValidationBundles.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangValidationBundles.java new file mode 100644 index 0000000000..b6b61c5209 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangValidationBundles.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; +import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; + +public final class YangValidationBundles { + + public static final HashSet SUPPORTED_REFINE_SUBSTATEMENTS = new HashSet<>( + Arrays.asList(new StatementDefinition[] { Rfc6020Mapping.DEFAULT, + Rfc6020Mapping.DESCRIPTION, Rfc6020Mapping.REFERENCE, + Rfc6020Mapping.CONFIG, Rfc6020Mapping.MANDATORY, + Rfc6020Mapping.MUST, Rfc6020Mapping.PRESENCE, + Rfc6020Mapping.MIN_ELEMENTS, Rfc6020Mapping.MAX_ELEMENTS })); + + public static final HashMap> SUPPORTED_REFINE_TARGETS = new HashMap<>(); + static { + SUPPORTED_REFINE_TARGETS.put(Rfc6020Mapping.DEFAULT, new HashSet<>( + Arrays.asList(new StatementDefinition[] { Rfc6020Mapping.LEAF, Rfc6020Mapping.CHOICE }))); + SUPPORTED_REFINE_TARGETS.put(Rfc6020Mapping.MANDATORY, new HashSet<>( + Arrays.asList(new StatementDefinition[] { Rfc6020Mapping.LEAF, Rfc6020Mapping.CHOICE, Rfc6020Mapping.ANYXML }))); + SUPPORTED_REFINE_TARGETS.put(Rfc6020Mapping.PRESENCE, new HashSet<>( + Arrays.asList(new StatementDefinition[] { Rfc6020Mapping.CONTAINER }))); + SUPPORTED_REFINE_TARGETS.put(Rfc6020Mapping.MUST, new HashSet<>( + Arrays.asList(new StatementDefinition[] { Rfc6020Mapping.CONTAINER, + Rfc6020Mapping.LIST, Rfc6020Mapping.LEAF, + Rfc6020Mapping.LEAF_LIST, Rfc6020Mapping.ANYXML, }))); + SUPPORTED_REFINE_TARGETS.put(Rfc6020Mapping.MIN_ELEMENTS, new HashSet<>( + Arrays.asList(new StatementDefinition[]{Rfc6020Mapping.LIST, Rfc6020Mapping.LEAF_LIST}))); + SUPPORTED_REFINE_TARGETS.put(Rfc6020Mapping.MAX_ELEMENTS, new HashSet<>( + Arrays.asList(new StatementDefinition[]{Rfc6020Mapping.LIST, Rfc6020Mapping.LEAF_LIST}))); + } + + + public static final HashSet SUPPORTED_AUGMENT_TARGETS = new HashSet<>( + Arrays.asList(new StatementDefinition[] { Rfc6020Mapping.CONTAINER, + Rfc6020Mapping.LIST, Rfc6020Mapping.CASE, + Rfc6020Mapping.INPUT, Rfc6020Mapping.OUTPUT, + Rfc6020Mapping.NOTIFICATION, Rfc6020Mapping.CHOICE, + Rfc6020Mapping.RPC })); + + public static final HashSet SUPPORTED_CASE_SHORTHANDS = new HashSet<>( + Arrays.asList(new StatementDefinition[] { Rfc6020Mapping.CONTAINER, + Rfc6020Mapping.LIST, Rfc6020Mapping.LEAF, + Rfc6020Mapping.LEAF_LIST, Rfc6020Mapping.ANYXML, })); + + public static final HashSet SUPPORTED_DATA_NODES = new HashSet<>( + Arrays.asList(new StatementDefinition[] { Rfc6020Mapping.CONTAINER, + Rfc6020Mapping.LIST, Rfc6020Mapping.LEAF, + Rfc6020Mapping.LEAF_LIST, Rfc6020Mapping.ANYXML, })); + + private YangValidationBundles() { + throw new UnsupportedOperationException("Utility class"); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDocumentedDataNodeContainer.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDocumentedDataNodeContainer.java index f17f3348d5..5056929b80 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDocumentedDataNodeContainer.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDocumentedDataNodeContainer.java @@ -7,17 +7,18 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import com.google.common.collect.ImmutableSet; +import org.opendaylight.yangtools.yang.model.util.ExtendedType; +import java.util.LinkedHashSet; +import java.util.LinkedHashMap; +import com.google.common.collect.ImmutableSet; 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.Set; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; @@ -42,30 +43,47 @@ public abstract class AbstractEffectiveDocumentedDataNodeContainer> effectiveSubstatements = effectiveSubstatements(); - Map mutableChildNodes = new HashMap(); - Set mutableGroupings = new HashSet(); - Set mutableUses = new HashSet(); - Set> mutableTypeDefinitions = new HashSet>(); - Set mutablePublicChildNodes = new HashSet(); + Map mutableChildNodes = new LinkedHashMap<>(); + Set mutableGroupings = new HashSet<>(); + Set mutableUses = new HashSet<>(); + Set> mutableTypeDefinitions = new LinkedHashSet<>(); + Set mutablePublicChildNodes = new LinkedHashSet<>(); for (EffectiveStatement effectiveStatement : effectiveSubstatements) { if (effectiveStatement instanceof DataSchemaNode) { DataSchemaNode dataSchemaNode = (DataSchemaNode) effectiveStatement; - - mutableChildNodes.put(dataSchemaNode.getQName(), dataSchemaNode); - mutablePublicChildNodes.add(dataSchemaNode); + if (!mutableChildNodes.containsKey(dataSchemaNode.getQName())) { + mutableChildNodes.put(dataSchemaNode.getQName(), + dataSchemaNode); + mutablePublicChildNodes.add(dataSchemaNode); + } else { + throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement); + } } if (effectiveStatement instanceof UsesNode) { UsesNode usesNode = (UsesNode) effectiveStatement; - mutableUses.add(usesNode); + if (!mutableUses.contains(usesNode)) { + mutableUses.add(usesNode); + } else { + throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement); + } } - if (effectiveStatement instanceof TypeDefinition) { - TypeDefinition typeDef = (TypeDefinition) effectiveStatement; - mutableTypeDefinitions.add(typeDef); + if (effectiveStatement instanceof TypeDefEffectiveStatementImpl) { + TypeDefEffectiveStatementImpl typeDef = (TypeDefEffectiveStatementImpl) effectiveStatement; + ExtendedType extendedType = typeDef.buildType(); + if (!mutableTypeDefinitions.contains(extendedType)) { + mutableTypeDefinitions.add(extendedType); + } else { + throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement); + } } if (effectiveStatement instanceof GroupingDefinition) { GroupingDefinition grp = (GroupingDefinition) effectiveStatement; - mutableGroupings.add(grp); + if (!mutableGroupings.contains(grp)) { + mutableGroupings.add(grp); + } else { + throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement); + } } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDocumentedNode.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDocumentedNode.java index 763b142162..6d79510f9e 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDocumentedNode.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDocumentedNode.java @@ -27,18 +27,27 @@ public abstract class AbstractEffectiveDocumentedNode> ctx) { - TypeOfCopy typeOfCopy = ctx.getTypeOfCopy(); - switch (typeOfCopy) { - case ADDED_BY_AUGMENTATION: + Set copyTypesFromOriginal = StmtContextUtils.getCopyTypesFromOriginal(ctx); + + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION)) { augmenting = true; - original = (AnyXmlSchemaNode) ctx.getOriginalCtx().buildEffective(); - break; - case ADDED_BY_USES: + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) { addedByUses = true; + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) { + addedByUses = augmenting = true; + } + + if (ctx.getTypeOfCopy() != TypeOfCopy.ORIGINAL) { original = (AnyXmlSchemaNode) ctx.getOriginalCtx().buildEffective(); - break; - default: - break; } } - private void initSubstatementCollections() { + private void initSubstatementCollectionsAndFields() { Collection> effectiveSubstatements = effectiveSubstatements(); List unknownNodesInit = new LinkedList<>(); + boolean configurationInit = false; for (EffectiveStatement effectiveStatement : effectiveSubstatements) { if (effectiveStatement instanceof UnknownSchemaNode) { UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement; unknownNodesInit.add(unknownNode); } + if (!configurationInit + && effectiveStatement instanceof ConfigEffectiveStatementImpl) { + ConfigEffectiveStatementImpl configStmt = (ConfigEffectiveStatementImpl) effectiveStatement; + this.configuration = configStmt.argument(); + configurationInit = true; + } } this.unknownNodes = ImmutableList.copyOf(unknownNodesInit); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AugmentEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AugmentEffectiveStatementImpl.java index 39e51d1f97..425ab74123 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AugmentEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AugmentEffectiveStatementImpl.java @@ -8,6 +8,10 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; import static com.google.common.base.Preconditions.checkNotNull; + +import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; +import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase; import java.util.Collection; import java.util.LinkedList; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; @@ -42,7 +46,8 @@ public class AugmentEffectiveStatementImpl private AugmentationSchema copyOf; public AugmentEffectiveStatementImpl( - StmtContext> ctx) { + StmtContext> ctx){ + super(ctx); SchemaNodeIdentifier schemaNodeIdentifier = ctx.getStatementArgument(); @@ -50,23 +55,40 @@ public class AugmentEffectiveStatementImpl schemaNodeIdentifier.getPathFromRoot(), schemaNodeIdentifier.isAbsolute()); - // :TODO init other fields + QNameModule rootModuleQName = Utils.getRootModuleQName(ctx); + this.namespace = rootModuleQName.getNamespace(); + this.revision = rootModuleQName.getRevision(); + this.order = 1; - // firstEffective(WhenEffectiveStatementImpl.class); + initCopyOf(ctx); initSubstatementCollections(); } + private void initCopyOf( + StmtContext> ctx) { + StatementContextBase originalCtx = ctx.getOriginalCtx(); + if (originalCtx != null) { + this.copyOf = (AugmentationSchema) originalCtx.buildEffective(); + } + } + private void initSubstatementCollections() { Collection> effectiveSubstatements = effectiveSubstatements(); List unknownNodesInit = new LinkedList<>(); + boolean initWhen = false; for (EffectiveStatement effectiveStatement : effectiveSubstatements) { if (effectiveStatement instanceof UnknownSchemaNode) { UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement; unknownNodesInit.add(unknownNode); } + if(!initWhen && effectiveStatement instanceof WhenEffectiveStatementImpl) { + WhenEffectiveStatementImpl whenStmt = (WhenEffectiveStatementImpl) effectiveStatement; + whenCondition = whenStmt.argument(); + initWhen = true; + } } this.unknownNodes = ImmutableList.copyOf(unknownNodesInit); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/CaseEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/CaseEffectiveStatementImpl.java index 50fb528446..8cbd413590 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/CaseEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/CaseEffectiveStatementImpl.java @@ -7,8 +7,9 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; import java.util.Collection; import java.util.HashSet; import java.util.LinkedList; @@ -48,7 +49,7 @@ public class CaseEffectiveStatementImpl extends super(ctx); this.qname = ctx.getStatementArgument(); this.path = Utils.getSchemaPath(ctx); - // :TODO init other fields + this.constraints = new EffectiveConstraintDefinitionImpl(this); initSubstatementCollections(); initCopyType(ctx); @@ -57,18 +58,20 @@ public class CaseEffectiveStatementImpl extends private void initCopyType( StmtContext> ctx) { - TypeOfCopy typeOfCopy = ctx.getTypeOfCopy(); - switch (typeOfCopy) { - case ADDED_BY_AUGMENTATION: + Set copyTypesFromOriginal = StmtContextUtils.getCopyTypesFromOriginal(ctx); + + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION)) { augmenting = true; - original = (ChoiceCaseNode) ctx.getOriginalCtx().buildEffective(); - break; - case ADDED_BY_USES: + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) { addedByUses = true; + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) { + addedByUses = augmenting = true; + } + + if (ctx.getTypeOfCopy() != TypeOfCopy.ORIGINAL) { original = (ChoiceCaseNode) ctx.getOriginalCtx().buildEffective(); - break; - default: - break; } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/CaseShorthandImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/CaseShorthandImpl.java new file mode 100644 index 0000000000..8554da34df --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/CaseShorthandImpl.java @@ -0,0 +1,138 @@ +/** + * 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.effective; + +import com.google.common.collect.Iterables; +import java.util.Collections; +import java.util.Arrays; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UsesNode; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; +import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; +import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; + +public class CaseShorthandImpl implements ChoiceCaseNode { + + private final DataSchemaNode caseShorthandNode; + private final QName qName; + private final SchemaPath path; + + public CaseShorthandImpl(DataSchemaNode caseShorthandNode) { + this.caseShorthandNode = caseShorthandNode; + this.qName = caseShorthandNode.getQName(); + + SchemaPath caseShorthandNodePath = caseShorthandNode.getPath(); + Iterable pathFromRoot = caseShorthandNodePath.getPathFromRoot(); + this.path = SchemaPath + .create(Iterables.limit(pathFromRoot, + Iterables.size(pathFromRoot) - 1), + caseShorthandNodePath.isAbsolute()); + } + + @Override + public boolean isAugmenting() { + return caseShorthandNode.isAugmenting(); + } + + @Override + public boolean isAddedByUses() { + return caseShorthandNode.isAddedByUses(); + } + + @Override + public boolean isConfiguration() { + return caseShorthandNode.isConfiguration(); + } + + @Override + public ConstraintDefinition getConstraints() { + return caseShorthandNode.getConstraints(); + } + + @Override + public QName getQName() { + return caseShorthandNode.getQName(); + } + + @Override + public SchemaPath getPath() { + return path; + } + + @Override + public List getUnknownSchemaNodes() { + return caseShorthandNode.getUnknownSchemaNodes(); + } + + @Override + public String getDescription() { + return caseShorthandNode.getDescription(); + } + + @Override + public String getReference() { + return caseShorthandNode.getReference(); + } + + @Override + public Status getStatus() { + return caseShorthandNode.getStatus(); + } + + @Override + public Set> getTypeDefinitions() { + return Collections.emptySet(); + } + + @Override + public Collection getChildNodes() { + return Arrays.asList(caseShorthandNode); + } + + @Override + public Set getGroupings() { + return Collections.emptySet(); + } + + @Override + public DataSchemaNode getDataChildByName(QName name) { + if (qName.equals(name)) { + return caseShorthandNode; + } else { + return null; + } + } + + @Override + public DataSchemaNode getDataChildByName(String name) { + if (qName.getLocalName().equals(name)) { + return caseShorthandNode; + } else { + return null; + } + } + + @Override + public Set getUses() { + return Collections.emptySet(); + } + + @Override + public Set getAvailableAugmentations() { + return Collections.emptySet(); + } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ChoiceEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ChoiceEffectiveStatementImpl.java index 7c36706d07..fc87e1bd2a 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ChoiceEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ChoiceEffectiveStatementImpl.java @@ -7,8 +7,15 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; import java.util.Collection; import java.util.HashSet; import java.util.LinkedList; @@ -30,14 +37,16 @@ import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; -public class ChoiceEffectiveStatementImpl extends AbstractEffectiveDocumentedNode implements ChoiceSchemaNode, DerivableSchemaNode { +public class ChoiceEffectiveStatementImpl extends + AbstractEffectiveDocumentedNode implements + ChoiceSchemaNode, DerivableSchemaNode { private final QName qname; private final SchemaPath path; boolean augmenting; boolean addedByUses; ChoiceSchemaNode original; - boolean configuration; + boolean configuration = true; ConstraintDefinition constraints; String defaultCase; @@ -45,42 +54,47 @@ public class ChoiceEffectiveStatementImpl extends AbstractEffectiveDocumentedNod ImmutableSet augmentations; ImmutableList unknownNodes; - public ChoiceEffectiveStatementImpl(StmtContext> ctx) { + public ChoiceEffectiveStatementImpl( + StmtContext> ctx) { super(ctx); this.qname = ctx.getStatementArgument(); this.path = Utils.getSchemaPath(ctx); - //:TODO init other fields + this.constraints = new EffectiveConstraintDefinitionImpl(this); - initSubstatementCollections(); + initSubstatementCollectionsAndFields(); initCopyType(ctx); } private void initCopyType( StmtContext> ctx) { - TypeOfCopy typeOfCopy = ctx.getTypeOfCopy(); - switch (typeOfCopy) { - case ADDED_BY_AUGMENTATION: + Set copyTypesFromOriginal = StmtContextUtils.getCopyTypesFromOriginal(ctx); + + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION)) { augmenting = true; - original = (ChoiceSchemaNode) ctx.getOriginalCtx().buildEffective(); - break; - case ADDED_BY_USES: + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) { addedByUses = true; + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) { + addedByUses = augmenting = true; + } + + if (ctx.getTypeOfCopy() != TypeOfCopy.ORIGINAL) { original = (ChoiceSchemaNode) ctx.getOriginalCtx().buildEffective(); - break; - default: - break; } } - private void initSubstatementCollections() { + private void initSubstatementCollectionsAndFields() { Collection> effectiveSubstatements = effectiveSubstatements(); List unknownNodesInit = new LinkedList<>(); Set augmentationsInit = new HashSet<>(); Set casesInit = new HashSet<>(); + boolean configurationInit = false; + boolean defaultInit = false; for (EffectiveStatement effectiveStatement : effectiveSubstatements) { if (effectiveStatement instanceof UnknownSchemaNode) { UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement; @@ -94,6 +108,27 @@ public class ChoiceEffectiveStatementImpl extends AbstractEffectiveDocumentedNod ChoiceCaseNode choiceCaseNode = (ChoiceCaseNode) effectiveStatement; casesInit.add(choiceCaseNode); } + if (effectiveStatement instanceof AnyXmlSchemaNode + || effectiveStatement instanceof ContainerSchemaNode + || effectiveStatement instanceof ListSchemaNode + || effectiveStatement instanceof LeafListSchemaNode + || effectiveStatement instanceof LeafSchemaNode) { + ChoiceCaseNode shorthandCase = new CaseShorthandImpl( + (DataSchemaNode) effectiveStatement); + casesInit.add(shorthandCase); + } + if (!configurationInit + && effectiveStatement instanceof ConfigEffectiveStatementImpl) { + ConfigEffectiveStatementImpl configStmt = (ConfigEffectiveStatementImpl) effectiveStatement; + this.configuration = configStmt.argument(); + configurationInit = true; + } + if (!defaultInit + && effectiveStatement instanceof DefaultEffectiveStatementImpl) { + DefaultEffectiveStatementImpl defaultCaseStmt = (DefaultEffectiveStatementImpl) effectiveStatement; + this.defaultCase = defaultCaseStmt.argument(); + defaultInit = true; + } } this.unknownNodes = ImmutableList.copyOf(unknownNodesInit); @@ -154,7 +189,8 @@ public class ChoiceEffectiveStatementImpl extends AbstractEffectiveDocumentedNod @Override public ChoiceCaseNode getCaseNodeByName(final QName name) { if (name == null) { - throw new IllegalArgumentException("Choice Case QName cannot be NULL!"); + throw new IllegalArgumentException( + "Choice Case QName cannot be NULL!"); } for (final ChoiceCaseNode caseNode : cases) { if (caseNode != null && name.equals(caseNode.getQName())) { @@ -167,7 +203,8 @@ public class ChoiceEffectiveStatementImpl extends AbstractEffectiveDocumentedNod @Override public ChoiceCaseNode getCaseNodeByName(final String name) { if (name == null) { - throw new IllegalArgumentException("Choice Case string Name cannot be NULL!"); + throw new IllegalArgumentException( + "Choice Case string Name cannot be NULL!"); } for (final ChoiceCaseNode caseNode : cases) { if (caseNode != null && (caseNode.getQName() != null) @@ -223,7 +260,8 @@ public class ChoiceEffectiveStatementImpl extends AbstractEffectiveDocumentedNod @Override public String toString() { - StringBuilder sb = new StringBuilder(ChoiceEffectiveStatementImpl.class.getSimpleName()); + StringBuilder sb = new StringBuilder( + ChoiceEffectiveStatementImpl.class.getSimpleName()); sb.append("["); sb.append("qname=").append(qname); sb.append("]"); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ContainerEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ContainerEffectiveStatementImpl.java index 7cb1b79a54..58b31c72d4 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ContainerEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ContainerEffectiveStatementImpl.java @@ -7,8 +7,9 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; +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; @@ -39,7 +40,7 @@ public class ContainerEffectiveStatementImpl extends private boolean presence; private boolean augmenting; private boolean addedByUses; - private boolean configuration; + private boolean configuration = true; private ContainerSchemaNode original; private ConstraintDefinition constraints; @@ -52,36 +53,39 @@ public class ContainerEffectiveStatementImpl extends qname = ctx.getStatementArgument(); path = Utils.getSchemaPath(ctx); + this.constraints = new EffectiveConstraintDefinitionImpl(this); initCopyType(ctx); - initFields(); - // :TODO init other fields + initSubstatementCollectionsAndFields(); } private void initCopyType( StmtContext> ctx) { - TypeOfCopy typeOfCopy = ctx.getTypeOfCopy(); - switch (typeOfCopy) { - case ADDED_BY_AUGMENTATION: + Set copyTypesFromOriginal = StmtContextUtils.getCopyTypesFromOriginal(ctx); + + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION)) { augmenting = true; - original = (ContainerSchemaNode) ctx.getOriginalCtx().buildEffective(); - break; - case ADDED_BY_USES: + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) { addedByUses = true; + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) { + addedByUses = augmenting = true; + } + + if (ctx.getTypeOfCopy() != TypeOfCopy.ORIGINAL) { original = (ContainerSchemaNode) ctx.getOriginalCtx().buildEffective(); - break; - default: - break; } } - private void initFields() { + private void initSubstatementCollectionsAndFields() { Collection> effectiveSubstatements = effectiveSubstatements(); List unknownNodesInit = new LinkedList<>(); Set augmentationsInit = new HashSet<>(); + boolean configurationInit = false; for (EffectiveStatement effectiveSubstatement : effectiveSubstatements) { if (effectiveSubstatement instanceof UnknownSchemaNode) { UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveSubstatement; @@ -94,9 +98,11 @@ public class ContainerEffectiveStatementImpl extends if (effectiveSubstatement instanceof PresenceEffectiveStatementImpl) { presence = true; } - if (effectiveSubstatement instanceof ConfigEffectiveStatementImpl) { - ConfigEffectiveStatementImpl config = (ConfigEffectiveStatementImpl) effectiveSubstatement; - this.configuration = config.argument(); + if (!configurationInit + && effectiveSubstatement instanceof ConfigEffectiveStatementImpl) { + ConfigEffectiveStatementImpl configStmt = (ConfigEffectiveStatementImpl) effectiveSubstatement; + this.configuration = configStmt.argument(); + configurationInit = true; } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveConstraintDefinitionImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveConstraintDefinitionImpl.java new file mode 100644 index 0000000000..25025841cd --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveConstraintDefinitionImpl.java @@ -0,0 +1,157 @@ +/** + * 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.effective; + +import com.google.common.collect.ImmutableSet; + +import java.util.Collection; +import java.util.Set; +import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition; +import org.opendaylight.yangtools.yang.model.api.MustDefinition; +import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; + +public class EffectiveConstraintDefinitionImpl implements ConstraintDefinition { + private final RevisionAwareXPath whenCondition; + private final Set mustConstraints; + private final Boolean mandatory; + private final Integer minElements; + private final Integer maxElements; + + public EffectiveConstraintDefinitionImpl(EffectiveStatementBase parent) { + + MandatoryEffectiveStatementImpl firstMandatoryStmt = parent + .firstEffective(MandatoryEffectiveStatementImpl.class); + this.mandatory = (firstMandatoryStmt == null) ? false + : firstMandatoryStmt.argument(); + + WhenEffectiveStatementImpl firstWhenStmt = parent + .firstEffective(WhenEffectiveStatementImpl.class); + this.whenCondition = (firstWhenStmt == null) ? null : firstWhenStmt + .argument(); + + MinElementsEffectiveStatementImpl firstMinElementsStmt = parent + .firstEffective(MinElementsEffectiveStatementImpl.class); + this.minElements = (firstMinElementsStmt == null) ? 0 + : firstMinElementsStmt.argument(); + + MaxElementsEffectiveStatementImpl firstMaxElementsStmt = parent + .firstEffective(MaxElementsEffectiveStatementImpl.class); + String maxElementsArg = (firstMaxElementsStmt == null) ? "unbounded" + : firstMaxElementsStmt.argument(); + if (maxElementsArg.equals("unbounded")) { + this.maxElements = Integer.MAX_VALUE; + } else { + this.maxElements = Integer.valueOf(maxElementsArg); + } + + Collection mustSubstatements = parent + .allSubstatementsOfType(MustDefinition.class); + this.mustConstraints = ImmutableSet.copyOf(mustSubstatements); + } + + @Override + public RevisionAwareXPath getWhenCondition() { + return whenCondition; + } + + @Override + public Set getMustConstraints() { + return mustConstraints; + } + + @Override + public boolean isMandatory() { + return mandatory; + } + + @Override + public Integer getMinElements() { + return minElements; + } + + @Override + public Integer getMaxElements() { + return maxElements; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((whenCondition == null) ? 0 : whenCondition.hashCode()); + result = prime * result + + ((mustConstraints == null) ? 0 : mustConstraints.hashCode()); + result = prime * result + + ((minElements == null) ? 0 : minElements.hashCode()); + result = prime * result + + ((maxElements == null) ? 0 : maxElements.hashCode()); + result = prime * result + mandatory.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; + } + EffectiveConstraintDefinitionImpl other = (EffectiveConstraintDefinitionImpl) obj; + if (whenCondition == null) { + if (other.whenCondition != null) { + return false; + } + } else if (!whenCondition.equals(other.whenCondition)) { + return false; + } + if (mustConstraints == null) { + if (other.mustConstraints != null) { + return false; + } + } else if (!mustConstraints.equals(other.mustConstraints)) { + return false; + } + if (!mandatory.equals(other.mandatory)) { + return false; + } + if (minElements == null) { + if (other.minElements != null) { + return false; + } + } else if (!minElements.equals(other.minElements)) { + return false; + } + if (maxElements == null) { + if (other.maxElements != null) { + return false; + } + } else if (!maxElements.equals(other.maxElements)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder( + EffectiveConstraintDefinitionImpl.class.getSimpleName()); + sb.append("["); + sb.append("whenCondition=").append(whenCondition); + sb.append(", mustConstraints=").append(mustConstraints); + sb.append(", mandatory=").append(mandatory); + sb.append(", minElements=").append(minElements); + sb.append(", maxElements=").append(maxElements); + sb.append("]"); + return sb.toString(); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveSchemaContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveSchemaContext.java index 4cedda12fa..ff89f81d14 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveSchemaContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveSchemaContext.java @@ -44,7 +44,7 @@ public class EffectiveSchemaContext extends AbstractEffectiveSchemaContext { Set modulesInit = new HashSet<>(); for (EffectiveStatement rootEffectiveStatement : rootEffectiveStatements) { - if (rootEffectiveStatement instanceof Module) { + if (rootEffectiveStatement instanceof ModuleEffectiveStatementImpl) { Module module = (Module) rootEffectiveStatement; modulesInit.add(module); } @@ -64,9 +64,7 @@ public class EffectiveSchemaContext extends AbstractEffectiveSchemaContext { namespaceToModules = ImmutableSetMultimap.copyOf(nsMap); nameToModules = ImmutableSetMultimap.copyOf(nameMap); - // :TODO - // this.identifiersToSources = - // ImmutableMap.copyOf(identifiersToSources); + // :TODO init identifiersToSources this.identifiersToSources = null; } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveStatementBase.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveStatementBase.java index fd269a1f16..b0a3429166 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveStatementBase.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveStatementBase.java @@ -7,26 +7,30 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import java.util.Collections; - -import java.util.NoSuchElementException; -import org.opendaylight.yangtools.yang.model.api.SchemaNode; -import com.google.common.collect.Collections2; import com.google.common.base.Predicates; -import com.google.common.collect.Iterables; -import java.util.LinkedList; -import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase; +import com.google.common.collect.Collections2; import com.google.common.collect.FluentIterable; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; import com.google.common.collect.ImmutableList; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; import java.util.Map; +import java.util.NoSuchElementException; + +import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; import org.opendaylight.yangtools.yang.model.api.meta.StatementSource; -import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +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.stmt.reactor.StatementContextBase; abstract public class EffectiveStatementBase> implements EffectiveStatement { @@ -52,10 +56,21 @@ abstract public class EffectiveStatementBase> .effectiveSubstatements(); Collection> substatementsInit = new LinkedList<>(); - substatementsInit.addAll(declaredSubstatements); + + for(StatementContextBase declaredSubstatement : declaredSubstatements) { + if(declaredSubstatement.getPublicDefinition() == Rfc6020Mapping.USES) { + substatementsInit.add(declaredSubstatement); + substatementsInit.addAll(declaredSubstatement.getEffectOfStatement()); + ((StatementContextBase)ctx).removeStatementsFromEffectiveSubstatements(declaredSubstatement + .getEffectOfStatement()); + } else { + substatementsInit.add(declaredSubstatement); + } + } + substatementsInit.addAll(effectiveSubstatements); - this.substatements = FluentIterable.from(substatementsInit) + this.substatements = FluentIterable.from(substatementsInit).filter(StmtContextUtils.IS_SUPPORTED_TO_BUILD_EFFECTIVE) .transform(StmtContextUtils.buildEffective()).toList(); } @@ -79,12 +94,9 @@ abstract public class EffectiveStatementBase> if (declaredInstance == null) { declaredInstance = stmtCtx.buildDeclared(); } - return declaredInstance; } - // public > V - // get( @Override public > V get( Class namespace, K identifier) { @@ -118,20 +130,6 @@ abstract public class EffectiveStatementBase> return result; } - @SuppressWarnings("unchecked") - protected final > Collection allEffective( - Class type) { - Collection result = null; - - try { - result = Collection.class.cast(Collections2.filter(substatements, - Predicates.instanceOf(type))); - } catch (NoSuchElementException e) { - result = Collections.emptyList(); - } - return result; - } - protected final S firstSchemaNode(Class type) { S result = null; try { @@ -144,9 +142,9 @@ abstract public class EffectiveStatementBase> } @SuppressWarnings("unchecked") - protected final Collection allSchemaNodes( - Class type) { - Collection result = null; + protected final Collection allSubstatementsOfType( + Class type) { + Collection result = null; try { result = Collection.class.cast(Collections2.filter(substatements, @@ -157,4 +155,14 @@ abstract public class EffectiveStatementBase> return result; } + protected final T firstSubstatementOfType(Class type) { + T result = null; + try { + result = type.cast(Iterables.find(substatements, + Predicates.instanceOf(type))); + } catch (NoSuchElementException e) { + result = null; + } + return result; + } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveStmtUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveStmtUtils.java new file mode 100644 index 0000000000..e3a14637fe --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveStmtUtils.java @@ -0,0 +1,27 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; + +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; + +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; + +public class EffectiveStmtUtils { + + private EffectiveStmtUtils(){ + throw new UnsupportedOperationException("Utility class"); + } + + public static final SourceException createNameCollisionSourceException( + final StmtContext ctx, + EffectiveStatement effectiveStatement) { + return new SourceException("Error in module '" + + ctx.getRoot().getStatementArgument() + + "': can not add '" + + effectiveStatement.argument() + + "'. Node name collision: '" + + effectiveStatement.argument() + + "' already declared.", + ctx.getStatementSourceReference()); + } + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ExtendedTypeEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ExtendedTypeEffectiveStatementImpl.java new file mode 100644 index 0000000000..bc379501a7 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ExtendedTypeEffectiveStatementImpl.java @@ -0,0 +1,325 @@ +/* + * 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.effective; + +import com.google.common.base.Optional; +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement; +import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; +import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; +import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition; +import org.opendaylight.yangtools.yang.model.util.ExtendedType; +import org.opendaylight.yangtools.yang.model.util.ExtendedType.Builder; +import org.opendaylight.yangtools.yang.parser.spi.TypeNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.LengthEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.PatternEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.RangeEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.TypeDefinitionEffectiveBuilder; +import org.opendaylight.yangtools.yang.parser.util.TypeConstraints; + +public class ExtendedTypeEffectiveStatementImpl extends EffectiveStatementBase implements + TypeDefinition>, TypeDefinitionEffectiveBuilder { + + private static final Splitter COLON_SPLITTER = Splitter.on(':').trimResults(); + + private final QName qName; + private final SchemaPath path; + + private final TypeDefinition baseType; + + private final String defaultValue = null; + private final String units = null; + + private final String description = null; + private final String reference = null; + + private final Status status = null; + + private final List ranges; + private final List lengths; + private final List patterns; + private final Integer fractionDigits; + + private ExtendedType extendedType = null; + private final boolean isExtended; + + public ExtendedTypeEffectiveStatementImpl( + StmtContext> ctx, boolean isExtended) { + super(ctx); + + this.isExtended = isExtended; + qName = initQName(ctx, isExtended); + + final StmtContext> typeStmt = ctx + .getFromNamespace(TypeNamespace.class, qName); + if (typeStmt == null) { + path = Utils.getSchemaPath(ctx); + } else { + path = Utils.getSchemaPath(ctx.getFromNamespace(TypeNamespace.class, qName)); + } + + ranges = initRanges(); + lengths = initLengths(); + patterns = initPatterns(); + fractionDigits = initFractionDigits(); + + baseType = parseBaseTypeFromCtx(ctx); + validateTypeConstraints(ctx); + } + + private QName initQName(final StmtContext> ctx, + final boolean isExtended) { + + QName qName; + + if (isExtended) { + final Splitter colonSplitter = Splitter.on(":").trimResults(); + final List nameTokens = colonSplitter.splitToList(ctx.getStatementArgument()); + + switch (nameTokens.size()) { + case 1: + qName = QName.create(Utils.getRootModuleQName(ctx), nameTokens.get(0)); + break; + case 2: + qName = QName.create(Utils.getRootModuleQName(ctx), nameTokens.get(1)); + break; + default: + throw new IllegalArgumentException(String.format( + "Bad colon separated parts number (%d) of QName '%s'.", nameTokens.size(), + ctx.getStatementArgument())); + } + } else { + qName = Utils.qNameFromArgument(ctx, ctx.getStatementArgument()); + } + return qName; + } + + private TypeDefinition parseBaseTypeFromCtx( + final StmtContext> ctx) { + + TypeDefinition baseType; + + final QName baseTypeQName = Utils.qNameFromArgument(ctx, ctx.getStatementArgument()); + if (TypeUtils.isYangBaseTypeString(baseTypeQName.getLocalName())) { + baseType = TypeUtils.getYangBaseTypeFromString(baseTypeQName.getLocalName()); + } else { + StmtContext> baseTypeCtx = ctx + .getParentContext().getFromNamespace(TypeNamespace.class, baseTypeQName); + + if (baseTypeCtx == null) { + throw new IllegalStateException(String.format("Type '%s' was not found in %s.", baseTypeQName, + ctx.getStatementSourceReference())); + } + + baseType = (TypeDefEffectiveStatementImpl) baseTypeCtx.buildEffective(); + } + + return baseType; + } + + private void validateTypeConstraints( + final StmtContext> ctx) { + + final List sourceParts = COLON_SPLITTER.splitToList(ctx.getStatementSourceReference().toString()); + TypeConstraints typeConstraints = new TypeConstraints(sourceParts.get(0), Integer.parseInt(sourceParts.get(1))); + + typeConstraints.addRanges(ranges); + typeConstraints.addLengths(lengths); + typeConstraints.addPatterns(patterns); + typeConstraints.addFractionDigits(fractionDigits); + + typeConstraints = addConstraintsFromBaseType(typeConstraints, baseType); + typeConstraints.validateConstraints(); + } + + private TypeConstraints addConstraintsFromBaseType(final TypeConstraints typeConstraints, + final TypeDefinition baseType) { + + final String baseTypeName = baseType.getQName().getLocalName(); + + if (baseType instanceof IntegerTypeDefinition) { + final IntegerTypeDefinition intType = (IntegerTypeDefinition) TypeUtils + .getYangBaseTypeFromString(baseTypeName); + typeConstraints.addRanges(intType.getRangeConstraints()); + } else if (baseType instanceof UnsignedIntegerTypeDefinition) { + final UnsignedIntegerTypeDefinition uintType = (UnsignedIntegerTypeDefinition) TypeUtils + .getYangBaseTypeFromString(baseTypeName); + typeConstraints.addRanges(uintType.getRangeConstraints()); + } else if (baseType instanceof StringTypeDefinition) { + final StringTypeDefinition stringType = (StringTypeDefinition) TypeUtils + .getYangBaseTypeFromString(baseTypeName); + typeConstraints.addLengths(stringType.getLengthConstraints()); + typeConstraints.addPatterns(stringType.getPatternConstraints()); + } else if (baseType instanceof DecimalTypeDefinition) { + final DecimalTypeDefinition decimalType = (DecimalTypeDefinition) TypeUtils + .getYangBaseTypeFromString(baseTypeName); + typeConstraints.addRanges(decimalType.getRangeConstraints()); + typeConstraints.addFractionDigits(decimalType.getFractionDigits()); + } else if (baseType instanceof BinaryTypeDefinition) { + final BinaryTypeDefinition binaryType = (BinaryTypeDefinition) TypeUtils + .getYangBaseTypeFromString(baseTypeName); + typeConstraints.addLengths(binaryType.getLengthConstraints()); + } else if (baseType instanceof TypeDefEffectiveStatementImpl) { + typeConstraints.addRanges(((TypeDefEffectiveStatementImpl) baseType).getRangeConstraints()); + typeConstraints.addLengths(((TypeDefEffectiveStatementImpl) baseType).getLengthConstraints()); + typeConstraints.addPatterns(((TypeDefEffectiveStatementImpl) baseType).getPatternConstraints()); + typeConstraints.addFractionDigits(((TypeDefEffectiveStatementImpl) baseType).getFractionDigits()); + } else if (baseType instanceof ExtendedTypeEffectiveStatementImpl) { + typeConstraints.addRanges(((ExtendedTypeEffectiveStatementImpl) baseType).getRangeConstraints()); + typeConstraints.addLengths(((ExtendedTypeEffectiveStatementImpl) baseType).getLengthConstraints()); + typeConstraints.addPatterns(((ExtendedTypeEffectiveStatementImpl) baseType).getPatternConstraints()); + typeConstraints.addFractionDigits(((ExtendedTypeEffectiveStatementImpl) baseType).getFractionDigits()); + } + + return typeConstraints; + } + + protected Integer initFractionDigits() { + final FractionDigitsEffectiveStatementImpl fractionDigitsEffStmt = firstEffective(FractionDigitsEffectiveStatementImpl.class); + return fractionDigitsEffStmt != null ? fractionDigitsEffStmt.argument() : null; + } + + protected List initRanges() { + final RangeEffectiveStatementImpl rangeConstraints = firstEffective(RangeEffectiveStatementImpl.class); + return rangeConstraints != null ? rangeConstraints.argument() : Collections. emptyList(); + } + + protected List initLengths() { + final LengthEffectiveStatementImpl lengthConstraints = firstEffective(LengthEffectiveStatementImpl.class); + return lengthConstraints != null ? lengthConstraints.argument() : Collections. emptyList(); + } + + protected List initPatterns() { + final List patternConstraints = new ArrayList<>(); + + for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { + if (effectiveStatement instanceof PatternEffectiveStatementImpl) { + final PatternConstraint pattern = ((PatternEffectiveStatementImpl) effectiveStatement).argument(); + + if (pattern != null) { + patternConstraints.add(pattern); + } + } + } + + return !patternConstraints.isEmpty() ? ImmutableList.copyOf(patternConstraints) : Collections + . emptyList(); + } + + @Override + public TypeDefinition getBaseType() { + return baseType; + } + + @Override + public String getUnits() { + return units; + } + + @Override + public Object getDefaultValue() { + return defaultValue; + } + + @Override + public QName getQName() { + return qName; + } + + @Override + public SchemaPath getPath() { + return path; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getReference() { + return reference; + } + + @Override + public Status getStatus() { + return status; + } + + public List getRangeConstraints() { + return ranges; + } + + public List getLengthConstraints() { + return lengths; + } + + public List getPatternConstraints() { + return patterns; + } + + public Integer getFractionDigits() { + return fractionDigits; + } + + @Override + public ExtendedType buildType() { + + if (extendedType != null) { + return extendedType; + } + + if (!isExtended && baseType instanceof TypeDefEffectiveStatementImpl) { + TypeDefEffectiveStatementImpl originalTypeDef = (TypeDefEffectiveStatementImpl) baseType; + return originalTypeDef.buildType(); + } + + Builder extendedTypeBuilder; + if (baseType instanceof TypeDefEffectiveStatementImpl) { + TypeDefEffectiveStatementImpl typeDefBaseType = (TypeDefEffectiveStatementImpl) baseType; + extendedTypeBuilder = ExtendedType.builder(qName, typeDefBaseType.buildType(), + Optional.fromNullable(description), Optional.fromNullable(reference), path); + } else { + extendedTypeBuilder = ExtendedType.builder(qName, baseType, Optional.fromNullable(description), + Optional.fromNullable(reference), path); + } + + extendedTypeBuilder.fractionDigits(fractionDigits); + extendedTypeBuilder.ranges(ranges); + extendedTypeBuilder.lengths(lengths); + extendedTypeBuilder.patterns(patterns); + + extendedType = extendedTypeBuilder.build(); + + return extendedType; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ExtensionEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ExtensionEffectiveStatementImpl.java index f9f1d80665..81e9f7bebf 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ExtensionEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ExtensionEffectiveStatementImpl.java @@ -48,16 +48,15 @@ public class ExtensionEffectiveStatementImpl extends if (argumentSubstatement != null) { this.argument = argumentSubstatement.argument().getLocalName(); - } - - YinElementEffectiveStatementImpl yinElement = firstEffective(YinElementEffectiveStatementImpl.class); - if (yinElement != null) { - this.yin = yinElement.argument(); - } else { - this.yin = false; + YinElementEffectiveStatementImpl yinElement = argumentSubstatement + .firstEffective(YinElementEffectiveStatementImpl.class); + if (yinElement != null) { + this.yin = yinElement.argument(); + } else { + this.yin = false; + } } - } private void initSubstatementCollections() { diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/FeatureEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/FeatureEffectiveStatementImpl.java index a71635b8cb..8663a1bd98 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/FeatureEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/FeatureEffectiveStatementImpl.java @@ -7,17 +7,135 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; +import java.util.LinkedList; +import java.util.List; + import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.FeatureDefinition; +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.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.FeatureStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; + +import com.google.common.collect.ImmutableList; -public class FeatureEffectiveStatementImpl extends - EffectiveStatementBase { +public class FeatureEffectiveStatementImpl extends EffectiveStatementBase implements + FeatureDefinition { - public FeatureEffectiveStatementImpl( - StmtContext ctx) { + private QName qName; + private SchemaPath path; + private List unknownSchemaNodes; + private String description; + private String reference; + private Status status; + + public FeatureEffectiveStatementImpl(StmtContext ctx) { super(ctx); + this.qName = ctx.getStatementArgument(); + this.path = Utils.getSchemaPath(ctx); + + initFields(); + } + + private void initFields() { + + List unknownNodesInit = new LinkedList<>(); + + for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { + if (effectiveStatement instanceof DescriptionEffectiveStatementImpl) { + description = ((DescriptionEffectiveStatementImpl) effectiveStatement).argument(); + } + if (effectiveStatement instanceof ReferenceEffectiveStatementImpl) { + reference = ((ReferenceEffectiveStatementImpl) effectiveStatement).argument(); + } + if (effectiveStatement instanceof StatusEffectiveStatementImpl) { + status = ((StatusEffectiveStatementImpl) effectiveStatement).argument(); + } + + if (effectiveStatement instanceof UnknownSchemaNode) { + unknownNodesInit.add((UnknownSchemaNode) effectiveStatement); + } + } + + this.unknownSchemaNodes = ImmutableList.copyOf(unknownNodesInit); + } + + @Override + public QName getQName() { + return qName; + } + + @Override + public SchemaPath getPath() { + return path; } + @Override + public List getUnknownSchemaNodes() { + return unknownSchemaNodes; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getReference() { + return reference; + } + + @Override + public Status getStatus() { + return status; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((qName == null) ? 0 : qName.hashCode()); + result = prime * result + ((path == null) ? 0 : path.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; + } + FeatureEffectiveStatementImpl other = (FeatureEffectiveStatementImpl) obj; + if (qName == null) { + if (other.qName != null) { + return false; + } + } else if (!qName.equals(other.qName)) { + return false; + } + if (path == null) { + if (other.path != null) { + return false; + } + } else if (!path.equals(other.path)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(FeatureEffectiveStatementImpl.class.getSimpleName()); + sb.append("[name=").append(qName).append("]"); + return sb.toString(); + } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/FractionDigitsEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/FractionDigitsEffectiveStatementImpl.java index 5f33bef200..910952dcbf 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/FractionDigitsEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/FractionDigitsEffectiveStatementImpl.java @@ -11,10 +11,10 @@ import org.opendaylight.yangtools.yang.model.api.stmt.FractionDigitsStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; public class FractionDigitsEffectiveStatementImpl extends - EffectiveStatementBase { + EffectiveStatementBase { public FractionDigitsEffectiveStatementImpl( - StmtContext ctx) { + StmtContext ctx) { super(ctx); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/GroupingEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/GroupingEffectiveStatementImpl.java index ea01448a56..636ef1e740 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/GroupingEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/GroupingEffectiveStatementImpl.java @@ -1,21 +1,23 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; +import java.util.Set; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; import java.util.Collection; import java.util.LinkedList; -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.stmt.GroupingStatement; import java.util.List; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; 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.GroupingStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; public class GroupingEffectiveStatementImpl extends - AbstractEffectiveDocumentedDataNodeContainer - implements GroupingDefinition { + AbstractEffectiveDocumentedDataNodeContainer implements GroupingDefinition { private final QName qname; private final SchemaPath path; @@ -28,15 +30,25 @@ public class GroupingEffectiveStatementImpl extends qname = ctx.getStatementArgument(); path = Utils.getSchemaPath(ctx); - // :TODO init other fields + initCopyType(ctx); initSubstatementCollections(); } + private void initCopyType( + StmtContext> ctx) { + + Set copyTypesFromOriginal = StmtContextUtils.getCopyTypesFromOriginal(ctx); + + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) { + addedByUses = true; + } + } + private void initSubstatementCollections() { Collection> effectiveSubstatements = effectiveSubstatements(); - unknownNodes = new LinkedList(); + unknownNodes = new LinkedList<>(); for (EffectiveStatement effectiveStatement : effectiveSubstatements) { if (effectiveStatement instanceof UnknownSchemaNode) { @@ -107,8 +119,7 @@ public class GroupingEffectiveStatementImpl extends @Override public String toString() { - StringBuilder sb = new StringBuilder( - GroupingEffectiveStatementImpl.class.getSimpleName()); + StringBuilder sb = new StringBuilder(GroupingEffectiveStatementImpl.class.getSimpleName()); sb.append("["); sb.append("qname=").append(qname); sb.append("]"); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/IdentityEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/IdentityEffectiveStatementImpl.java index 8ee820a7ba..7562c76096 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/IdentityEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/IdentityEffectiveStatementImpl.java @@ -7,9 +7,12 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; +import org.opendaylight.yangtools.yang.parser.spi.meta.DerivedIdentitiesNamespace; + +import java.util.HashSet; +import com.google.common.collect.ImmutableSet; 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.model.api.stmt.IdentityStatement; @@ -29,7 +32,7 @@ public class IdentityEffectiveStatementImpl extends private final QName qname; private final SchemaPath path; IdentitySchemaNode baseIdentity; - private final Set derivedIdentities; + private ImmutableSet derivedIdentities; ImmutableList unknownNodes; @@ -41,9 +44,32 @@ public class IdentityEffectiveStatementImpl extends this.path = Utils.getSchemaPath(ctx); initSubstatementCollections(); + initDerivedIdentities(ctx); + } + + private void initDerivedIdentities( + StmtContext> ctx) { + + Set derivedIdentitiesInit = new HashSet(); + List> derivedIdentitiesCtxList = ctx.getFromNamespace( + DerivedIdentitiesNamespace.class, ctx.getStatementArgument()); + + if(derivedIdentitiesCtxList == null) { + this.derivedIdentities = ImmutableSet.of(); + return; + } + + for (StmtContext derivedIdentityCtx : derivedIdentitiesCtxList) { + IdentityEffectiveStatementImpl derivedIdentity = (IdentityEffectiveStatementImpl) derivedIdentityCtx + .buildEffective(); + derivedIdentity.initBaseIdentity(this); + derivedIdentitiesInit.add(derivedIdentity); + } + this.derivedIdentities = ImmutableSet.copyOf(derivedIdentitiesInit); + } - // :TODO init other fields - this.derivedIdentities = null; + private void initBaseIdentity(IdentityEffectiveStatementImpl baseIdentity) { + this.baseIdentity = baseIdentity; } private void initSubstatementCollections() { diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ImportEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ImportEffectiveStatementImpl.java index d322c22a7d..7eb4e6c03b 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ImportEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ImportEffectiveStatementImpl.java @@ -7,8 +7,9 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import java.util.Date; +import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; +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; @@ -25,10 +26,11 @@ public class ImportEffectiveStatementImpl extends EffectiveStatementBase effectiveStatement : effectiveSubstatements()) { - if (effectiveStatement instanceof RevisionEffectiveStatementImpl) { - revision = ((RevisionEffectiveStatementImpl) effectiveStatement).argument(); + if (effectiveStatement instanceof RevisionDateEffectiveStatementImpl) { + revision = ((RevisionDateEffectiveStatementImpl) effectiveStatement).argument(); } if (effectiveStatement instanceof PrefixEffectiveStatementImpl) { prefix = ((PrefixEffectiveStatementImpl) effectiveStatement).argument(); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/InputEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/InputEffectiveStatementImpl.java index 03f1daf928..293f0ebd56 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/InputEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/InputEffectiveStatementImpl.java @@ -7,8 +7,9 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; +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; @@ -37,7 +38,7 @@ public class InputEffectiveStatementImpl extends boolean augmenting; boolean addedByUses; - boolean configuration; + boolean configuration = true; ContainerSchemaNode original; ConstraintDefinition constraints; @@ -52,38 +53,39 @@ public class InputEffectiveStatementImpl extends path = Utils.getSchemaPath(ctx); presence = (firstEffective(PresenceEffectiveStatementImpl.class) == null) ? false : true; - // :TODO init other fields + this.constraints = new EffectiveConstraintDefinitionImpl(this); - initSubstatementCollections(); + initSubstatementCollectionsAndFields(); initCopyType(ctx); } private void initCopyType( StmtContext> ctx) { - TypeOfCopy typeOfCopy = ctx.getTypeOfCopy(); - switch (typeOfCopy) { - case ADDED_BY_AUGMENTATION: + Set copyTypesFromOriginal = StmtContextUtils.getCopyTypesFromOriginal(ctx); + + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION)) { augmenting = true; - original = (ContainerSchemaNode) ctx.getOriginalCtx() - .buildEffective(); - break; - case ADDED_BY_USES: + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) { addedByUses = true; - original = (ContainerSchemaNode) ctx.getOriginalCtx() - .buildEffective(); - break; - default: - break; + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) { + addedByUses = augmenting = true; + } + + if (ctx.getTypeOfCopy() != TypeOfCopy.ORIGINAL) { + original = (ContainerSchemaNode) ctx.getOriginalCtx().buildEffective(); } } - private void initSubstatementCollections() { + private void initSubstatementCollectionsAndFields() { Collection> effectiveSubstatements = effectiveSubstatements(); List unknownNodesInit = new LinkedList<>(); Set augmentationsInit = new HashSet<>(); + boolean configurationInit = false; for (EffectiveStatement effectiveStatement : effectiveSubstatements) { if (effectiveStatement instanceof UnknownSchemaNode) { UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement; @@ -93,6 +95,12 @@ public class InputEffectiveStatementImpl extends AugmentationSchema augmentationSchema = (AugmentationSchema) effectiveStatement; augmentationsInit.add(augmentationSchema); } + if (!configurationInit + && effectiveStatement instanceof ConfigEffectiveStatementImpl) { + ConfigEffectiveStatementImpl configStmt = (ConfigEffectiveStatementImpl) effectiveStatement; + this.configuration = configStmt.argument(); + configurationInit = true; + } } this.unknownNodes = ImmutableList.copyOf(unknownNodesInit); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LeafEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LeafEffectiveStatementImpl.java index 37980b5575..0676661c2f 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LeafEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LeafEffectiveStatementImpl.java @@ -7,16 +7,14 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import java.util.Set; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; -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; -import org.opendaylight.yangtools.yang.model.api.stmt.LeafStatement; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; +import java.util.Collection; +import java.util.LinkedList; import java.util.List; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition; @@ -25,62 +23,88 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.LeafStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; -public class LeafEffectiveStatementImpl extends - AbstractEffectiveDocumentedNode implements +public class LeafEffectiveStatementImpl extends AbstractEffectiveDocumentedNode implements LeafSchemaNode, DerivableSchemaNode { private final QName qname; private final SchemaPath path; - boolean augmenting; - boolean addedByUses; - LeafSchemaNode original; - boolean configuration; - ConstraintDefinition constraintsDef; - TypeDefinition type; - String defaultStr; - String unitsStr; + private boolean augmenting; + private boolean addedByUses; + private LeafSchemaNode original; + private boolean configuration = true; + private ConstraintDefinition constraintsDef; + private TypeDefinition type; + private String defaultStr; + private String unitsStr; private ImmutableList unknownNodes; - public LeafEffectiveStatementImpl( - StmtContext> ctx) { + public LeafEffectiveStatementImpl(StmtContext> ctx) { super(ctx); this.qname = ctx.getStatementArgument(); this.path = Utils.getSchemaPath(ctx); - // :TODO init other fields + this.constraintsDef = new EffectiveConstraintDefinitionImpl(this); - initSubstatementCollections(); + initSubstatementCollections(ctx); initCopyType(ctx); } private void initCopyType( StmtContext> ctx) { - TypeOfCopy typeOfCopy = ctx.getTypeOfCopy(); - switch (typeOfCopy) { - case ADDED_BY_AUGMENTATION: + Set copyTypesFromOriginal = StmtContextUtils.getCopyTypesFromOriginal(ctx); + + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION)) { augmenting = true; - original = (LeafSchemaNode) ctx.getOriginalCtx().buildEffective(); - break; - case ADDED_BY_USES: + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) { addedByUses = true; + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) { + addedByUses = augmenting = true; + } + + if (ctx.getTypeOfCopy() != TypeOfCopy.ORIGINAL) { original = (LeafSchemaNode) ctx.getOriginalCtx().buildEffective(); - break; - default: - break; } } - private void initSubstatementCollections() { + private void initSubstatementCollections( + final StmtContext> ctx) { Collection> effectiveSubstatements = effectiveSubstatements(); List unknownNodesInit = new LinkedList<>(); + boolean configurationInit = false; + boolean defaultInit = false; + boolean unitsInit = false; for (EffectiveStatement effectiveStatement : effectiveSubstatements) { if (effectiveStatement instanceof UnknownSchemaNode) { - UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement; - unknownNodesInit.add(unknownNode); + unknownNodesInit.add((UnknownSchemaNode) effectiveStatement); + } + if (effectiveStatement instanceof TypeDefinition) { + type = TypeUtils.getTypeFromEffectiveStatement(effectiveStatement); + } + if (!configurationInit && effectiveStatement instanceof ConfigEffectiveStatementImpl) { + ConfigEffectiveStatementImpl configStmt = (ConfigEffectiveStatementImpl) effectiveStatement; + this.configuration = configStmt.argument(); + configurationInit = true; + } + if (!defaultInit && effectiveStatement instanceof DefaultEffectiveStatementImpl) { + DefaultEffectiveStatementImpl defStmt = (DefaultEffectiveStatementImpl) effectiveStatement; + this.defaultStr = defStmt.argument(); + defaultInit = true; + } + if (!unitsInit && effectiveStatement instanceof UnitsEffectiveStatementImpl) { + UnitsEffectiveStatementImpl unitStmt = (UnitsEffectiveStatementImpl) effectiveStatement; + this.unitsStr = unitStmt.argument(); + unitsInit = true; } } @@ -182,8 +206,7 @@ public class LeafEffectiveStatementImpl extends @Override public String toString() { - StringBuilder sb = new StringBuilder( - LeafEffectiveStatementImpl.class.getSimpleName()); + StringBuilder sb = new StringBuilder(LeafEffectiveStatementImpl.class.getSimpleName()); sb.append("["); sb.append("qname=").append(qname); sb.append(", path=").append(path); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LeafListEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LeafListEffectiveStatementImpl.java index afb24b4d33..8840670ea3 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LeafListEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LeafListEffectiveStatementImpl.java @@ -7,16 +7,14 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import java.util.Set; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; -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; -import org.opendaylight.yangtools.yang.model.api.stmt.LeafListStatement; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; +import java.util.Collection; +import java.util.LinkedList; import java.util.List; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition; @@ -25,20 +23,24 @@ import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.LeafListStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; -public class LeafListEffectiveStatementImpl extends - AbstractEffectiveDocumentedNode implements +public class LeafListEffectiveStatementImpl extends AbstractEffectiveDocumentedNode implements LeafListSchemaNode, DerivableSchemaNode { private final QName qname; private final SchemaPath path; - boolean augmenting; - boolean addedByUses; - LeafListSchemaNode original; - boolean configuration; - ConstraintDefinition constraintsDef; - TypeDefinition type; - boolean userOrdered; + private boolean augmenting; + private boolean addedByUses; + private LeafListSchemaNode original; + private boolean configuration = true; + private ConstraintDefinition constraintsDef; + private TypeDefinition type; + private boolean userOrdered; private ImmutableList unknownNodes; @@ -47,7 +49,9 @@ public class LeafListEffectiveStatementImpl extends super(ctx); this.qname = ctx.getStatementArgument(); this.path = Utils.getSchemaPath(ctx); - // :TODO init other fields + this.constraintsDef = new EffectiveConstraintDefinitionImpl(this); + + // :TODO init TypeDefinition initSubstatementCollections(); initCopyType(ctx); @@ -56,32 +60,45 @@ public class LeafListEffectiveStatementImpl extends private void initCopyType( StmtContext> ctx) { - TypeOfCopy typeOfCopy = ctx.getTypeOfCopy(); - switch (typeOfCopy) { - case ADDED_BY_AUGMENTATION: + Set copyTypesFromOriginal = StmtContextUtils.getCopyTypesFromOriginal(ctx); + + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION)) { augmenting = true; - original = (LeafListSchemaNode) ctx.getOriginalCtx() - .buildEffective(); - break; - case ADDED_BY_USES: + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) { addedByUses = true; - original = (LeafListSchemaNode) ctx.getOriginalCtx() - .buildEffective(); - break; - default: - break; } - } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) { + addedByUses = augmenting = true; + } + if (ctx.getTypeOfCopy() != TypeOfCopy.ORIGINAL) { + original = (LeafListSchemaNode) ctx.getOriginalCtx().buildEffective(); + } + } private void initSubstatementCollections() { Collection> effectiveSubstatements = effectiveSubstatements(); List unknownNodesInit = new LinkedList<>(); + boolean configurationInit = false; + boolean userOrderedInit = false; for (EffectiveStatement effectiveStatement : effectiveSubstatements) { if (effectiveStatement instanceof UnknownSchemaNode) { - UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement; - unknownNodesInit.add(unknownNode); + unknownNodesInit.add((UnknownSchemaNode) effectiveStatement); + } + if (effectiveStatement instanceof TypeDefinition) { + type = TypeUtils.getTypeFromEffectiveStatement(effectiveStatement); + } + if (!configurationInit && effectiveStatement instanceof ConfigEffectiveStatementImpl) { + ConfigEffectiveStatementImpl configStmt = (ConfigEffectiveStatementImpl) effectiveStatement; + this.configuration = configStmt.argument(); + configurationInit = true; + } + if (!userOrderedInit && effectiveStatement instanceof OrderedByEffectiveStatementImpl) { + OrderedByEffectiveStatementImpl orderedByStmt = (OrderedByEffectiveStatementImpl) effectiveStatement; + this.userOrdered = orderedByStmt.argument().equals("user") ? true : false; + userOrderedInit = true; } } @@ -178,8 +195,7 @@ public class LeafListEffectiveStatementImpl extends @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("]"); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ListEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ListEffectiveStatementImpl.java index 4e205bde1a..d1e2484134 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ListEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ListEffectiveStatementImpl.java @@ -1,18 +1,14 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; -import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; -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.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.model.api.stmt.ListStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Set; import org.opendaylight.yangtools.yang.common.QName; @@ -22,9 +18,14 @@ import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; 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.ListStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; -public class ListEffectiveStatementImpl extends - AbstractEffectiveDocumentedDataNodeContainer +public class ListEffectiveStatementImpl extends AbstractEffectiveDocumentedDataNodeContainer implements ListSchemaNode, DerivableSchemaNode { private final QName qname; private final SchemaPath path; @@ -32,7 +33,7 @@ public class ListEffectiveStatementImpl extends boolean augmenting; boolean addedByUses; ListSchemaNode original; - boolean configuration; + boolean configuration = true; ConstraintDefinition constraints; boolean userOrdered; @@ -40,59 +41,77 @@ public class ListEffectiveStatementImpl extends ImmutableSet augmentations; ImmutableList unknownNodes; - public ListEffectiveStatementImpl( - StmtContext> ctx) { + public ListEffectiveStatementImpl(StmtContext> ctx) { super(ctx); this.qname = ctx.getStatementArgument(); this.path = Utils.getSchemaPath(ctx); - // :TODO init other fields + this.constraints = new EffectiveConstraintDefinitionImpl(this); - initKeyDefinition(); - initSubstatementCollections(); + initSubstatementCollectionsAndFields(); initCopyType(ctx); + + // should be after initSubstatementCollectionsAndFields() + initKeyDefinition(ctx); } private void initCopyType( StmtContext> ctx) { - TypeOfCopy typeOfCopy = ctx.getTypeOfCopy(); - switch (typeOfCopy) { - case ADDED_BY_AUGMENTATION: + Set copyTypesFromOriginal = StmtContextUtils.getCopyTypesFromOriginal(ctx); + + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION)) { augmenting = true; - original = (ListSchemaNode) ctx.getOriginalCtx().buildEffective(); - break; - case ADDED_BY_USES: + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) { addedByUses = true; + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) { + addedByUses = augmenting = true; + } + + if (ctx.getTypeOfCopy() != TypeOfCopy.ORIGINAL) { original = (ListSchemaNode) ctx.getOriginalCtx().buildEffective(); - break; - default: - break; } } - /** - * - */ - private void initKeyDefinition() { - List keyDefinitionInit = new LinkedList(); - KeyEffectiveStatementImpl key = firstEffective(KeyEffectiveStatementImpl.class); + private void initKeyDefinition(StmtContext> ctx) { + List keyDefinitionInit = new LinkedList<>(); + KeyEffectiveStatementImpl keyEffectiveSubstatement = firstEffective(KeyEffectiveStatementImpl.class); + + if (keyEffectiveSubstatement != null) { + Set possibleLeafQNamesForKey = new HashSet<>(); + + for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { + if (effectiveStatement instanceof LeafSchemaNode) { + possibleLeafQNamesForKey.add(((LeafSchemaNode) effectiveStatement).getQName()); + } + } + + Collection keys = keyEffectiveSubstatement.argument(); + for (SchemaNodeIdentifier key : keys) { + final QName keyQName = key.getLastComponent(); + + if (!possibleLeafQNamesForKey.contains(keyQName)) { + throw new IllegalArgumentException(String.format("Key '%s' misses node '%s' in list '%s', file %s", + keyEffectiveSubstatement.getDeclared().rawArgument(), keyQName.getLocalName(), ctx.getStatementArgument(), + ctx.getStatementSourceReference())); + } - if (key != null) { - Collection keyParts = key.argument(); - for (SchemaNodeIdentifier keyPart : keyParts) { - keyDefinitionInit.add(keyPart.getLastComponent()); + keyDefinitionInit.add(keyQName); } } this.keyDefinition = ImmutableList.copyOf(keyDefinitionInit); } - private void initSubstatementCollections() { + private void initSubstatementCollectionsAndFields() { Collection> effectiveSubstatements = effectiveSubstatements(); - List unknownNodesInit = new LinkedList(); - Set augmentationsInit = new HashSet(); + List unknownNodesInit = new LinkedList<>(); + Set augmentationsInit = new HashSet<>(); + boolean configurationInit = false; + boolean userOrderedInit = false; for (EffectiveStatement effectiveStatement : effectiveSubstatements) { if (effectiveStatement instanceof UnknownSchemaNode) { UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement; @@ -102,6 +121,16 @@ public class ListEffectiveStatementImpl extends AugmentationSchema augmentationSchema = (AugmentationSchema) effectiveStatement; augmentationsInit.add(augmentationSchema); } + if (!configurationInit && effectiveStatement instanceof ConfigEffectiveStatementImpl) { + ConfigEffectiveStatementImpl configStmt = (ConfigEffectiveStatementImpl) effectiveStatement; + this.configuration = configStmt.argument(); + configurationInit = true; + } + if (!userOrderedInit && effectiveStatement instanceof OrderedByEffectiveStatementImpl) { + OrderedByEffectiveStatementImpl orderedByStmt = (OrderedByEffectiveStatementImpl) effectiveStatement; + this.userOrdered = orderedByStmt.argument().equals("user") ? true : false; + userOrderedInit = true; + } } this.unknownNodes = ImmutableList.copyOf(unknownNodesInit); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/MinElementsEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/MinElementsEffectiveStatementImpl.java index e80e26c6db..15819a4326 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/MinElementsEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/MinElementsEffectiveStatementImpl.java @@ -11,10 +11,10 @@ import org.opendaylight.yangtools.yang.model.api.stmt.MinElementsStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; public class MinElementsEffectiveStatementImpl extends - EffectiveStatementBase { + EffectiveStatementBase { public MinElementsEffectiveStatementImpl( - StmtContext ctx) { + StmtContext ctx) { super(ctx); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ModuleEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ModuleEffectiveStatementImpl.java index 9fdeae77a4..db3f31110a 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ModuleEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ModuleEffectiveStatementImpl.java @@ -7,8 +7,27 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; +import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName; + +import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import org.opendaylight.yangtools.yang.model.util.ExtendedType; +import java.util.LinkedHashSet; +import java.util.LinkedHashMap; +import com.google.common.collect.ImmutableMap; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UsesNode; +import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; +import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable; +import org.opendaylight.yangtools.yang.parser.spi.SubmoduleNamespace; +import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; +import java.util.Map; +import org.opendaylight.yangtools.yang.parser.spi.source.IncludedSubmoduleNameToIdentifier; import java.net.URI; import java.util.Collection; import java.util.Date; @@ -29,17 +48,15 @@ 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.ModuleStatement; -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; -public class ModuleEffectiveStatementImpl extends AbstractEffectiveDocumentedDataNodeContainer +public class ModuleEffectiveStatementImpl extends + AbstractEffectiveDocumentedNode implements Module, Immutable { private final QNameModule qNameModule; private final String name; - private String sourcePath; + private String sourcePath; // TODO fill private String prefix; private String yangVersion; private String organization; @@ -54,43 +71,91 @@ public class ModuleEffectiveStatementImpl extends AbstractEffectiveDocumentedDat private ImmutableList extensionNodes; private ImmutableSet identities; private ImmutableList unknownNodes; - private final String source; + private String source; + private ImmutableList> substatementsOfSubmodules; - public ModuleEffectiveStatementImpl(final StmtContext ctx) { + private ImmutableMap childNodes; + private ImmutableSet groupings; + private ImmutableSet uses; + private ImmutableSet> typeDefinitions; + private ImmutableSet publicChildNodes; + + public ModuleEffectiveStatementImpl( + StmtContext> ctx) { super(ctx); name = argument(); - qNameModule = ctx.getFromNamespace(ModuleNameToModuleQName.class, name); + QNameModule qNameModuleInit = ctx.getFromNamespace( + ModuleCtxToModuleQName.class, ctx); + qNameModule = qNameModuleInit.getRevision() == null ? QNameModule + .create(qNameModuleInit.getNamespace(), + SimpleDateFormatUtil.DEFAULT_DATE_REV) + : qNameModuleInit; for (EffectiveStatement effectiveStatement : effectiveSubstatements()) { if (effectiveStatement instanceof PrefixEffectiveStatementImpl) { - prefix = ((PrefixEffectiveStatementImpl) effectiveStatement).argument(); + prefix = ((PrefixEffectiveStatementImpl) effectiveStatement) + .argument(); } if (effectiveStatement instanceof YangVersionEffectiveStatementImpl) { - yangVersion = ((YangVersionEffectiveStatementImpl) effectiveStatement).argument(); + yangVersion = ((YangVersionEffectiveStatementImpl) effectiveStatement) + .argument(); } if (effectiveStatement instanceof OrganizationEffectiveStatementImpl) { - organization = ((OrganizationEffectiveStatementImpl) effectiveStatement).argument(); + organization = ((OrganizationEffectiveStatementImpl) effectiveStatement) + .argument(); } if (effectiveStatement instanceof ContactEffectiveStatementImpl) { - contact = ((ContactEffectiveStatementImpl) effectiveStatement).argument(); + contact = ((ContactEffectiveStatementImpl) effectiveStatement) + .argument(); } } + // TODO init source, sourcePath source = ctx.getStatementSource().name(); - //ctx.getFromNamespace(IncludedModuleContext.class, ) //ModuleIdentifier + initSubmodules(ctx); + initSubstatementCollections(ctx); + } + + private void initSubmodules( + StmtContext> ctx) { + Map includedSubmodulesMap = ctx + .getAllFromCurrentStmtCtxNamespace(IncludedSubmoduleNameToIdentifier.class); + + if (includedSubmodulesMap == null || includedSubmodulesMap.isEmpty()) { + this.submodules = ImmutableSet.of(); + this.substatementsOfSubmodules = ImmutableList.of(); + return; + } + + Collection includedSubmodules = includedSubmodulesMap + .values(); + + Set submodulesInit = new HashSet<>(); + List> substatementsOfSubmodulesInit = new LinkedList<>(); + for (ModuleIdentifier submoduleIdentifier : includedSubmodules) { + Mutable> submoduleCtx = (Mutable>) ctx + .getFromNamespace(SubmoduleNamespace.class, + submoduleIdentifier); + SubmoduleEffectiveStatementImpl submodule = (SubmoduleEffectiveStatementImpl) submoduleCtx.buildEffective(); + submodulesInit.add(submodule); + substatementsOfSubmodulesInit.addAll(submodule.effectiveSubstatements()); + } - initSubstatementCollections(); + this.submodules = ImmutableSet.copyOf(submodulesInit); + this.substatementsOfSubmodules = ImmutableList.copyOf(substatementsOfSubmodulesInit); } - private void initSubstatementCollections() { - Collection> effectiveSubstatements = effectiveSubstatements(); + private void initSubstatementCollections(StmtContext> ctx) { + List> effectiveSubstatements = new LinkedList<>(); + + effectiveSubstatements.addAll(effectiveSubstatements()); + effectiveSubstatements.addAll(substatementsOfSubmodules); List unknownNodesInit = new LinkedList<>(); Set augmentationsInit = new HashSet<>(); Set importsInit = new HashSet<>(); - Set submodulesInit = new HashSet<>(); Set notificationsInit = new HashSet<>(); Set rpcsInit = new HashSet<>(); Set deviationsInit = new HashSet<>(); @@ -98,7 +163,11 @@ public class ModuleEffectiveStatementImpl extends AbstractEffectiveDocumentedDat Set featuresInit = new HashSet<>(); List extensionNodesInit = new LinkedList<>(); - + Map mutableChildNodes = new LinkedHashMap<>(); + Set mutableGroupings = new HashSet<>(); + Set mutableUses = new HashSet<>(); + Set> mutableTypeDefinitions = new LinkedHashSet<>(); + Set mutablePublicChildNodes = new LinkedHashSet<>(); for (EffectiveStatement effectiveStatement : effectiveSubstatements) { if (effectiveStatement instanceof UnknownSchemaNode) { @@ -110,11 +179,9 @@ public class ModuleEffectiveStatementImpl extends AbstractEffectiveDocumentedDat if (effectiveStatement instanceof ModuleImport) { importsInit.add((ModuleImport) effectiveStatement); } - if (effectiveStatement instanceof IncludeEffectiveStatementImpl) { -// ((IncludeEffectiveStatementImpl) effectiveStatement). - } if (effectiveStatement instanceof NotificationDefinition) { - notificationsInit.add((NotificationDefinition) effectiveStatement); + notificationsInit + .add((NotificationDefinition) effectiveStatement); } if (effectiveStatement instanceof RpcDefinition) { rpcsInit.add((RpcDefinition) effectiveStatement); @@ -129,20 +196,61 @@ public class ModuleEffectiveStatementImpl extends AbstractEffectiveDocumentedDat featuresInit.add((FeatureDefinition) effectiveStatement); } if (effectiveStatement instanceof ExtensionDefinition) { - extensionNodesInit.add((ExtensionDefinition) effectiveStatement); + extensionNodesInit + .add((ExtensionDefinition) effectiveStatement); + } + if (effectiveStatement instanceof DataSchemaNode) { + DataSchemaNode dataSchemaNode = (DataSchemaNode) effectiveStatement; + if (!mutableChildNodes.containsKey(dataSchemaNode.getQName())) { + mutableChildNodes.put(dataSchemaNode.getQName(), + dataSchemaNode); + mutablePublicChildNodes.add(dataSchemaNode); + } else { + throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement); + } + } + if (effectiveStatement instanceof UsesNode) { + UsesNode usesNode = (UsesNode) effectiveStatement; + if (!mutableUses.contains(usesNode)) { + mutableUses.add(usesNode); + } else { + throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement); + } + } + if (effectiveStatement instanceof TypeDefEffectiveStatementImpl) { + TypeDefEffectiveStatementImpl typeDef = (TypeDefEffectiveStatementImpl) effectiveStatement; + ExtendedType extendedType = typeDef.buildType(); + if (!mutableTypeDefinitions.contains(extendedType)) { + mutableTypeDefinitions.add(extendedType); + } else { + throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement); + } + } + if (effectiveStatement instanceof GroupingDefinition) { + GroupingDefinition grp = (GroupingDefinition) effectiveStatement; + if (!mutableGroupings.contains(grp)) { + mutableGroupings.add(grp); + } else { + throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, 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); + + 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 @@ -235,6 +343,43 @@ public class ModuleEffectiveStatementImpl extends AbstractEffectiveDocumentedDat return unknownNodes; } + @Override + public final Set> getTypeDefinitions() { + return typeDefinitions; + } + + @Override + public final Set getChildNodes() { + return publicChildNodes; + } + + @Override + public final Set getGroupings() { + return groupings; + } + + @Override + public final DataSchemaNode getDataChildByName(final QName name) { + // Child nodes are keyed by their container name, so we can do a direct + // lookup + return childNodes.get(name); + } + + @Override + public final DataSchemaNode getDataChildByName(final String name) { + for (DataSchemaNode node : childNodes.values()) { + if (node.getQName().getLocalName().equals(name)) { + return node; + } + } + return null; + } + + @Override + public Set getUses() { + return uses; + } + @Override public String getSource() { return source; @@ -245,7 +390,8 @@ public class ModuleEffectiveStatementImpl extends AbstractEffectiveDocumentedDat 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 + + ((yangVersion == null) ? 0 : yangVersion.hashCode()); result = prime * result + qNameModule.hashCode(); return result; } @@ -284,7 +430,7 @@ public class ModuleEffectiveStatementImpl extends AbstractEffectiveDocumentedDat @Override public String toString() { - StringBuilder sb = new StringBuilder(ModuleImpl.class.getSimpleName()); + StringBuilder sb = new StringBuilder(ModuleEffectiveStatementImpl.class.getSimpleName()); sb.append("["); sb.append("name=").append(name); sb.append(", namespace=").append(getNamespace()); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/MustEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/MustEffectiveStatementImpl.java index 52bbd3718c..e9419896e8 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/MustEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/MustEffectiveStatementImpl.java @@ -1,16 +1,135 @@ +/** + * 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.effective; +import org.opendaylight.yangtools.yang.model.api.MustDefinition; import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.MustStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; public class MustEffectiveStatementImpl extends - EffectiveStatementBase { + EffectiveStatementBase implements + MustDefinition { + + private RevisionAwareXPath xPath; + private String description; + private String errorAppTag; + private String errorMessage; + private String reference; public MustEffectiveStatementImpl( StmtContext ctx) { super(ctx); + initFields(); + + xPath = ctx.getStatementArgument(); + } + + private void initFields() { + + for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { + + if (effectiveStatement instanceof DescriptionEffectiveStatementImpl) { + description = ((DescriptionEffectiveStatementImpl) effectiveStatement) + .argument(); + } + if (effectiveStatement instanceof ErrorAppTagEffectiveStatementImpl) { + errorAppTag = ((ErrorAppTagEffectiveStatementImpl) effectiveStatement) + .argument(); + } + if (effectiveStatement instanceof ErrorMessageEffectiveStatementImpl) { + errorMessage = ((ErrorMessageEffectiveStatementImpl) effectiveStatement) + .argument(); + } + if (effectiveStatement instanceof ReferenceEffectiveStatementImpl) { + reference = ((ReferenceEffectiveStatementImpl) effectiveStatement) + .argument(); + } + } } -} \ No newline at end of file + @Override + public RevisionAwareXPath getXpath() { + return xPath; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getErrorAppTag() { + return errorAppTag; + } + + @Override + public String getErrorMessage() { + return errorMessage; + } + + @Override + public String getReference() { + return reference; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((xPath == null) ? 0 : xPath.hashCode()); + result = prime * result + + ((description == null) ? 0 : description.hashCode()); + result = prime * result + + ((reference == null) ? 0 : reference.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; + } + final MustEffectiveStatementImpl other = (MustEffectiveStatementImpl) obj; + if (xPath == null) { + if (other.xPath != null) { + return false; + } + } else if (!xPath.equals(other.xPath)) { + return false; + } + if (description == null) { + if (other.description != null) { + return false; + } + } else if (!description.equals(other.description)) { + 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() { + return xPath.toString(); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/NotificationEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/NotificationEffectiveStatementImpl.java index b53772ae92..8b2ec246cb 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/NotificationEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/NotificationEffectiveStatementImpl.java @@ -10,7 +10,6 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; 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.NotificationStatement; diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/OutputEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/OutputEffectiveStatementImpl.java index 0d061e115b..7f8133cad4 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/OutputEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/OutputEffectiveStatementImpl.java @@ -7,8 +7,9 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; +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; @@ -37,7 +38,7 @@ public class OutputEffectiveStatementImpl extends boolean augmenting; boolean addedByUses; - boolean configuration; + boolean configuration = true; ContainerSchemaNode original; ConstraintDefinition constraints; @@ -52,7 +53,7 @@ public class OutputEffectiveStatementImpl extends path = Utils.getSchemaPath(ctx); presence = (firstEffective(PresenceEffectiveStatementImpl.class) == null) ? false : true; - // :TODO init other fields + this.constraints = new EffectiveConstraintDefinitionImpl(this); initSubstatementCollections(); initCopyType(ctx); @@ -61,20 +62,20 @@ public class OutputEffectiveStatementImpl extends private void initCopyType( StmtContext> ctx) { - TypeOfCopy typeOfCopy = ctx.getTypeOfCopy(); - switch (typeOfCopy) { - case ADDED_BY_AUGMENTATION: + Set copyTypesFromOriginal = StmtContextUtils.getCopyTypesFromOriginal(ctx); + + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION)) { augmenting = true; - original = (ContainerSchemaNode) ctx.getOriginalCtx() - .buildEffective(); - break; - case ADDED_BY_USES: + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) { addedByUses = true; - original = (ContainerSchemaNode) ctx.getOriginalCtx() - .buildEffective(); - break; - default: - break; + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) { + addedByUses = augmenting = true; + } + + if (ctx.getTypeOfCopy() != TypeOfCopy.ORIGINAL) { + original = (ContainerSchemaNode) ctx.getOriginalCtx().buildEffective(); } } @@ -84,6 +85,7 @@ public class OutputEffectiveStatementImpl extends List unknownNodesInit = new LinkedList<>(); Set augmentationsInit = new HashSet<>(); + boolean configurationInit = false; for (EffectiveStatement effectiveStatement : effectiveSubstatements) { if (effectiveStatement instanceof UnknownSchemaNode) { UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement; @@ -93,6 +95,12 @@ public class OutputEffectiveStatementImpl extends AugmentationSchema augmentationSchema = (AugmentationSchema) effectiveStatement; augmentationsInit.add(augmentationSchema); } + if (!configurationInit + && effectiveStatement instanceof ConfigEffectiveStatementImpl) { + ConfigEffectiveStatementImpl configStmt = (ConfigEffectiveStatementImpl) effectiveStatement; + this.configuration = configStmt.argument(); + configurationInit = true; + } } this.unknownNodes = ImmutableList.copyOf(unknownNodesInit); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EnumEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/PathEffectiveStatementImpl.java similarity index 56% rename from yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EnumEffectiveStatementImpl.java rename to yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/PathEffectiveStatementImpl.java index 439b8de0bb..5fa69b0aeb 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EnumEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/PathEffectiveStatementImpl.java @@ -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 @@ -7,14 +7,17 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import org.opendaylight.yangtools.yang.model.api.stmt.EnumStatement; +import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; +import org.opendaylight.yangtools.yang.model.api.stmt.PathStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -public class EnumEffectiveStatementImpl extends - EffectiveStatementBase { +public class PathEffectiveStatementImpl extends + EffectiveStatementBase { - public EnumEffectiveStatementImpl(StmtContext ctx) { + public PathEffectiveStatementImpl( + StmtContext ctx) { super(ctx); } + } \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/PositionEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/PositionEffectiveStatementImpl.java index 41eaba7d59..4b132cc975 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/PositionEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/PositionEffectiveStatementImpl.java @@ -10,11 +10,9 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; import org.opendaylight.yangtools.yang.model.api.stmt.PositionStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -public class PositionEffectiveStatementImpl extends - EffectiveStatementBase { +public class PositionEffectiveStatementImpl extends EffectiveStatementBase { - public PositionEffectiveStatementImpl( - StmtContext ctx) { + public PositionEffectiveStatementImpl(StmtContext ctx) { super(ctx); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RefineEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RefineEffectiveStatementImpl.java index b5c222106d..13f277d54c 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RefineEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RefineEffectiveStatementImpl.java @@ -7,17 +7,73 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; +import java.util.Collection; +import java.util.LinkedList; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; + +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; +import com.google.common.collect.ImmutableList; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; public class RefineEffectiveStatementImpl extends - EffectiveStatementBase { + AbstractEffectiveDocumentedNode + implements SchemaNode { + + private final QName qname; + private final SchemaPath path; + ImmutableList unknownNodes; + private final SchemaNode refineTargetNode; public RefineEffectiveStatementImpl( StmtContext ctx) { super(ctx); + qname = ctx.getStatementArgument().getLastComponent(); + path = Utils.getSchemaPath(ctx); + refineTargetNode = (SchemaNode) ctx.getEffectOfStatement().iterator().next().buildEffective(); + + initSubstatementCollectionsAndFields(); + + } + + public SchemaNode getRefineTargetNode() { + return refineTargetNode; + } + + private void initSubstatementCollectionsAndFields() { + Collection> effectiveSubstatements = effectiveSubstatements(); + + List unknownNodesInit = new LinkedList<>(); + + for (EffectiveStatement effectiveSubstatement : effectiveSubstatements) { + if (effectiveSubstatement instanceof UnknownSchemaNode) { + UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveSubstatement; + unknownNodesInit.add(unknownNode); + } + } + + this.unknownNodes = ImmutableList.copyOf(unknownNodesInit); + } + + @Override + public QName getQName() { + return qname; + } + + @Override + public SchemaPath getPath() { + return path; } + @Override + public List getUnknownSchemaNodes() { + return unknownNodes; + } } \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RequireInstanceEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RequireInstanceEffectiveStatementImpl.java index b89b443710..1d66959415 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RequireInstanceEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RequireInstanceEffectiveStatementImpl.java @@ -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 @@ -10,11 +10,9 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; import org.opendaylight.yangtools.yang.model.api.stmt.RequireInstanceStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -public class RequireInstanceEffectiveStatementImpl extends - EffectiveStatementBase { +public class RequireInstanceEffectiveStatementImpl extends EffectiveStatementBase { - public RequireInstanceEffectiveStatementImpl( - StmtContext ctx) { + public RequireInstanceEffectiveStatementImpl(StmtContext ctx) { super(ctx); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RevisionDateEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RevisionDateEffectiveStatementImpl.java index 5c9508068c..57714cfe6c 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RevisionDateEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RevisionDateEffectiveStatementImpl.java @@ -7,14 +7,16 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; +import java.util.Date; + import org.opendaylight.yangtools.yang.model.api.stmt.RevisionDateStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; public class RevisionDateEffectiveStatementImpl extends - EffectiveStatementBase { + EffectiveStatementBase { public RevisionDateEffectiveStatementImpl( - StmtContext ctx) { + StmtContext ctx) { super(ctx); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RevisionEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RevisionEffectiveStatementImpl.java index b255ff9b29..1e75a8b783 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RevisionEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RevisionEffectiveStatementImpl.java @@ -14,9 +14,34 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; public class RevisionEffectiveStatementImpl extends EffectiveStatementBase { + private final String reference; + private final String description; + public RevisionEffectiveStatementImpl( StmtContext ctx) { super(ctx); + + DescriptionEffectiveStatementImpl descStmt = firstEffective(DescriptionEffectiveStatementImpl.class); + if (descStmt != null) { + description = descStmt.argument(); + } else { + description = null; + } + + ReferenceEffectiveStatementImpl refStmt = firstEffective(ReferenceEffectiveStatementImpl.class); + if (refStmt != null) { + reference = refStmt.argument(); + } else { + reference = null; + } + } + + public final String getDescription() { + return description; + } + + public final String getReference() { + return reference; } } \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/StatusEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/StatusEffectiveStatementImpl.java index eb5274dda0..e0280ca76d 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/StatusEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/StatusEffectiveStatementImpl.java @@ -7,14 +7,16 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; +import org.opendaylight.yangtools.yang.model.api.Status; + import org.opendaylight.yangtools.yang.model.api.stmt.StatusStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; public class StatusEffectiveStatementImpl extends - EffectiveStatementBase { + EffectiveStatementBase { public StatusEffectiveStatementImpl( - StmtContext ctx) { + StmtContext ctx) { super(ctx); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/SubmoduleEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/SubmoduleEffectiveStatementImpl.java index 380bcb10cc..4af5525e95 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/SubmoduleEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/SubmoduleEffectiveStatementImpl.java @@ -7,6 +7,22 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; +import org.opendaylight.yangtools.yang.model.util.ExtendedType; + +import java.util.LinkedHashSet; +import java.util.LinkedHashMap; +import com.google.common.collect.ImmutableMap; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UsesNode; +import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; +import java.util.Map; +import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; +import org.opendaylight.yangtools.yang.parser.spi.SubmoduleNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable; +import org.opendaylight.yangtools.yang.parser.spi.source.IncludedSubmoduleNameToIdentifier; import java.net.URI; import java.util.Collection; import java.util.Date; @@ -14,7 +30,6 @@ 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; @@ -30,17 +45,16 @@ 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 - AbstractEffectiveDocumentedDataNodeContainer implements Module, Immutable { +public class SubmoduleEffectiveStatementImpl + extends + AbstractEffectiveDocumentedNode + implements Module, Immutable { private final QNameModule qNameModule; private final String name; @@ -60,43 +74,96 @@ public class SubmoduleEffectiveStatementImpl extends private ImmutableSet identities; private ImmutableList unknownNodes; private String source; + private ImmutableList> substatementsOfSubmodules; - public SubmoduleEffectiveStatementImpl(StmtContext ctx) { + private ImmutableMap childNodes; + private ImmutableSet groupings; + private ImmutableSet uses; + private ImmutableSet> typeDefinitions; + private ImmutableSet publicChildNodes; + + public SubmoduleEffectiveStatementImpl( + StmtContext> 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()); + String belongsToModuleName = firstAttributeOf( + ctx.declaredSubstatements(), BelongsToStatement.class); + final QNameModule belongsToModuleQName = ctx.getFromNamespace( + ModuleNameToModuleQName.class, belongsToModuleName); + RevisionEffectiveStatementImpl submoduleRevision = firstEffective(RevisionEffectiveStatementImpl.class); + + qNameModule = submoduleRevision == null ? QNameModule.create( + belongsToModuleQName.getNamespace(), + SimpleDateFormatUtil.DEFAULT_DATE_REV) : QNameModule.create( + belongsToModuleQName.getNamespace(), + submoduleRevision.argument()); for (EffectiveStatement effectiveStatement : effectiveSubstatements()) { if (effectiveStatement instanceof PrefixEffectiveStatementImpl) { - prefix = ((PrefixEffectiveStatementImpl) effectiveStatement).argument(); + prefix = ((PrefixEffectiveStatementImpl) effectiveStatement) + .argument(); } if (effectiveStatement instanceof YangVersionEffectiveStatementImpl) { - yangVersion = ((YangVersionEffectiveStatementImpl) effectiveStatement).argument(); + yangVersion = ((YangVersionEffectiveStatementImpl) effectiveStatement) + .argument(); } if (effectiveStatement instanceof OrganizationEffectiveStatementImpl) { - organization = ((OrganizationEffectiveStatementImpl) effectiveStatement).argument(); + organization = ((OrganizationEffectiveStatementImpl) effectiveStatement) + .argument(); } if (effectiveStatement instanceof ContactEffectiveStatementImpl) { - contact = ((ContactEffectiveStatementImpl) effectiveStatement).argument(); + contact = ((ContactEffectiveStatementImpl) effectiveStatement) + .argument(); } } + //:TODO init source, sourcePath source = ctx.getStatementSource().name(); - initSubstatementCollections(); + initSubmodules(ctx); + initSubstatementCollections(ctx); } - private void initSubstatementCollections() { - Collection> effectiveSubstatements = effectiveSubstatements(); + private void initSubmodules( + StmtContext> ctx) { + Map includedSubmodulesMap = ctx + .getAllFromCurrentStmtCtxNamespace(IncludedSubmoduleNameToIdentifier.class); + + if (includedSubmodulesMap == null || includedSubmodulesMap.isEmpty()) { + this.submodules = ImmutableSet.of(); + this.substatementsOfSubmodules = ImmutableList.of(); + return; + } + + Collection includedSubmodules = includedSubmodulesMap + .values(); + + Set submodulesInit = new HashSet<>(); + List> substatementsOfSubmodulesInit = new LinkedList<>(); + for (ModuleIdentifier submoduleIdentifier : includedSubmodules) { + Mutable> submoduleCtx = (Mutable>) ctx + .getFromNamespace(SubmoduleNamespace.class, + submoduleIdentifier); + SubmoduleEffectiveStatementImpl submodule = (SubmoduleEffectiveStatementImpl) submoduleCtx.buildEffective(); + submodulesInit.add(submodule); + substatementsOfSubmodulesInit.addAll(submodule.effectiveSubstatements()); + } + + this.submodules = ImmutableSet.copyOf(submodulesInit); + this.substatementsOfSubmodules = ImmutableList.copyOf(substatementsOfSubmodulesInit); + } + + private void initSubstatementCollections(StmtContext> ctx) { + List> effectiveSubstatements = new LinkedList<>(); + + effectiveSubstatements.addAll(effectiveSubstatements()); + effectiveSubstatements.addAll(this.substatementsOfSubmodules); List unknownNodesInit = new LinkedList<>(); Set augmentationsInit = new HashSet<>(); Set importsInit = new HashSet<>(); - Set submodulesInit = new HashSet<>(); Set notificationsInit = new HashSet<>(); Set rpcsInit = new HashSet<>(); Set deviationsInit = new HashSet<>(); @@ -104,6 +171,13 @@ public class SubmoduleEffectiveStatementImpl extends Set featuresInit = new HashSet<>(); List extensionNodesInit = new LinkedList<>(); + Map mutableChildNodes = new LinkedHashMap<>(); + Set mutableGroupings = new HashSet<>(); + Set mutableUses = new HashSet<>(); + Set> mutableTypeDefinitions = new LinkedHashSet<>(); + Set mutablePublicChildNodes = new LinkedHashSet<>(); + + //:TODO add validation also for other node types for (EffectiveStatement effectiveStatement : effectiveSubstatements) { if (effectiveStatement instanceof UnknownSchemaNode) { unknownNodesInit.add((UnknownSchemaNode) effectiveStatement); @@ -114,11 +188,9 @@ public class SubmoduleEffectiveStatementImpl extends if (effectiveStatement instanceof ModuleImport) { importsInit.add((ModuleImport) effectiveStatement); } - if (effectiveStatement instanceof Module) { - submodulesInit.add((Module) effectiveStatement); - } if (effectiveStatement instanceof NotificationDefinition) { - notificationsInit.add((NotificationDefinition) effectiveStatement); + notificationsInit + .add((NotificationDefinition) effectiveStatement); } if (effectiveStatement instanceof RpcDefinition) { rpcsInit.add((RpcDefinition) effectiveStatement); @@ -133,20 +205,61 @@ public class SubmoduleEffectiveStatementImpl extends featuresInit.add((FeatureDefinition) effectiveStatement); } if (effectiveStatement instanceof ExtensionDefinition) { - extensionNodesInit.add((ExtensionDefinition) effectiveStatement); + extensionNodesInit + .add((ExtensionDefinition) effectiveStatement); + } + if (effectiveStatement instanceof DataSchemaNode) { + DataSchemaNode dataSchemaNode = (DataSchemaNode) effectiveStatement; + if (!mutableChildNodes.containsKey(dataSchemaNode.getQName())) { + mutableChildNodes.put(dataSchemaNode.getQName(), + dataSchemaNode); + mutablePublicChildNodes.add(dataSchemaNode); + } else { + throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement); + } + } + if (effectiveStatement instanceof UsesNode) { + UsesNode usesNode = (UsesNode) effectiveStatement; + if (!mutableUses.contains(usesNode)) { + mutableUses.add(usesNode); + } else { + throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement); + } + } + if (effectiveStatement instanceof TypeDefEffectiveStatementImpl) { + TypeDefEffectiveStatementImpl typeDef = (TypeDefEffectiveStatementImpl) effectiveStatement; + ExtendedType extendedType = typeDef.buildType(); + if (!mutableTypeDefinitions.contains(extendedType)) { + mutableTypeDefinitions.add(extendedType); + } else { + throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement); + } + } + if (effectiveStatement instanceof GroupingDefinition) { + GroupingDefinition grp = (GroupingDefinition) effectiveStatement; + if (!mutableGroupings.contains(grp)) { + mutableGroupings.add(grp); + } else { + throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, 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); + + 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 @@ -239,6 +352,43 @@ public class SubmoduleEffectiveStatementImpl extends return unknownNodes; } + @Override + public final Set> getTypeDefinitions() { + return typeDefinitions; + } + + @Override + public final Set getChildNodes() { + return publicChildNodes; + } + + @Override + public final Set getGroupings() { + return groupings; + } + + @Override + public final DataSchemaNode getDataChildByName(final QName name) { + // Child nodes are keyed by their container name, so we can do a direct + // lookup + return childNodes.get(name); + } + + @Override + public final DataSchemaNode getDataChildByName(final String name) { + for (DataSchemaNode node : childNodes.values()) { + if (node.getQName().getLocalName().equals(name)) { + return node; + } + } + return null; + } + + @Override + public Set getUses() { + return uses; + } + @Override public String getSource() { return source; @@ -249,7 +399,8 @@ public class SubmoduleEffectiveStatementImpl 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 + + ((yangVersion == null) ? 0 : yangVersion.hashCode()); result = prime * result + qNameModule.hashCode(); return result; } @@ -288,7 +439,8 @@ public class SubmoduleEffectiveStatementImpl extends @Override public String toString() { - StringBuilder sb = new StringBuilder(ModuleImpl.class.getSimpleName()); + + StringBuilder sb = new StringBuilder(SubmoduleEffectiveStatementImpl.class.getSimpleName()); sb.append("["); sb.append("name=").append(name); sb.append(", namespace=").append(getNamespace()); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/TypeDefEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/TypeDefEffectiveStatementImpl.java new file mode 100644 index 0000000000..ee0ec2007a --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/TypeDefEffectiveStatementImpl.java @@ -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.parser.stmt.rfc6020.effective; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement; +import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; +import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; +import org.opendaylight.yangtools.yang.model.util.ExtendedType; +import org.opendaylight.yangtools.yang.model.util.ExtendedType.Builder; +import org.opendaylight.yangtools.yang.parser.spi.TypeNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.TypeDefinitionEffectiveBuilder; + +public class TypeDefEffectiveStatementImpl extends EffectiveStatementBase implements + TypeDefinition>, TypeDefinitionEffectiveBuilder { + + private final QName qName; + private final SchemaPath path; + + private final TypeDefinition baseType; + + private String defaultValue; + private String units; + + private String description; + private String reference; + + private Status status; + + private final List ranges; + private final List lengths; + private final List patterns; + private final Integer fractionDigits; + + private ExtendedType extendedType = null; + + public TypeDefEffectiveStatementImpl(StmtContext ctx) { + super(ctx); + + qName = ctx.getStatementArgument(); + path = Utils.getSchemaPath(ctx); + + ExtendedTypeEffectiveStatementImpl type = null; + + for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { + if (effectiveStatement instanceof ExtendedTypeEffectiveStatementImpl) { + type = ((ExtendedTypeEffectiveStatementImpl) effectiveStatement); + } + if (effectiveStatement instanceof DefaultEffectiveStatementImpl) { + defaultValue = ((DefaultEffectiveStatementImpl) effectiveStatement).argument(); + } + if (effectiveStatement instanceof UnitsEffectiveStatementImpl) { + units = ((UnitsEffectiveStatementImpl) effectiveStatement).argument(); + } + if (effectiveStatement instanceof DescriptionEffectiveStatementImpl) { + description = ((DescriptionEffectiveStatementImpl) effectiveStatement).argument(); + } + if (effectiveStatement instanceof ReferenceEffectiveStatementImpl) { + reference = ((ReferenceEffectiveStatementImpl) effectiveStatement).argument(); + } + if (effectiveStatement instanceof StatusEffectiveStatementImpl) { + status = ((StatusEffectiveStatementImpl) effectiveStatement).argument(); + } + } + + if (type != null) { + + ranges = ImmutableList.copyOf(type.getRangeConstraints()); + lengths = ImmutableList.copyOf(type.getLengthConstraints()); + patterns = ImmutableList.copyOf(type.getPatternConstraints()); + fractionDigits = type.getFractionDigits(); + } else { + + ranges = Collections.emptyList(); + lengths = Collections.emptyList(); + patterns = Collections.emptyList(); + fractionDigits = null; + } + + baseType = parseBaseTypeFromCtx(ctx); + } + + private TypeDefinition parseBaseTypeFromCtx(final StmtContext ctx) { + + TypeDefinition baseType; + + QName baseTypeQName = Utils.qNameFromArgument(ctx, + StmtContextUtils.firstAttributeOf(ctx.declaredSubstatements(), TypeStatement.class)); + + if (TypeUtils.isYangBaseTypeString(baseTypeQName.getLocalName())) { + baseType = TypeUtils.getYangBaseTypeFromString(baseTypeQName.getLocalName()); + } else { + StmtContext> baseTypeCtx = ctx + .getParentContext().getFromNamespace(TypeNamespace.class, baseTypeQName); + baseType = (TypeDefEffectiveStatementImpl) baseTypeCtx.buildEffective(); + } + + if (baseType == null) { + baseType = firstSubstatementOfType(TypeDefinition.class); + } + + return baseType; + } + + @Override + public TypeDefinition getBaseType() { + return baseType; + } + + @Override + public String getUnits() { + return units; + } + + @Override + public Object getDefaultValue() { + return defaultValue; + } + + @Override + public QName getQName() { + return qName; + } + + @Override + public SchemaPath getPath() { + return path; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getReference() { + return reference; + } + + @Override + public Status getStatus() { + return status; + } + + public List getRangeConstraints() { + return ranges; + } + + public List getLengthConstraints() { + return lengths; + } + + public List getPatternConstraints() { + return patterns; + } + + public Integer getFractionDigits() { + return fractionDigits; + } + + @Override + public ExtendedType buildType() { + + if (extendedType != null) { + return extendedType; + } + + Builder extendedTypeBuilder; + if (baseType instanceof TypeDefinitionEffectiveBuilder) { + TypeDefinitionEffectiveBuilder typeDefBaseType = (TypeDefinitionEffectiveBuilder) baseType; + extendedTypeBuilder = ExtendedType.builder(qName, typeDefBaseType.buildType(), + Optional.fromNullable(description), Optional.fromNullable(reference), path); + } else { + extendedTypeBuilder = ExtendedType.builder(qName, baseType, Optional.fromNullable(description), + Optional.fromNullable(reference), path); + } + + extendedTypeBuilder.defaultValue(defaultValue); + extendedTypeBuilder.units(units); + + extendedTypeBuilder.fractionDigits(fractionDigits); + extendedTypeBuilder.ranges(ranges); + extendedTypeBuilder.lengths(lengths); + extendedTypeBuilder.patterns(patterns); + + extendedType = extendedTypeBuilder.build(); + + return extendedType; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UniqueEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UniqueEffectiveStatementImpl.java new file mode 100644 index 0000000000..81af5e73f2 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UniqueEffectiveStatementImpl.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; + +import java.util.Collection; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; +import org.opendaylight.yangtools.yang.model.api.stmt.UniqueStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; + +public class UniqueEffectiveStatementImpl extends + EffectiveStatementBase, UniqueStatement> { + + public UniqueEffectiveStatementImpl( + StmtContext, UniqueStatement, ?> ctx) { + super(ctx); + } + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UnitsEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UnitsEffectiveStatementImpl.java index 83e4fd2b22..7ab0ac0971 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UnitsEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UnitsEffectiveStatementImpl.java @@ -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 diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UnknownEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UnknownEffectiveStatementImpl.java new file mode 100644 index 0000000000..0493465c19 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UnknownEffectiveStatementImpl.java @@ -0,0 +1,207 @@ +/* + * 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.effective; + +import java.util.Set; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; + +import java.util.ArrayList; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition; +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.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement; +import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; + +public class UnknownEffectiveStatementImpl extends EffectiveStatementBase> implements + UnknownSchemaNode { + + private boolean augmenting; + private boolean addedByUses; + private UnknownSchemaNode original; + + private final QName qName; + private final SchemaPath path; + private ExtensionDefinition extension; + private String description; + private String reference; + private Status status = Status.CURRENT; + private final List unknownNodes = new ArrayList<>(); + private QName nodeType; + private String nodeParameter; + + public UnknownEffectiveStatementImpl(final StmtContext, ?> ctx) { + super(ctx); + + extension = (ExtensionEffectiveStatementImpl) ctx.getAllFromNamespace(ExtensionNamespace.class).get(ctx + .getPublicDefinition().getStatementName()).buildEffective(); + + nodeType = extension.getQName(); + nodeParameter = argument(); + qName = argument() != null ? QName.create(Utils.qNameFromArgument(ctx, ctx.getStatementArgument()).getModule(), argument()) : null; + path = Utils.getSchemaPath(ctx); + + // TODO init other fields (see Bug1412Test) + + for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { + if (effectiveStatement instanceof DescriptionEffectiveStatementImpl) { + description = ((DescriptionEffectiveStatementImpl) effectiveStatement).argument(); + } + if (effectiveStatement instanceof ReferenceEffectiveStatementImpl) { + reference = ((ReferenceEffectiveStatementImpl) effectiveStatement).argument(); + } + if (effectiveStatement instanceof UnknownEffectiveStatementImpl) { + unknownNodes.add((UnknownEffectiveStatementImpl) effectiveStatement); + } + } + + initCopyType(ctx); + } + + private void initCopyType( + final StmtContext, ?> ctx) { + + Set copyTypesFromOriginal = StmtContextUtils.getCopyTypesFromOriginal(ctx); + + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION)) { + augmenting = true; + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) { + addedByUses = true; + } + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) { + addedByUses = augmenting = true; + } + + if (ctx.getTypeOfCopy() != TypeOfCopy.ORIGINAL) { + original = (UnknownSchemaNode) ctx.getOriginalCtx().buildEffective(); + } + } + + @Override + public QName getNodeType() { + return nodeType; + } + + @Override + public String getNodeParameter() { + return nodeParameter; + } + + @Override + public boolean isAddedByUses() { + return addedByUses; + } + + @Override + public ExtensionDefinition getExtensionDefinition() { + return extension; + } + + @Override + public QName getQName() { + return qName; + } + + @Override + public SchemaPath getPath() { + return path; + } + + @Override + public List getUnknownSchemaNodes() { + return unknownNodes; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getReference() { + return reference; + } + + @Override + public Status getStatus() { + return status; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((qName == null) ? 0 : qName.hashCode()); + result = prime * result + ((path == null) ? 0 : path.hashCode()); + result = prime * result + ((nodeType == null) ? 0 : nodeType.hashCode()); + result = prime * result + ((nodeParameter == null) ? 0 : nodeParameter.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; + } + UnknownEffectiveStatementImpl other = (UnknownEffectiveStatementImpl) obj; + if (qName == null) { + if (other.qName != null) { + return false; + } + } else if (!qName.equals(other.qName)) { + return false; + } + if (path == null) { + if (other.path != null) { + return false; + } + } else if (!path.equals(other.path)) { + return false; + } + if (nodeType == null) { + if (other.nodeType != null) { + return false; + } + } else if (!nodeType.equals(other.nodeType)) { + return false; + } + if (nodeParameter == null) { + if (other.nodeParameter != null) { + return false; + } + } else if (!nodeParameter.equals(other.nodeParameter)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(nodeType.getNamespace()); + sb.append(":"); + sb.append(nodeType.getLocalName()); + sb.append(" "); + sb.append(nodeParameter); + return sb.toString(); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UsesEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UsesEffectiveStatementImpl.java index 21f6831cdf..bd61e97e1e 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UsesEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UsesEffectiveStatementImpl.java @@ -7,34 +7,89 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; -import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import java.util.Collection; +import java.util.HashMap; +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.model.api.AugmentationSchema; import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; import org.opendaylight.yangtools.yang.model.api.UsesNode; +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.SchemaNodeIdentifier; +import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement; +import org.opendaylight.yangtools.yang.parser.spi.GroupingNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; -public class UsesEffectiveStatementImpl extends EffectiveStatementBaseimplements UsesNode { +public class UsesEffectiveStatementImpl extends EffectiveStatementBase implements UsesNode { private SchemaPath groupingPath; - ImmutableSet augmentations; private boolean addedByUses; ImmutableMap refines; + ImmutableSet augmentations; ImmutableList unknownNodes; public UsesEffectiveStatementImpl(StmtContext> ctx) { super(ctx); - this.groupingPath = null; + initGroupingPath(ctx); + initCopyType(ctx); + initSubstatementCollections(); + } + + private void initGroupingPath(StmtContext> ctx) { + StmtContext> grpCtx = ctx.getFromNamespace( + GroupingNamespace.class, ctx.getStatementArgument()); + this.groupingPath = Utils.getSchemaPath(grpCtx); + } + + private void initSubstatementCollections() { + Collection> effectiveSubstatements = effectiveSubstatements(); + + List unknownNodesInit = new LinkedList<>(); + Set augmentationsInit = new HashSet<>(); + Map refinesInit = new HashMap<>(); + + for (EffectiveStatement effectiveStatement : effectiveSubstatements) { + if (effectiveStatement instanceof UnknownSchemaNode) { + UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement; + unknownNodesInit.add(unknownNode); + } + if (effectiveStatement instanceof AugmentationSchema) { + AugmentationSchema augmentationSchema = (AugmentationSchema) effectiveStatement; + augmentationsInit.add(augmentationSchema); + } + if (effectiveStatement instanceof RefineEffectiveStatementImpl) { + RefineEffectiveStatementImpl refineStmt = (RefineEffectiveStatementImpl) effectiveStatement; + SchemaNodeIdentifier identifier = refineStmt.argument(); + refinesInit.put(Utils.SchemaNodeIdentifierToSchemaPath(identifier), refineStmt.getRefineTargetNode()); + } + } + + this.unknownNodes = ImmutableList.copyOf(unknownNodesInit); + this.augmentations = ImmutableSet.copyOf(augmentationsInit); + this.refines = ImmutableMap.copyOf(refinesInit); + } + + private void initCopyType( + StmtContext> ctx) { + + Set copyTypesFromOriginal = StmtContextUtils.getCopyTypesFromOriginal(ctx); + if(copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) { + addedByUses = true; + } } @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ValueEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ValueEffectiveStatementImpl.java index d21d6fabe8..802893d20b 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ValueEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ValueEffectiveStatementImpl.java @@ -10,13 +10,9 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; import org.opendaylight.yangtools.yang.model.api.stmt.ValueStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -public class ValueEffectiveStatementImpl extends - EffectiveStatementBase { +public class ValueEffectiveStatementImpl extends EffectiveStatementBase { - public ValueEffectiveStatementImpl( - StmtContext ctx) { + public ValueEffectiveStatementImpl(StmtContext ctx) { super(ctx); - } - } \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/WhenEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/WhenEffectiveStatementImpl.java index c7eeac506f..45a1142ce1 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/WhenEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/WhenEffectiveStatementImpl.java @@ -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 diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BinaryEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BinaryEffectiveStatementImpl.java new file mode 100644 index 0000000000..3e94190e50 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BinaryEffectiveStatementImpl.java @@ -0,0 +1,92 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; + +import com.google.common.base.Optional; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangConstants; +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.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; + +public class BinaryEffectiveStatementImpl extends + EffectiveStatementBase implements + BinaryTypeDefinition { + + private static final String DESCRIPTION = "The binary built-in type represents any binary data, i.e., a sequence of octets."; + private static final String REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.8"; + private static final String UNITS = ""; + + private final static QName QNAME = QName.create( + YangConstants.RFC6020_YANG_MODULE, "binary"); + + private final static SchemaPath PATH = SchemaPath.create(true, QNAME); + private final List defaultValue = Collections.emptyList(); + private final List lengthConstraints; + + public BinaryEffectiveStatementImpl( + final StmtContext> ctx) { + super(ctx); + + final LengthConstraint lengthConstraint = new LengthConstraintEffectiveImpl( + 0, Long.MAX_VALUE, Optional.of(""), Optional.of("")); + lengthConstraints = Collections.singletonList(lengthConstraint); + } + + @Override + public List getLengthConstraints() { + return lengthConstraints; + } + + @Override + public BinaryTypeDefinition getBaseType() { + return null; + } + + @Override + public String getUnits() { + return UNITS; + } + + @Override + public Object getDefaultValue() { + return defaultValue; + } + + @Override + public QName getQName() { + return QNAME; + } + + @Override + public SchemaPath getPath() { + return PATH; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return DESCRIPTION; + } + + @Override + public String getReference() { + return REFERENCE; + } + + @Override + public Status getStatus() { + return Status.CURRENT; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BitEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BitEffectiveStatementImpl.java new file mode 100644 index 0000000000..e5d83c0a0f --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BitEffectiveStatementImpl.java @@ -0,0 +1,156 @@ +/* + * 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.effective.type; + +import java.util.ArrayList; +import java.util.List; + +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.BitStatement; +import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; + +import com.google.common.collect.ImmutableList; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.DescriptionEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.PositionEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ReferenceEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.StatusEffectiveStatementImpl; + +public class BitEffectiveStatementImpl extends EffectiveStatementBase implements + BitsTypeDefinition.Bit { + + private final QName qName; + private final SchemaPath schemaPath; + private Long position; + private String description; + private String reference; + private Status status; + private List unknownSchemaNodes; + + public BitEffectiveStatementImpl(StmtContext ctx) { + super(ctx); + + List unknownSchemaNodesInit = new ArrayList<>(); + + qName = ctx.getStatementArgument(); + schemaPath = Utils.getSchemaPath(ctx); + + for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { + if (effectiveStatement instanceof DescriptionEffectiveStatementImpl) { + description = ((DescriptionEffectiveStatementImpl) effectiveStatement).argument(); + } + if (effectiveStatement instanceof ReferenceEffectiveStatementImpl) { + reference = ((ReferenceEffectiveStatementImpl) effectiveStatement).argument(); + } + if (effectiveStatement instanceof StatusEffectiveStatementImpl) { + status = ((StatusEffectiveStatementImpl) effectiveStatement).argument(); + } + if (effectiveStatement instanceof PositionEffectiveStatementImpl) { + position = ((PositionEffectiveStatementImpl) effectiveStatement).argument(); + } + + if (effectiveStatement instanceof UnknownSchemaNode) { + unknownSchemaNodesInit.add((UnknownSchemaNode) effectiveStatement); + } + } + + unknownSchemaNodes = ImmutableList.copyOf(unknownSchemaNodesInit); + } + + @Override + public Long getPosition() { + return position; + } + + @Override + public String getName() { + return qName.getLocalName(); + } + + @Override + public QName getQName() { + return qName; + } + + @Override + public SchemaPath getPath() { + return schemaPath; + } + + @Override + public List getUnknownSchemaNodes() { + return unknownSchemaNodes; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getReference() { + return reference; + } + + @Override + public Status getStatus() { + return status; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + qName.hashCode(); + result = prime * result + schemaPath.hashCode(); + result = prime * result + ((position == null) ? 0 : position.hashCode()); + result = prime * result + ((unknownSchemaNodes == null) ? 0 : unknownSchemaNodes.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; + } + BitsTypeDefinition.Bit other = (BitsTypeDefinition.Bit) obj; + if (qName == null) { + if (other.getQName() != null) { + return false; + } + } else if (!qName.equals(other.getQName())) { + return false; + } + if (schemaPath == null) { + if (other.getPath() != null) { + return false; + } + } else if (!schemaPath.equals(other.getPath())) { + return false; + } + return true; + } + + @Override + public String toString() { + return BitEffectiveStatementImpl.class.getSimpleName() + "[name=" + qName.getLocalName() + ", position=" + + position + "]"; + } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BitsSpecificationEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BitsSpecificationEffectiveStatementImpl.java new file mode 100644 index 0000000000..8ce3d864c2 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BitsSpecificationEffectiveStatementImpl.java @@ -0,0 +1,179 @@ +/* + * 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.effective.type; + +import org.opendaylight.yangtools.yang.model.util.BitsType; + +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; +import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition; +import org.opendaylight.yangtools.yang.model.util.BaseTypes; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; + +public class BitsSpecificationEffectiveStatementImpl extends + EffectiveStatementBase implements BitsTypeDefinition, TypeDefinitionEffectiveBuilder { + + private static final QName QNAME = BaseTypes.BITS_QNAME; + private static final String DESCRIPTION = "The bits built-in type represents a bit set. " + + "That is, a bits value is a set of flags identified by small integer position " + + "numbers starting at 0. Each bit number has an assigned name."; + + private static final String REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.7"; + private static final String UNITS = ""; + private final SchemaPath path; + private final List bits; + + public BitsSpecificationEffectiveStatementImpl(StmtContext> ctx) { + super(ctx); + + List bitsInit = new ArrayList<>(); + + path = Utils.getSchemaPath(ctx.getParentContext()).createChild(QNAME); + + for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { + if (effectiveStatement instanceof Bit) { + bitsInit.add(((Bit) effectiveStatement)); + } + } + + bits = ImmutableList.copyOf(bitsInit); + } + + @Override + public List getBits() { + return bits; + } + + @Override + public BitsTypeDefinition getBaseType() { + return null; + } + + @Override + public String getUnits() { + return UNITS; + } + + @Override + public Object getDefaultValue() { + return bits; + } + + @Override + public QName getQName() { + return QNAME; + } + + @Override + public SchemaPath getPath() { + return path; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return DESCRIPTION; + } + + @Override + public String getReference() { + return REFERENCE; + } + + @Override + public Status getStatus() { + return Status.CURRENT; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((bits == null) ? 0 : bits.hashCode()); + result = prime * result + QNAME.hashCode(); + result = prime * result + path.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; + } + BitsSpecificationEffectiveStatementImpl other = (BitsSpecificationEffectiveStatementImpl) obj; + if (bits == null) { + if (other.bits != null) { + return false; + } + } else if (!bits.equals(other.bits)) { + return false; + } + if (path == null) { + if (other.path != null) { + return false; + } + } else if (!path.equals(other.path)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(BitsSpecificationEffectiveStatementImpl.class.getSimpleName()); + builder.append(" [name="); + builder.append(QNAME); + builder.append(", path="); + builder.append(path); + builder.append(", description="); + builder.append(DESCRIPTION); + builder.append(", reference="); + builder.append(REFERENCE); + builder.append(", bits="); + builder.append(bits); + builder.append(", units="); + builder.append(UNITS); + builder.append("]"); + return builder.toString(); + } + + private BitsType bitsTypeInstance = null; + @Override + public TypeDefinition buildType() { + + if(bitsTypeInstance != null) { + return bitsTypeInstance; + } + + bitsTypeInstance = BitsType.create(path, bits); + + return bitsTypeInstance; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BooleanEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BooleanEffectiveStatementImpl.java new file mode 100644 index 0000000000..53c858d691 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/BooleanEffectiveStatementImpl.java @@ -0,0 +1,93 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; + +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangConstants; +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.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition; +import org.opendaylight.yangtools.yang.model.util.BaseTypes; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; + +public class BooleanEffectiveStatementImpl + extends EffectiveStatementBase implements + BooleanTypeDefinition { + + public static final String LOCAL_NAME = TypeUtils.BOOLEAN; + private static final QName QNAME = QName.create( + YangConstants.RFC6020_YANG_MODULE, LOCAL_NAME); + private static final SchemaPath PATH = SchemaPath.create(true, QNAME); + private static final String DESCRIPTION = "The boolean built-in type represents a boolean value."; + private static final String REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.5"; + private static final String UNITS = ""; + + public BooleanEffectiveStatementImpl( + StmtContext> ctx) { + super(ctx); + + } + + @Override + public BooleanTypeDefinition getBaseType() { + return null; + } + + @Override + public String getUnits() { + return UNITS; + } + + @Override + public Object getDefaultValue() { + return false; + } + + @Override + public QName getQName() { + return QNAME; + } + + @Override + public SchemaPath getPath() { + return PATH; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return DESCRIPTION; + } + + @Override + public String getReference() { + return REFERENCE; + } + + @Override + public Status getStatus() { + return Status.CURRENT; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(getClass().getSimpleName()); + builder.append(" [name="); + builder.append(BaseTypes.BOOLEAN_QNAME); + builder.append(", path="); + builder.append(PATH); + builder.append("]"); + return builder.toString(); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Decimal64SpecificationEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Decimal64SpecificationEffectiveStatementImpl.java new file mode 100644 index 0000000000..73d6d34ad0 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Decimal64SpecificationEffectiveStatementImpl.java @@ -0,0 +1,183 @@ +/* + * 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.effective.type; + +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; + +import org.opendaylight.yangtools.yang.model.util.Decimal64; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangConstants; +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.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.FractionDigitsEffectiveStatementImpl; + +public class Decimal64SpecificationEffectiveStatementImpl extends + EffectiveStatementBase implements DecimalTypeDefinition, TypeDefinitionEffectiveBuilder { + + private static final String UNITS = ""; + private static final BigDecimal DEFAULT_VALUE = null; + private static final QName QNAME = QName.create(YangConstants.RFC6020_YANG_MODULE, TypeUtils.DECIMAL64); + + private static final String DESCRIPTION = "The decimal64 type represents a subset of the real numbers, which can " + + "be represented by decimal numerals. The value space of decimal64 is the set of numbers that can " + + "be obtained by multiplying a 64-bit signed integer by a negative power of ten, i.e., expressible as " + + "'i x 10^-n' where i is an integer64 and n is an integer between 1 and 18, inclusively."; + + private static final String REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.3"; + private static final BigDecimal MIN_VALUE = new BigDecimal("-922337203685477580.8"); + private static final BigDecimal MAX_VALUE = new BigDecimal("922337203685477580.7"); + + private List rangeConstraints; + private Integer fractionDigits; + private SchemaPath path; + + public Decimal64SpecificationEffectiveStatementImpl(StmtContext> ctx) { + super(ctx); + + path = Utils.getSchemaPath(ctx.getParentContext()).createChild(QNAME); + + for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { + if (effectiveStatement instanceof FractionDigitsEffectiveStatementImpl) { + fractionDigits = ((FractionDigitsEffectiveStatementImpl) effectiveStatement).argument(); + } + } + + rangeConstraints = defaultRangeStatements(); + } + + private List defaultRangeStatements() { + + final List rangeStmts = new ArrayList<>(); + final String rangeDescription = "Integer values between " + MIN_VALUE + " and " + MAX_VALUE + ", inclusively."; + final String rangeReference = RangeConstraintEffectiveImpl.DEFAULT_REFERENCE; + + rangeStmts.add(new RangeConstraintEffectiveImpl(MIN_VALUE, MAX_VALUE, Optional.of(rangeDescription), Optional + .of(rangeReference))); + + return ImmutableList.copyOf(rangeStmts); + } + + @Override + public List getRangeConstraints() { + return rangeConstraints; + } + + @Override + public Integer getFractionDigits() { + return fractionDigits; + } + + @Override + public DecimalTypeDefinition getBaseType() { + return null; + } + + @Override + public String getUnits() { + return UNITS; + } + + @Override + public Object getDefaultValue() { + return DEFAULT_VALUE; + } + + @Override + public QName getQName() { + return QNAME; + } + + @Override + public SchemaPath getPath() { + return path; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return DESCRIPTION; + } + + @Override + public String getReference() { + return REFERENCE; + } + + @Override + public Status getStatus() { + return Status.CURRENT; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((QNAME == null) ? 0 : QNAME.hashCode()); + result = prime * result + ((path == null) ? 0 : path.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; + } + Decimal64SpecificationEffectiveStatementImpl other = (Decimal64SpecificationEffectiveStatementImpl) obj; + if (path == null) { + if (other.path != null) { + return false; + } + } else if (!path.equals(other.path)) { + return false; + } + return true; + } + + @Override + public String toString() { + return Decimal64SpecificationEffectiveStatementImpl.class.getSimpleName() + "[qName=" + QNAME + + ", fractionDigits=" + fractionDigits + "]"; + } + + private Decimal64 decimal64Instance = null; + + @Override + public Decimal64 buildType() { + + if (decimal64Instance != null) { + return decimal64Instance; + } + decimal64Instance = Decimal64.create(path, fractionDigits); + + return decimal64Instance; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/EmptyEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/EmptyEffectiveStatementImpl.java new file mode 100644 index 0000000000..fab86a029a --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/EmptyEffectiveStatementImpl.java @@ -0,0 +1,84 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; + +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangConstants; +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.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; + +public class EmptyEffectiveStatementImpl extends + EffectiveStatementBase implements + EmptyTypeDefinition { + + public static final String LOCAL_NAME = TypeUtils.EMPTY; + private static final QName QNAME = QName.create( + YangConstants.RFC6020_YANG_MODULE, LOCAL_NAME); + private static final SchemaPath PATH = SchemaPath.create(true, QNAME); + private static final String DESCRIPTION = "The empty built-in type represents a leaf that does not have any value, it conveys information by its presence or absence."; + private static final String REFERENCE = "https://tools.ietf.org/html/rfc6020#page-131"; + + public EmptyEffectiveStatementImpl( + StmtContext> ctx) { + super(ctx); + + } + + @Override + public EmptyTypeDefinition getBaseType() { + return null; + } + + @Override + public String getUnits() { + return null; + } + + @Override + public Object getDefaultValue() { + return null; + } + + @Override + public QName getQName() { + return QNAME; + } + + @Override + public SchemaPath getPath() { + return PATH; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return DESCRIPTION; + } + + @Override + public String getReference() { + return REFERENCE; + } + + @Override + public Status getStatus() { + return Status.CURRENT; + } + + @Override + public String toString() { + return "type empty " + QNAME; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/EnumEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/EnumEffectiveStatementImpl.java new file mode 100644 index 0000000000..478004f25e --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/EnumEffectiveStatementImpl.java @@ -0,0 +1,99 @@ +/** + * 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.effective.type; + +import java.util.Collections; +import java.util.List; + +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.EnumStatement; +import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.DescriptionEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ReferenceEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.StatusEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ValueEffectiveStatementImpl; + +public class EnumEffectiveStatementImpl extends EffectiveStatementBase implements + EnumTypeDefinition.EnumPair { + + private QName qName; + private SchemaPath path; + private String description; + private String reference; + private Status status; + private Integer value; + + public EnumEffectiveStatementImpl(StmtContext ctx) { + super(ctx); + + qName = ctx.getStatementArgument(); + path = Utils.getSchemaPath(ctx); + + for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { + if (effectiveStatement instanceof DescriptionEffectiveStatementImpl) { + description = ((DescriptionEffectiveStatementImpl) effectiveStatement).argument(); + } + if (effectiveStatement instanceof ReferenceEffectiveStatementImpl) { + reference = ((ReferenceEffectiveStatementImpl) effectiveStatement).argument(); + } + if (effectiveStatement instanceof StatusEffectiveStatementImpl) { + status = ((StatusEffectiveStatementImpl) effectiveStatement).argument(); + } + if (effectiveStatement instanceof ValueEffectiveStatementImpl) { + value = ((ValueEffectiveStatementImpl) effectiveStatement).argument(); + } + } + } + + @Override + public String getName() { + return qName.getLocalName(); + } + + @Override + public Integer getValue() { + return value; + } + + @Override + public QName getQName() { + return qName; + } + + @Override + public SchemaPath getPath() { + return path; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getReference() { + return reference; + } + + @Override + public Status getStatus() { + return status; + } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/EnumSpecificationEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/EnumSpecificationEffectiveStatementImpl.java new file mode 100644 index 0000000000..7fbc2b21df --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/EnumSpecificationEffectiveStatementImpl.java @@ -0,0 +1,192 @@ +/* + * 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.effective.type; + +import com.google.common.base.Optional; +import org.opendaylight.yangtools.yang.model.util.EnumerationType; + +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; +import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangConstants; +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.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; + +public class EnumSpecificationEffectiveStatementImpl extends + EffectiveStatementBase implements EnumTypeDefinition, TypeDefinitionEffectiveBuilder { + + private static final QName QNAME = QName.create(YangConstants.RFC6020_YANG_MODULE, "enumeration"); + + private static final String DESCRIPTION = "The enumeration built-in type represents values from a set of assigned names."; + private static final String REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.6"; + private static final String UNITS = ""; + + private final SchemaPath path; + private EnumPair defaultEnum; + private final List enums; + + public EnumSpecificationEffectiveStatementImpl(StmtContext> ctx) { + super(ctx); + + List enumsInit = new ArrayList<>(); + + path = Utils.getSchemaPath(ctx.getParentContext()).createChild(QNAME); + + for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { + if (effectiveStatement instanceof EnumPair) { + enumsInit.add((EnumPair) effectiveStatement); + } + } + + defaultEnum = null; // TODO get from parentContext + enums = ImmutableList.copyOf(enumsInit); + } + + @Override + public List getValues() { + return enums; + } + + @Override + public EnumTypeDefinition getBaseType() { + return null; + } + + @Override + public String getUnits() { + return UNITS; + } + + @Override + public Object getDefaultValue() { + return defaultEnum; + } + + @Override + public QName getQName() { + return QNAME; + } + + @Override + public SchemaPath getPath() { + return path; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return DESCRIPTION; + } + + @Override + public String getReference() { + return REFERENCE; + } + + @Override + public Status getStatus() { + return Status.CURRENT; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((defaultEnum == null) ? 0 : defaultEnum.hashCode()); + result = prime * result + ((enums == null) ? 0 : enums.hashCode()); + result = prime * result + QNAME.hashCode(); + result = prime * result + ((path == null) ? 0 : path.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; + } + EnumSpecificationEffectiveStatementImpl other = (EnumSpecificationEffectiveStatementImpl) obj; + if (defaultEnum == null) { + if (other.defaultEnum != null) { + return false; + } + } else if (!defaultEnum.equals(other.defaultEnum)) { + return false; + } + if (enums == null) { + if (other.enums != null) { + return false; + } + } else if (!enums.equals(other.enums)) { + return false; + } + if (path == null) { + if (other.path != null) { + return false; + } + } else if (!path.equals(other.path)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(EnumSpecificationEffectiveStatementImpl.class.getSimpleName()); + builder.append(" [name="); + builder.append(QNAME); + builder.append(", path="); + builder.append(path); + builder.append(", description="); + builder.append(DESCRIPTION); + builder.append(", reference="); + builder.append(REFERENCE); + builder.append(", defaultEnum="); + builder.append(defaultEnum); + builder.append(", enums="); + builder.append(enums); + builder.append(", units="); + builder.append(UNITS); + builder.append("]"); + return builder.toString(); + } + + private EnumerationType enumerationTypeInstance = null; + @Override + public TypeDefinition buildType() { + + if(enumerationTypeInstance !=null) { + return enumerationTypeInstance; + } + + //:FIXME set defaultValue as parameter + enumerationTypeInstance = EnumerationType.create(path, enums, Optional.absent()); + + return enumerationTypeInstance; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/IdentityRefSpecificationEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/IdentityRefSpecificationEffectiveStatementImpl.java new file mode 100644 index 0000000000..240c13cb19 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/IdentityRefSpecificationEffectiveStatementImpl.java @@ -0,0 +1,130 @@ +/* + * 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.effective.type; + +import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement; + +import org.opendaylight.yangtools.yang.parser.spi.IdentityNamespace; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.BaseEffectiveStatementImpl; +import org.opendaylight.yangtools.yang.model.util.IdentityrefType; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangConstants; +import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; +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.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; + +public class IdentityRefSpecificationEffectiveStatementImpl extends + EffectiveStatementBase implements IdentityrefTypeDefinition, + TypeDefinitionEffectiveBuilder { + + private static final QName QNAME = QName.create(YangConstants.RFC6020_YANG_MODULE, TypeUtils.IDENTITY_REF); + + private static final String DESCRIPTION = "The identityref type is used to reference an existing identity."; + private static final String REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.10"; + + private static final String UNITS = ""; + + private final SchemaPath path; + + private final IdentitySchemaNode identity; + private IdentityrefType identityRefTypeInstance = null; + + public IdentityRefSpecificationEffectiveStatementImpl( + StmtContext> ctx) { + super(ctx); + + path = Utils.getSchemaPath(ctx.getParentContext()).createChild(QNAME); + + final BaseEffectiveStatementImpl base = firstEffective(BaseEffectiveStatementImpl.class); + if (base != null) { + QName identityQName = base.argument(); + StmtContext> identityCtx = ctx.getFromNamespace(IdentityNamespace.class, identityQName); + identity = (IdentitySchemaNode) identityCtx.buildEffective(); + } else { + identity = null; + } + } + + @Override + public IdentitySchemaNode getIdentity() { + return identity; + } + + @Override + public IdentityrefTypeDefinition getBaseType() { + return null; + } + + @Override + public String getUnits() { + return UNITS; + } + + @Override + public Object getDefaultValue() { + return identity; + } + + @Override + public QName getQName() { + return QNAME; + } + + @Override + public SchemaPath getPath() { + return path; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return DESCRIPTION; + } + + @Override + public String getReference() { + return REFERENCE; + } + + @Override + public Status getStatus() { + return Status.CURRENT; + } + + @Override + public String toString() { + return "identityref " + identity.getQName().getLocalName(); + } + + @Override + public TypeDefinition buildType() { + + if (identityRefTypeInstance != null) { + return identityRefTypeInstance; + } + + identityRefTypeInstance = IdentityrefType.create(path, identity); + + return identityRefTypeInstance; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/InstanceIdentifierSpecificationEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/InstanceIdentifierSpecificationEffectiveStatementImpl.java new file mode 100644 index 0000000000..faa53652cf --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/InstanceIdentifierSpecificationEffectiveStatementImpl.java @@ -0,0 +1,130 @@ +/* + * 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.effective.type; + +import org.opendaylight.yangtools.yang.model.util.InstanceIdentifierType; + +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangConstants; +import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.RequireInstanceEffectiveStatementImpl; + +public class InstanceIdentifierSpecificationEffectiveStatementImpl extends + EffectiveStatementBase implements TypeDefinitionEffectiveBuilder, InstanceIdentifierTypeDefinition { + + private static final QName QNAME = QName.create(YangConstants.RFC6020_YANG_MODULE, "instance-identifier"); + private static final SchemaPath PATH = SchemaPath.create(true, QNAME); + private static final String DESCRIPTION = "The instance-identifier built-in type is used to " + + "uniquely identify a particular instance node in the data tree."; + private static final String REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.13"; + + private static final String UNITS = ""; + private final Boolean requireInstance; + + public InstanceIdentifierSpecificationEffectiveStatementImpl( + StmtContext> ctx) { + super(ctx); + + RequireInstanceEffectiveStatementImpl requireInstanceStmtCtx = firstEffective(RequireInstanceEffectiveStatementImpl.class); + requireInstance = (requireInstanceStmtCtx != null) ? requireInstanceStmtCtx.argument() : false; + } + + @Override + public RevisionAwareXPath getPathStatement() { + return null; + } + + @Override + public boolean requireInstance() { + return requireInstance; + } + + @Override + public InstanceIdentifierTypeDefinition getBaseType() { + return null; + } + + @Override + public String getUnits() { + return UNITS; + } + + @Override + public Object getDefaultValue() { + return null; + } + + @Override + public QName getQName() { + return QNAME; + } + + @Override + public SchemaPath getPath() { + return PATH; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return DESCRIPTION; + } + + @Override + public String getReference() { + return REFERENCE; + } + + @Override + public Status getStatus() { + return Status.CURRENT; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + requireInstance.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; + } + InstanceIdentifierSpecificationEffectiveStatementImpl other = (InstanceIdentifierSpecificationEffectiveStatementImpl) obj; + return requireInstance.equals(other.requireInstance); + } + + @Override + public TypeDefinition buildType() { + return InstanceIdentifierType.create(requireInstance); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int16EffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int16EffectiveStatementImpl.java new file mode 100644 index 0000000000..22c0e6cc4e --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int16EffectiveStatementImpl.java @@ -0,0 +1,27 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; + +public class Int16EffectiveStatementImpl extends IntegerEffectiveImplBase { + + public static final String LOCAL_NAME = TypeUtils.INT16; + + private static final Number MIN_RANGE = Short.MIN_VALUE; + private static final Number MAX_RANGE = Short.MAX_VALUE; + + private static final String DESCRIPTION = LOCAL_NAME + " represents integer values between " + MIN_RANGE + " and " + + MAX_RANGE + ", inclusively."; + + public Int16EffectiveStatementImpl(final StmtContext> ctx) { + + super(ctx, LOCAL_NAME, MIN_RANGE, MAX_RANGE, DESCRIPTION); + } + + @Override + public String toString() { + return "type " + qName; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int32EffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int32EffectiveStatementImpl.java new file mode 100644 index 0000000000..a4e76d610e --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int32EffectiveStatementImpl.java @@ -0,0 +1,27 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; + +public class Int32EffectiveStatementImpl extends IntegerEffectiveImplBase { + + public static final String LOCAL_NAME = TypeUtils.INT32; + + private static final Number MIN_RANGE = Integer.MIN_VALUE; + private static final Number MAX_RANGE = Integer.MAX_VALUE; + + private static final String DESCRIPTION = LOCAL_NAME + " represents integer values between " + MIN_RANGE + " and " + + MAX_RANGE + ", inclusively."; + + public Int32EffectiveStatementImpl(final StmtContext> ctx) { + + super(ctx, LOCAL_NAME, MIN_RANGE, MAX_RANGE, DESCRIPTION); + } + + @Override + public String toString() { + return "type " + qName; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int64EffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int64EffectiveStatementImpl.java new file mode 100644 index 0000000000..69316df8c1 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int64EffectiveStatementImpl.java @@ -0,0 +1,27 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; + +public class Int64EffectiveStatementImpl extends IntegerEffectiveImplBase { + + public static final String LOCAL_NAME = TypeUtils.INT64; + + private static final Number MIN_RANGE = Long.MIN_VALUE; + private static final Number MAX_RANGE = Long.MAX_VALUE; + + private static final String DESCRIPTION = LOCAL_NAME + " represents integer values between " + MIN_RANGE + " and " + + MAX_RANGE + ", inclusively."; + + public Int64EffectiveStatementImpl(final StmtContext> ctx) { + + super(ctx, LOCAL_NAME, MIN_RANGE, MAX_RANGE, DESCRIPTION); + } + + @Override + public String toString() { + return "type " + qName; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int8EffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int8EffectiveStatementImpl.java new file mode 100644 index 0000000000..9a9a7ccfbc --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/Int8EffectiveStatementImpl.java @@ -0,0 +1,27 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; + +public class Int8EffectiveStatementImpl extends IntegerEffectiveImplBase { + + public static final String LOCAL_NAME = TypeUtils.INT8; + + private static final Number MIN_RANGE = Byte.MIN_VALUE; + private static final Number MAX_RANGE = Byte.MAX_VALUE; + + private static final String DESCRIPTION = LOCAL_NAME + " represents integer values between " + MIN_RANGE + " and " + + MAX_RANGE + ", inclusively."; + + public Int8EffectiveStatementImpl(final StmtContext> ctx) { + + super(ctx, LOCAL_NAME, MIN_RANGE, MAX_RANGE, DESCRIPTION); + } + + @Override + public String toString() { + return "type " + qName; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/IntegerEffectiveImplBase.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/IntegerEffectiveImplBase.java new file mode 100644 index 0000000000..87e0836610 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/IntegerEffectiveImplBase.java @@ -0,0 +1,178 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; + +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; +import com.google.common.base.Optional; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangConstants; +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.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; + +abstract class IntegerEffectiveImplBase extends + EffectiveStatementBase implements IntegerTypeDefinition { + + private static final String REFERENCE_INT = "https://tools.ietf.org/html/rfc6020#section-9.2"; + + protected QName qName; + private SchemaPath path; + private String units = ""; + private final String description; + private List rangeStatements; + + protected IntegerEffectiveImplBase(final StmtContext> ctx, + final String localName, final Number minRange, final Number maxRange, final String description) { + + super(ctx); + + this.qName = QName.create(YangConstants.RFC6020_YANG_MODULE, localName); + path = Utils.getSchemaPath(ctx); + + final String rangeDescription = "Integer values between " + minRange + " and " + maxRange + ", inclusively."; + final RangeConstraint defaultRange = new RangeConstraintEffectiveImpl(minRange, maxRange, + Optional.of(rangeDescription), Optional.of(RangeConstraintEffectiveImpl.DEFAULT_REFERENCE)); + rangeStatements = Collections.singletonList(defaultRange); + + this.description = description; + } + + @Override + public List getRangeConstraints() { + return rangeStatements; + } + + @Override + public IntegerTypeDefinition getBaseType() { + return null; + } + + @Override + public String getUnits() { + return units; + } + + @Override + public Object getDefaultValue() { + return null; + } + + @Override + public QName getQName() { + return qName; + } + + @Override + public SchemaPath getPath() { + return path; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getReference() { + return REFERENCE_INT; + } + + @Override + public Status getStatus() { + return Status.CURRENT; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((qName == null) ? 0 : qName.hashCode()); + result = prime * result + ((path == null) ? 0 : path.hashCode()); + result = prime * result + ((rangeStatements == null) ? 0 : rangeStatements.hashCode()); + result = prime * result + ((units == null) ? 0 : units.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; + } + IntegerEffectiveImplBase other = (IntegerEffectiveImplBase) obj; + if (description == null) { + if (other.description != null) { + return false; + } + } else if (!description.equals(other.description)) { + return false; + } + if (qName == null) { + if (other.qName != null) { + return false; + } + } else if (!qName.equals(other.qName)) { + return false; + } + if (path == null) { + if (other.path != null) { + return false; + } + } else if (!path.equals(other.path)) { + return false; + } + if (rangeStatements == null) { + if (other.rangeStatements != null) { + return false; + } + } else if (!rangeStatements.equals(other.rangeStatements)) { + return false; + } + if (units == null) { + if (other.units != null) { + return false; + } + } else if (!units.equals(other.units)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(getClass().getSimpleName()); + builder.append(" [name="); + builder.append(qName); + builder.append(", path="); + builder.append(path); + builder.append(", description="); + builder.append(description); + builder.append(", reference="); + builder.append(REFERENCE_INT); + builder.append(", units="); + builder.append(units); + builder.append(", rangeStatements="); + builder.append(rangeStatements); + builder.append("]"); + return builder.toString(); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LeafrefSpecificationEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LeafrefSpecificationEffectiveStatementImpl.java new file mode 100644 index 0000000000..67f0e37719 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LeafrefSpecificationEffectiveStatementImpl.java @@ -0,0 +1,156 @@ +/* + * 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.effective.type; + +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; + +import org.opendaylight.yangtools.yang.model.util.Leafref; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangConstants; +import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.PathEffectiveStatementImpl; + +public class LeafrefSpecificationEffectiveStatementImpl extends + EffectiveStatementBase implements LeafrefTypeDefinition, TypeDefinitionEffectiveBuilder { + + public static final String LOCAL_NAME = "leafref"; + private static final QName QNAME = QName.create(YangConstants.RFC6020_YANG_MODULE, LOCAL_NAME); + private static final SchemaPath PATH = SchemaPath.create(true, QNAME); + private static final String DESCRIPTION = "The leafref type is used to reference a particular leaf instance in the data tree."; + private static final String REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.9"; + private static final String UNITS = ""; + + private RevisionAwareXPath xpath; + private final SchemaPath path; + + public LeafrefSpecificationEffectiveStatementImpl(StmtContext> ctx) { + super(ctx); + + path = Utils.getSchemaPath(ctx.getParentContext()).createChild(QNAME); + + for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { + if (effectiveStatement instanceof PathEffectiveStatementImpl) { + xpath = ((PathEffectiveStatementImpl) effectiveStatement).argument(); + } + } + } + + @Override + public RevisionAwareXPath getPathStatement() { + return xpath; + } + + @Override + public LeafrefTypeDefinition getBaseType() { + return null; + } + + @Override + public String getUnits() { + return UNITS; + } + + @Override + public Object getDefaultValue() { + return this; + } + + @Override + public QName getQName() { + return QNAME; + } + + @Override + public SchemaPath getPath() { + return path; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return DESCRIPTION; + } + + @Override + public String getReference() { + return REFERENCE; + } + + @Override + public Status getStatus() { + return Status.CURRENT; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((xpath == null) ? 0 : xpath.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; + } + LeafrefSpecificationEffectiveStatementImpl other = (LeafrefSpecificationEffectiveStatementImpl) obj; + if (xpath == null) { + if (other.xpath != null) { + return false; + } + } else if (!xpath.equals(other.xpath)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("type "); + builder.append(QNAME); + builder.append(" [xpath="); + builder.append(xpath); + builder.append("]"); + return builder.toString(); + } + + private Leafref leafrefInstance = null; + + @Override + public Leafref buildType() { + + if (leafrefInstance != null) { + return leafrefInstance; + } + leafrefInstance = Leafref.create(path, xpath); + + return leafrefInstance; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthConstraintEffectiveImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthConstraintEffectiveImpl.java new file mode 100644 index 0000000000..be0e5e2f33 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthConstraintEffectiveImpl.java @@ -0,0 +1,153 @@ +/** + * 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.effective.type; + +import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; + +import java.util.Objects; + +public class LengthConstraintEffectiveImpl implements LengthConstraint { + + private final Number min; + private final Number max; + + private final String description; + private final String reference; + + private final String errorAppTag; + private final String errorMessage; + + public LengthConstraintEffectiveImpl(final Number min, final Number max, final Optional description, + final Optional reference) { + + super(); + + this.min = Preconditions.checkNotNull(min, "min must not be null."); + this.max = Preconditions.checkNotNull(max, "max must not be null"); + this.description = description.orNull(); + this.reference = reference.orNull(); + + this.errorAppTag = "length-out-of-specified-bounds"; + this.errorMessage = "The argument is out of bounds <" + min + ", " + max + ">"; + } + + @Override + public Number getMin() { + return min; + } + + @Override + public Number getMax() { + return max; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getErrorAppTag() { + return errorAppTag; + } + + @Override + public String getErrorMessage() { + return errorMessage; + } + + @Override + public String getReference() { + return reference; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + errorAppTag.hashCode(); + result = prime * result + errorMessage.hashCode(); + result = prime * result + max.hashCode(); + result = prime * result + min.hashCode(); + result = prime * result + ((reference == null) ? 0 : reference.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; + } + final LengthConstraintEffectiveImpl other = (LengthConstraintEffectiveImpl) obj; + if (description == null) { + if (other.description != null) { + return false; + } + } else if (!description.equals(other.description)) { + return false; + } + if (errorAppTag == null) { + if (other.errorAppTag != null) { + return false; + } + } else if (!errorAppTag.equals(other.errorAppTag)) { + return false; + } + if (errorMessage == null) { + if (other.errorMessage != null) { + return false; + } + } else if (!errorMessage.equals(other.errorMessage)) { + return false; + } + if (!Objects.equals(max, other.max)) { + return false; + } + if (!Objects.equals(min, other.min)) { + 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 builder = new StringBuilder(); + builder.append(LengthConstraintEffectiveImpl.class.getSimpleName()); + builder.append(" [min="); + builder.append(min); + builder.append(", max="); + builder.append(max); + builder.append(", description="); + builder.append(description); + builder.append(", errorAppTag="); + builder.append(errorAppTag); + builder.append(", reference="); + builder.append(reference); + builder.append(", errorMessage="); + builder.append(errorMessage); + builder.append("]"); + return builder.toString(); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LengthEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthEffectiveStatementImpl.java similarity index 56% rename from yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LengthEffectiveStatementImpl.java rename to yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthEffectiveStatementImpl.java index a2d18ecdd4..e26d69600b 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LengthEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/LengthEffectiveStatementImpl.java @@ -5,16 +5,18 @@ * 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.effective; +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import java.util.List; import org.opendaylight.yangtools.yang.model.api.stmt.LengthStatement; +import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; -public class LengthEffectiveStatementImpl extends - EffectiveStatementBase { +public class LengthEffectiveStatementImpl extends EffectiveStatementBase, LengthStatement> { - public LengthEffectiveStatementImpl( - StmtContext ctx) { + public LengthEffectiveStatementImpl(StmtContext, LengthStatement, ?> ctx) { super(ctx); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/NumericalRestrictionsEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/NumericalRestrictionsEffectiveStatementImpl.java new file mode 100644 index 0000000000..ce97127540 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/NumericalRestrictionsEffectiveStatementImpl.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; + +public class NumericalRestrictionsEffectiveStatementImpl extends EffectiveStatementBase { + + public NumericalRestrictionsEffectiveStatementImpl(StmtContext ctx) { + super(ctx); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternConstraintEffectiveImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternConstraintEffectiveImpl.java new file mode 100644 index 0000000000..e1bef18bb3 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternConstraintEffectiveImpl.java @@ -0,0 +1,141 @@ +/** + * 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.effective.type; + +import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; + +public class PatternConstraintEffectiveImpl implements PatternConstraint { + + private final String regEx; + private final String description; + private final String reference; + + private final String errorAppTag; + private final String errorMessage; + + public PatternConstraintEffectiveImpl(final String regex, final Optional description, + final Optional reference) { + + super(); + + this.regEx = Preconditions.checkNotNull(regex, "regex must not be null."); + this.description = description.orNull(); + this.reference = reference.orNull(); + + errorAppTag = "invalid-regular-expression"; + errorMessage = String.format("String %s is not valid regular expression.", regex); + } + + @Override + public String getRegularExpression() { + return regEx; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getErrorAppTag() { + return errorAppTag; + } + + @Override + public String getErrorMessage() { + return errorMessage; + } + + @Override + public String getReference() { + return reference; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((errorAppTag == null) ? 0 : errorAppTag.hashCode()); + result = prime * result + ((errorMessage == null) ? 0 : errorMessage.hashCode()); + result = prime * result + ((reference == null) ? 0 : reference.hashCode()); + result = prime * result + regEx.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; + } + final PatternConstraintEffectiveImpl other = (PatternConstraintEffectiveImpl) obj; + if (description == null) { + if (other.description != null) { + return false; + } + } else if (!description.equals(other.description)) { + return false; + } + if (errorAppTag == null) { + if (other.errorAppTag != null) { + return false; + } + } else if (!errorAppTag.equals(other.errorAppTag)) { + return false; + } + if (errorMessage == null) { + if (other.errorMessage != null) { + return false; + } + } else if (!errorMessage.equals(other.errorMessage)) { + return false; + } + if (reference == null) { + if (other.reference != null) { + return false; + } + } else if (!reference.equals(other.reference)) { + return false; + } + if (regEx == null) { + if (other.regEx != null) { + return false; + } + } else if (!regEx.equals(other.regEx)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(PatternConstraintEffectiveImpl.class.getSimpleName()); + builder.append(" [regex="); + builder.append(regEx); + builder.append(", description="); + builder.append(description); + builder.append(", reference="); + builder.append(reference); + builder.append(", errorAppTag="); + builder.append(errorAppTag); + builder.append(", errorMessage="); + builder.append(errorMessage); + builder.append("]"); + return builder.toString(); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/PatternEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternEffectiveStatementImpl.java similarity index 58% rename from yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/PatternEffectiveStatementImpl.java rename to yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternEffectiveStatementImpl.java index c3a776ed71..81f7d2a4d3 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/PatternEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/PatternEffectiveStatementImpl.java @@ -5,18 +5,17 @@ * 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.effective; +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; import org.opendaylight.yangtools.yang.model.api.stmt.PatternStatement; +import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; -public class PatternEffectiveStatementImpl extends - EffectiveStatementBase { +public class PatternEffectiveStatementImpl extends EffectiveStatementBase { - public PatternEffectiveStatementImpl( - StmtContext ctx) { + public PatternEffectiveStatementImpl(StmtContext ctx) { super(ctx); } - } \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeConstraintEffectiveImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeConstraintEffectiveImpl.java new file mode 100644 index 0000000000..398b79e408 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeConstraintEffectiveImpl.java @@ -0,0 +1,146 @@ +/** + * 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.effective.type; + +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; + +public class RangeConstraintEffectiveImpl implements RangeConstraint { + + public static final String DEFAULT_REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.2.4"; + private final Number min; + private final Number max; + + private final String description; + private final String reference; + + private final String errorAppTag; + private final String errorMessage; + + public RangeConstraintEffectiveImpl(final Number min, final Number max, final Optional description, + final Optional reference) { + + super(); + + this.min = Preconditions.checkNotNull(min, "min must not be null."); + this.max = Preconditions.checkNotNull(max, "max must not be null."); + this.description = description.orNull(); + this.reference = reference.orNull(); + + this.errorAppTag = "range-out-of-specified-bounds"; + this.errorMessage = "The argument is out of bounds <" + min + ", " + max + ">"; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getErrorAppTag() { + return errorAppTag; + } + + @Override + public String getErrorMessage() { + return errorMessage; + } + + @Override + public String getReference() { + return reference; + } + + @Override + public Number getMin() { + return min; + } + + @Override + public Number getMax() { + return max; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + errorAppTag.hashCode(); + result = prime * result + errorMessage.hashCode(); + result = prime * result + max.hashCode(); + result = prime * result + min.hashCode(); + result = prime * result + ((reference == null) ? 0 : reference.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; + } + final RangeConstraintEffectiveImpl other = (RangeConstraintEffectiveImpl) obj; + if (description == null) { + if (other.description != null) { + return false; + } + } else if (!description.equals(other.description)) { + return false; + } + if (max == null) { + if (other.max != null) { + return false; + } + } else if (!max.equals(other.max)) { + return false; + } + if (min == null) { + if (other.min != null) { + return false; + } + } else if (!min.equals(other.min)) { + 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() { + final StringBuilder builder = new StringBuilder(); + builder.append(RangeConstraintEffectiveImpl.class.getSimpleName()); + builder.append(" [min="); + builder.append(min); + builder.append(", max="); + builder.append(max); + builder.append(", description="); + builder.append(description); + builder.append(", reference="); + builder.append(reference); + builder.append(", errorAppTag="); + builder.append(errorAppTag); + builder.append(", errorMessage="); + builder.append(errorMessage); + builder.append("]"); + return builder.toString(); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RangeEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeEffectiveStatementImpl.java similarity index 56% rename from yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RangeEffectiveStatementImpl.java rename to yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeEffectiveStatementImpl.java index 8b03a38c67..0c88187c41 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/RangeEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/RangeEffectiveStatementImpl.java @@ -5,18 +5,18 @@ * 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.effective; +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import java.util.List; import org.opendaylight.yangtools.yang.model.api.stmt.RangeStatement; +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; -public class RangeEffectiveStatementImpl extends - EffectiveStatementBase { +public class RangeEffectiveStatementImpl extends EffectiveStatementBase, RangeStatement> { - public RangeEffectiveStatementImpl( - StmtContext ctx) { + public RangeEffectiveStatementImpl(StmtContext, RangeStatement, ?> ctx) { super(ctx); - } - -} \ No newline at end of file +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/StringEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/StringEffectiveStatementImpl.java new file mode 100644 index 0000000000..5db27f0aa0 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/StringEffectiveStatementImpl.java @@ -0,0 +1,164 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import com.google.common.base.Optional; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangConstants; +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.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; +import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; +import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; + +public class StringEffectiveStatementImpl extends EffectiveStatementBase implements + StringTypeDefinition { + + public static final String LOCAL_NAME = TypeUtils.STRING; + private static final QName QNAME = QName.create(YangConstants.RFC6020_YANG_MODULE, LOCAL_NAME); + private static final SchemaPath PATH = SchemaPath.create(true, QNAME); + private static final String DEFAULT_VALUE = ""; + private static final String DESCRIPTION = "The string built-in type represents human-readable strings in YANG. " + + "Legal characters are tab, carriage return, line feed, and the legal " + + "characters of Unicode and ISO/IEC 10646"; + private static final String REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.4"; + private final List lengthConstraints; + private final List patternConstraints; + private static final String UNITS = ""; + + public StringEffectiveStatementImpl( + StmtContext> ctx) { + super(ctx); + + final LengthConstraint defLength = new LengthConstraintEffectiveImpl(0, Integer.MAX_VALUE, Optional.of(""), + Optional.of("")); + + lengthConstraints = Collections.singletonList(defLength); + patternConstraints = Collections.emptyList(); + } + + @Override + public List getLengthConstraints() { + return lengthConstraints; + } + + @Override + public List getPatternConstraints() { + return patternConstraints; + } + + @Override + public StringTypeDefinition getBaseType() { + return null; + } + + @Override + public String getUnits() { + return UNITS; + } + + @Override + public Object getDefaultValue() { + return DEFAULT_VALUE; + } + + @Override + public QName getQName() { + return QNAME; + } + + @Override + public SchemaPath getPath() { + return PATH; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return DESCRIPTION; + } + + @Override + public String getReference() { + return REFERENCE; + } + + @Override + public Status getStatus() { + return Status.CURRENT; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((lengthConstraints == null) ? 0 : lengthConstraints.hashCode()); + result = prime * result + QNAME.hashCode(); + result = prime * result + PATH.hashCode(); + result = prime * result + ((patternConstraints == null) ? 0 : patternConstraints.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; + } + StringEffectiveStatementImpl other = (StringEffectiveStatementImpl) obj; + if (lengthConstraints == null) { + if (other.lengthConstraints != null) { + return false; + } + } else if (!lengthConstraints.equals(other.lengthConstraints)) { + return false; + } + if (patternConstraints == null) { + if (other.patternConstraints != null) { + return false; + } + } else if (!patternConstraints.equals(other.patternConstraints)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(getClass().getSimpleName()); + builder.append(" [name="); + builder.append(QNAME); + builder.append(", path="); + builder.append(PATH); + builder.append(", defaultValue="); + builder.append(DEFAULT_VALUE); + builder.append(", description="); + builder.append(DESCRIPTION); + builder.append(", reference="); + builder.append(REFERENCE); + builder.append(", lengthStatements="); + builder.append(lengthConstraints); + builder.append(", patterns="); + builder.append(patternConstraints); + builder.append(", units="); + builder.append(UNITS); + builder.append("]"); + return builder.toString(); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/BitEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/StringRestrictionsEffectiveStatementImpl.java similarity index 51% rename from yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/BitEffectiveStatementImpl.java rename to yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/StringRestrictionsEffectiveStatementImpl.java index 73cb760233..dbbd8eaa75 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/BitEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/StringRestrictionsEffectiveStatementImpl.java @@ -1,20 +1,20 @@ -/** +/* * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; -import org.opendaylight.yangtools.yang.model.api.stmt.BitStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; -public class BitEffectiveStatementImpl extends - EffectiveStatementBase { +public class StringRestrictionsEffectiveStatementImpl extends + EffectiveStatementBase { - public BitEffectiveStatementImpl(StmtContext ctx) { + public StringRestrictionsEffectiveStatementImpl(StmtContext ctx) { super(ctx); } - -} \ No newline at end of file +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/TypeDefinitionEffectiveBuilder.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/TypeDefinitionEffectiveBuilder.java new file mode 100644 index 0000000000..9db85eed24 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/TypeDefinitionEffectiveBuilder.java @@ -0,0 +1,14 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; + +/** + * Effective statements of TypeDef, ExtendedType, Decimal64, Enumeration, Leafref, Union, IndetityRef, Bits + * should implement this interface and method buildType() should create particular object from + * yang.model.util (e.g. Decimal64) + */ +public interface TypeDefinitionEffectiveBuilder { + + TypeDefinition buildType(); + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt16EffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt16EffectiveStatementImpl.java new file mode 100644 index 0000000000..bc0e73b695 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt16EffectiveStatementImpl.java @@ -0,0 +1,26 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; + +public class UInt16EffectiveStatementImpl extends UnsignedIntegerEffectiveImplBase { + + public static final String LOCAL_NAME = TypeUtils.UINT16; + + private static final Number MAX_RANGE = 65535; + + private static final String DESCRIPTION = LOCAL_NAME + " represents integer values between " + MIN_RANGE + " and " + + MAX_RANGE + ", inclusively."; + + public UInt16EffectiveStatementImpl(final StmtContext> ctx) { + + super(ctx, LOCAL_NAME, MAX_RANGE, DESCRIPTION); + } + + @Override + public String toString() { + return "type " + qName; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt32EffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt32EffectiveStatementImpl.java new file mode 100644 index 0000000000..6de9a84a8b --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt32EffectiveStatementImpl.java @@ -0,0 +1,26 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; + +public class UInt32EffectiveStatementImpl extends UnsignedIntegerEffectiveImplBase { + + public static final String LOCAL_NAME = TypeUtils.UINT32; + + private static final Number MAX_RANGE = 4294967295L; + + private static final String DESCRIPTION = LOCAL_NAME + " represents integer values between " + MIN_RANGE + " and " + + MAX_RANGE + ", inclusively."; + + public UInt32EffectiveStatementImpl(final StmtContext> ctx) { + + super(ctx, LOCAL_NAME, MAX_RANGE, DESCRIPTION); + } + + @Override + public String toString() { + return "type " + qName; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt64EffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt64EffectiveStatementImpl.java new file mode 100644 index 0000000000..cf029d693d --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt64EffectiveStatementImpl.java @@ -0,0 +1,28 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import java.math.BigInteger; + +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; + +public class UInt64EffectiveStatementImpl extends UnsignedIntegerEffectiveImplBase { + + public static final String LOCAL_NAME = TypeUtils.UINT64; + + private static final Number MAX_RANGE = new BigInteger("18446744073709551615"); + + private static final String DESCRIPTION = LOCAL_NAME + " represents integer values between " + MIN_RANGE + " and " + + MAX_RANGE + ", inclusively."; + + public UInt64EffectiveStatementImpl(final StmtContext> ctx) { + + super(ctx, LOCAL_NAME, MAX_RANGE, DESCRIPTION); + } + + @Override + public String toString() { + return "type " + qName; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt8EffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt8EffectiveStatementImpl.java new file mode 100644 index 0000000000..7ac048ea87 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UInt8EffectiveStatementImpl.java @@ -0,0 +1,26 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; + +public class UInt8EffectiveStatementImpl extends UnsignedIntegerEffectiveImplBase { + + public static final String LOCAL_NAME = TypeUtils.UINT8; + + private static final Number MAX_RANGE = 255; + + private static final String DESCRIPTION = LOCAL_NAME + " represents integer values between " + MIN_RANGE + " and " + + MAX_RANGE + ", inclusively."; + + public UInt8EffectiveStatementImpl(final StmtContext> ctx) { + + super(ctx, LOCAL_NAME, MAX_RANGE, DESCRIPTION); + } + + @Override + public String toString() { + return "type " + qName; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UnionSpecificationEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UnionSpecificationEffectiveStatementImpl.java new file mode 100644 index 0000000000..51e4f5d3da --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UnionSpecificationEffectiveStatementImpl.java @@ -0,0 +1,153 @@ +/* + * 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.effective.type; + +import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangConstants; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; +import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; +import org.opendaylight.yangtools.yang.model.util.UnionType; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; + +public class UnionSpecificationEffectiveStatementImpl extends + EffectiveStatementBase implements UnionTypeDefinition, + TypeDefinitionEffectiveBuilder { + + private static final QName QNAME = QName.create(YangConstants.RFC6020_YANG_MODULE, "union"); + private static final SchemaPath PATH = SchemaPath.create(true, QNAME); + private static final String DESCRIPTION = "The union built-in type represents a value that corresponds to one of its member types."; + private static final String REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.12"; + + private final List> types; + private UnionType unionTypeInstance = null; + + public UnionSpecificationEffectiveStatementImpl( + StmtContext> ctx) { + super(ctx); + + List> typesInit = new ArrayList<>(); + + for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { + if (effectiveStatement instanceof TypeDefinition) { + typesInit.add(TypeUtils.getTypeFromEffectiveStatement(effectiveStatement)); + } + } + + TypeUtils.sortTypes(typesInit); + + types = ImmutableList.copyOf(typesInit); + } + + @Override + public List> getTypes() { + return types; + } + + @Override + public UnionTypeDefinition getBaseType() { + return null; + } + + @Override + public String getUnits() { + return null; + } + + @Override + public Object getDefaultValue() { + return null; + } + + @Override + public QName getQName() { + return QNAME; + } + + @Override + public SchemaPath getPath() { + return PATH; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return DESCRIPTION; + } + + @Override + public String getReference() { + return REFERENCE; + } + + @Override + public Status getStatus() { + return Status.CURRENT; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + types.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; + } + UnionSpecificationEffectiveStatementImpl other = (UnionSpecificationEffectiveStatementImpl) obj; + return types.equals(other.types); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("type "); + builder.append(QNAME); + builder.append(" (types=["); + for (TypeDefinition td : types) { + builder.append(", ").append(td.getQName().getLocalName()); + } + builder.append(']'); + return builder.toString(); + } + + public TypeDefinition buildType() { + + if (unionTypeInstance != null) { + return unionTypeInstance; + } + + unionTypeInstance = UnionType.create(types); + + return unionTypeInstance; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UnsignedIntegerEffectiveImplBase.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UnsignedIntegerEffectiveImplBase.java new file mode 100644 index 0000000000..04b8afc82c --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/type/UnsignedIntegerEffectiveImplBase.java @@ -0,0 +1,179 @@ +package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type; + +import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; + +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveStatementBase; +import com.google.common.base.Optional; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangConstants; +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.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; +import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; + +abstract class UnsignedIntegerEffectiveImplBase extends + EffectiveStatementBase implements UnsignedIntegerTypeDefinition { + + private static final String REFERENCE_INT = "https://tools.ietf.org/html/rfc6020#section-9.2"; + + protected static final Number MIN_RANGE = 0; + protected QName qName; + private SchemaPath path; + private String units = ""; + private final String description; + private List rangeStatements; + + protected UnsignedIntegerEffectiveImplBase(final StmtContext> ctx, + final String localName, final Number maxRange, final String description) { + + super(ctx); + + this.qName = QName.create(YangConstants.RFC6020_YANG_MODULE, localName); + path = Utils.getSchemaPath(ctx); + + final String rangeDescription = "Integer values between " + MIN_RANGE + " and " + maxRange + ", inclusively."; + final RangeConstraint defaultRange = new RangeConstraintEffectiveImpl(MIN_RANGE, maxRange, + Optional.of(rangeDescription), Optional.of(RangeConstraintEffectiveImpl.DEFAULT_REFERENCE)); + rangeStatements = Collections.singletonList(defaultRange); + + this.description = description; + } + + @Override + public List getRangeConstraints() { + return rangeStatements; + } + + @Override + public UnsignedIntegerTypeDefinition getBaseType() { + return null; + } + + @Override + public String getUnits() { + return units; + } + + @Override + public Object getDefaultValue() { + return null; + } + + @Override + public QName getQName() { + return qName; + } + + @Override + public SchemaPath getPath() { + return path; + } + + @Override + public List getUnknownSchemaNodes() { + return Collections.emptyList(); + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getReference() { + return REFERENCE_INT; + } + + @Override + public Status getStatus() { + return Status.CURRENT; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((qName == null) ? 0 : qName.hashCode()); + result = prime * result + ((path == null) ? 0 : path.hashCode()); + result = prime * result + ((rangeStatements == null) ? 0 : rangeStatements.hashCode()); + result = prime * result + ((units == null) ? 0 : units.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; + } + UnsignedIntegerEffectiveImplBase other = (UnsignedIntegerEffectiveImplBase) obj; + if (description == null) { + if (other.description != null) { + return false; + } + } else if (!description.equals(other.description)) { + return false; + } + if (qName == null) { + if (other.qName != null) { + return false; + } + } else if (!qName.equals(other.qName)) { + return false; + } + if (path == null) { + if (other.path != null) { + return false; + } + } else if (!path.equals(other.path)) { + return false; + } + if (rangeStatements == null) { + if (other.rangeStatements != null) { + return false; + } + } else if (!rangeStatements.equals(other.rangeStatements)) { + return false; + } + if (units == null) { + if (other.units != null) { + return false; + } + } else if (!units.equals(other.units)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(getClass().getSimpleName()); + builder.append(" [name="); + builder.append(qName); + builder.append(", path="); + builder.append(path); + builder.append(", description="); + builder.append(description); + builder.append(", reference="); + builder.append(REFERENCE_INT); + builder.append(", units="); + builder.append(units); + builder.append(", rangeStatements="); + builder.append(rangeStatements); + builder.append("]"); + return builder.toString(); + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/YangParserSimpleTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/YangParserSimpleTest.java index 3c11b01608..4fd15c2cc3 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/YangParserSimpleTest.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/YangParserSimpleTest.java @@ -13,6 +13,19 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import org.junit.Before; + +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.api.UsesNode; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.MustDefinition; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition; +import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; import java.net.URI; import java.text.DateFormat; import java.text.ParseException; @@ -21,21 +34,9 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Set; -import org.junit.Before; -import org.junit.Test; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; -import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition; -import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; -import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; -import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; -import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; -import org.opendaylight.yangtools.yang.model.api.MustDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaPath; -import org.opendaylight.yangtools.yang.model.api.Status; -import org.opendaylight.yangtools.yang.model.api.TypeDefinition; -import org.opendaylight.yangtools.yang.model.api.UsesNode; public class YangParserSimpleTest { private final URI snNS = URI.create("urn:opendaylight:simple-nodes"); @@ -45,6 +46,7 @@ public class YangParserSimpleTest { private final DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); private Set modules; + //TODO: uncomment and run this test once commits are merged @Before public void init() throws Exception { snRev = simpleDateFormat.parse("2013-07-30"); diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveBuildTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveBuildTest.java index f16b13936f..c1f164e053 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveBuildTest.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveBuildTest.java @@ -2,6 +2,16 @@ package org.opendaylight.yangtools.yang.stmt.effective.build.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import java.util.Collection; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import java.util.Set; +import java.net.URISyntaxException; +import java.io.FileNotFoundException; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; import java.net.URI; import org.junit.Test; import org.opendaylight.yangtools.yang.common.QName; @@ -20,8 +30,11 @@ import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSc public class EffectiveBuildTest { private static final YangStatementSourceImpl SIMPLE_MODULE = new YangStatementSourceImpl( - "/stmt-test/effective-build/simple-module.yang"); - private static final QNameModule SIMPLE_MODULE_QNAME = QNameModule.create(URI.create("simple.yang"), null); + "/stmt-test/effective-build/simple-module.yang", false); + private static final QNameModule SIMPLE_MODULE_QNAME = QNameModule.create( + URI.create("simple.yang"), SimpleDateFormatUtil.DEFAULT_DATE_REV); + private static final YangStatementSourceImpl YANG_EXT = new YangStatementSourceImpl( + "/stmt-test/extensions/yang-ext.yang", false); @Test public void effectiveBuildTest() throws SourceException, ReactorException { @@ -42,41 +55,82 @@ public class EffectiveBuildTest { QName q6 = QName.create(SIMPLE_MODULE_QNAME, "sub-sub-container2"); QName q7 = QName.create(SIMPLE_MODULE_QNAME, "grp"); - ContainerSchemaNode rootCon = (ContainerSchemaNode) simpleModule.getDataChildByName(q1); + ContainerSchemaNode rootCon = (ContainerSchemaNode) simpleModule + .getDataChildByName(q1); assertNotNull(rootCon); - ContainerSchemaNode subCon = (ContainerSchemaNode) rootCon.getDataChildByName(q2); + ContainerSchemaNode subCon = (ContainerSchemaNode) rootCon + .getDataChildByName(q2); assertNotNull(subCon); - ContainerSchemaNode subSubCon = (ContainerSchemaNode) subCon.getDataChildByName(q3); + ContainerSchemaNode subSubCon = (ContainerSchemaNode) subCon + .getDataChildByName(q3); assertNotNull(subSubCon); - ContainerSchemaNode rootCon2 = (ContainerSchemaNode) simpleModule.getDataChildByName(q4); + ContainerSchemaNode rootCon2 = (ContainerSchemaNode) simpleModule + .getDataChildByName(q4); assertNotNull(rootCon2); - ContainerSchemaNode subCon2 = (ContainerSchemaNode) rootCon2.getDataChildByName(q5); + ContainerSchemaNode subCon2 = (ContainerSchemaNode) rootCon2 + .getDataChildByName(q5); assertNotNull(subCon2); - ContainerSchemaNode subSubCon2 = (ContainerSchemaNode) subCon2.getDataChildByName(q6); + ContainerSchemaNode subSubCon2 = (ContainerSchemaNode) subCon2 + .getDataChildByName(q6); assertNotNull(subSubCon2); GroupingDefinition grp = simpleModule.getGroupings().iterator().next(); assertNotNull(grp); assertEquals(q7, grp.getQName()); - ContainerSchemaNode grpSubCon2 = (ContainerSchemaNode) grp.getDataChildByName(q5); + ContainerSchemaNode grpSubCon2 = (ContainerSchemaNode) grp + .getDataChildByName(q5); assertNotNull(grpSubCon2); - ContainerSchemaNode grpSubSubCon2 = (ContainerSchemaNode) grpSubCon2.getDataChildByName(q6); + ContainerSchemaNode grpSubSubCon2 = (ContainerSchemaNode) grpSubCon2 + .getDataChildByName(q6); assertNotNull(grpSubSubCon2); assertEquals(SchemaPath.create(true, q1, q2, q3), subSubCon.getPath()); assertEquals(SchemaPath.create(true, q4, q5, q6), subSubCon2.getPath()); - assertEquals(SchemaPath.create(true, q7, q5, q6), grpSubSubCon2.getPath()); + assertEquals(SchemaPath.create(true, q7, q5, q6), + grpSubSubCon2.getPath()); } - private static void addSources(final BuildAction reactor, final YangStatementSourceImpl... sources) { + @Test + public void extensionsTest() throws SourceException, ReactorException { + BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, YANG_EXT); + EffectiveSchemaContext result = reactor.buildEffective(); + assertNotNull(result); + + Set groupings = result.getGroupings(); + assertEquals(1, groupings.size()); + + GroupingDefinition grp = groupings.iterator().next(); + + Collection childNodes = grp.getChildNodes(); + assertEquals(1, childNodes.size()); + DataSchemaNode child = childNodes.iterator().next(); + + assertTrue(child instanceof LeafSchemaNode); + LeafSchemaNode leaf = (LeafSchemaNode) child; + + assertNotNull(leaf.getType()); + } + + @Test + public void mockTest() throws SourceException, ReactorException, FileNotFoundException, URISyntaxException { + BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + reactor.addSource(YANG_EXT); + + SchemaContext result = reactor.buildEffective(); + assertNotNull(result); + } + + private void addSources(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/EffectiveIdentityTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveIdentityTest.java new file mode 100644 index 0000000000..109800d5df --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveIdentityTest.java @@ -0,0 +1,123 @@ +package org.opendaylight.yangtools.yang.stmt.effective.build.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 org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException; + +import java.util.Set; +import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext; +import java.net.URISyntaxException; +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.stmt.test.StmtTestUtils; +import org.junit.Test; + +public class EffectiveIdentityTest { + + private static final YangStatementSourceImpl IDENTITY_TEST = new YangStatementSourceImpl( + "/stmt-test/identity/identity-test.yang", false); + + private static final YangStatementSourceImpl CYCLIC_IDENTITY_TEST = new YangStatementSourceImpl( + "/stmt-test/identity/cyclic-identity-test.yang", false); + + @Test(expected = SomeModifiersUnresolvedException.class) + public void cyclicefineTest() throws SourceException, ReactorException, + URISyntaxException { + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR + .newBuild(); + StmtTestUtils.addSources(reactor, CYCLIC_IDENTITY_TEST); + try { + EffectiveSchemaContext result = reactor.buildEffective(); + } catch (SomeModifiersUnresolvedException e) { + StmtTestUtils.log(e, " "); + throw e; + } + } + + @Test + public void identityTest() throws SourceException, ReactorException, + URISyntaxException { + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR + .newBuild(); + StmtTestUtils.addSources(reactor, IDENTITY_TEST); + EffectiveSchemaContext result = reactor.buildEffective(); + + assertNotNull(result); + + Module module = result.findModuleByName("identity-test", + SimpleDateFormatUtil.DEFAULT_DATE_REV); + + assertNotNull(module); + + Set identities = module.getIdentities(); + + assertNotNull(identities); + assertEquals(4, identities.size()); + + IdentitySchemaNode root = null; + IdentitySchemaNode child1 = null; + IdentitySchemaNode child2 = null; + IdentitySchemaNode child12 = null; + for (IdentitySchemaNode identitySchemaNode : identities) { + switch (identitySchemaNode.getQName().getLocalName()) { + case "root-identity": + root = identitySchemaNode; + break; + case "child-identity-1": + child1 = identitySchemaNode; + break; + case "child-identity-2": + child2 = identitySchemaNode; + break; + case "child-identity-1-2": + child12 = identitySchemaNode; + break; + default: + break; + } + } + + assertNotNull(root); + assertNotNull(child1); + assertNotNull(child2); + assertNotNull(child12); + + assertNull(root.getBaseIdentity()); + + Set rootDerivedIdentities = root + .getDerivedIdentities(); + assertEquals(2, rootDerivedIdentities.size()); + + assertTrue(rootDerivedIdentities.contains(child1)); + assertTrue(rootDerivedIdentities.contains(child2)); + assertFalse(rootDerivedIdentities.contains(child12)); + assertFalse(child1.equals(child2)); + + assertTrue(root == child1.getBaseIdentity()); + assertTrue(root == child2.getBaseIdentity()); + + assertTrue(child2.getDerivedIdentities().isEmpty()); + + Set child1DerivedIdentities = child1 + .getDerivedIdentities(); + assertEquals(1, child1DerivedIdentities.size()); + assertTrue(child1DerivedIdentities.contains(child12)); + assertFalse(child1DerivedIdentities.contains(child1)); + + assertTrue(child1 == child12.getBaseIdentity()); + assertTrue(child12 == child1DerivedIdentities.iterator().next()); + } + +} 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 index b412f69b94..257e23716c 100644 --- 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 @@ -1,8 +1,8 @@ package org.opendaylight.yangtools.yang.stmt.effective.build.test; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; + import java.net.URI; import java.text.ParseException; import java.util.Date; @@ -14,14 +14,17 @@ 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.ContainerSchemaNode; 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.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; 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; @@ -32,25 +35,27 @@ import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSc public class EffectiveModuleTest { private static final YangStatementSourceImpl ROOT_MODULE = new YangStatementSourceImpl( - "/semantic-statement-parser/effective-module/root.yang"); + "/semantic-statement-parser/effective-module/root.yang", false); private static final YangStatementSourceImpl IMPORTED_MODULE = new YangStatementSourceImpl( - "/semantic-statement-parser/effective-module/imported.yang"); + "/semantic-statement-parser/effective-module/imported.yang", false); private static final YangStatementSourceImpl SUBMODULE = new YangStatementSourceImpl( - "/semantic-statement-parser/effective-module/submod.yang"); + "/semantic-statement-parser/effective-module/submod.yang", false); - private static final QNameModule ROOT_MODULE_QNAME = QNameModule.create(URI.create("root-ns"), null); + private static final QNameModule ROOT_MODULE_QNAME = QNameModule.create(URI.create("root-ns"), + SimpleDateFormatUtil.DEFAULT_DATE_REV); private static final QName cont = QName.create(ROOT_MODULE_QNAME, "cont"); + private static final QName feature1 = QName.create(ROOT_MODULE_QNAME, "feature1"); private static final SchemaPath contSchemaPath = SchemaPath.create(true, cont); + private static final SchemaPath feature1SchemaPath = SchemaPath.create(true, feature1); private static Date revision; @BeforeClass public static void init() { try { - revision = SimpleDateFormatUtil.getRevisionFormat() - .parse("2000-01-01"); + revision = SimpleDateFormatUtil.getRevisionFormat().parse("2000-01-01"); } catch (ParseException e) { throw new IllegalArgumentException(e); } @@ -69,8 +74,11 @@ public class EffectiveModuleTest { assertEquals("root-pref", rootModule.getPrefix()); assertEquals("1", rootModule.getYangVersion()); - assertEquals("kisko", rootModule.getOrganization()); - assertEquals("kisko email", rootModule.getContact()); + assertEquals("cisco", rootModule.getOrganization()); + assertEquals("cisco email", rootModule.getContact()); + + final ContainerSchemaNode contSchemaNode = (ContainerSchemaNode) rootModule.getDataChildByName(cont); + assertNotNull(contSchemaNode); final Set augmentations = rootModule.getAugmentations(); assertEquals(1, augmentations.size()); @@ -85,8 +93,8 @@ public class EffectiveModuleTest { assertEquals("imp-pref", importStmt.getPrefix()); final Set submodules = rootModule.getSubmodules(); - //assertEquals(1, submodules.size()); - //assertEquals("submod", submodules.iterator().next().getName()); + assertEquals(1, submodules.size()); + assertEquals("submod", submodules.iterator().next().getName()); final Set notifications = rootModule.getNotifications(); assertEquals(1, notifications.size()); @@ -108,9 +116,15 @@ public class EffectiveModuleTest { assertEquals(1, identities.size()); assertEquals("identity1", identities.iterator().next().getQName().getLocalName()); -// final Set features = rootModule.getFeatures(); -// assertEquals(1, features.size()); -// assertEquals("feature1", features.iterator().next().getQName().getLocalName()); + final Set features = rootModule.getFeatures(); + assertEquals(1, features.size()); + final FeatureDefinition featureStmt = features.iterator().next(); + assertNotNull(featureStmt); + assertEquals(feature1, featureStmt.getQName()); + assertEquals(feature1SchemaPath, featureStmt.getPath()); + assertEquals("feature1 description", featureStmt.getDescription()); + assertEquals("feature1 reference", featureStmt.getReference()); + assertEquals(Status.CURRENT, featureStmt.getStatus()); final List extensionSchemaNodes = rootModule.getExtensionSchemaNodes(); assertEquals(1, extensionSchemaNodes.size()); diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveModulesAndSubmodulesTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveModulesAndSubmodulesTest.java new file mode 100644 index 0000000000..9de3b4b04f --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveModulesAndSubmodulesTest.java @@ -0,0 +1,215 @@ +package org.opendaylight.yangtools.yang.stmt.effective.build.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import org.opendaylight.yangtools.yang.common.QName; + +import org.opendaylight.yangtools.yang.common.QNameModule; +import java.net.URISyntaxException; +import java.net.URI; +import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; +import java.util.Collection; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import java.util.Set; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.stmt.test.StmtTestUtils; +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.effective.EffectiveSchemaContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl; +import org.junit.Test; + +public class EffectiveModulesAndSubmodulesTest { + + private static final YangStatementSourceImpl ROOT_MODULE = new YangStatementSourceImpl( + "/stmt-test/submodules/root-module.yang",false); + private static final YangStatementSourceImpl IMPORTED_MODULE = new YangStatementSourceImpl( + "/stmt-test/submodules/imported-module.yang",false); + private static final YangStatementSourceImpl SUBMODULE_1 = new YangStatementSourceImpl( + "/stmt-test/submodules/submodule-1.yang",false); + private static final YangStatementSourceImpl SUBMODULE_2 = new YangStatementSourceImpl( + "/stmt-test/submodules/submodule-2.yang",false); + private static final YangStatementSourceImpl SUBMODULE_TO_SUBMODULE_1 = new YangStatementSourceImpl( + "/stmt-test/submodules/submodule-to-submodule-1.yang",false); + + @Test + public void modulesAndSubmodulesSimpleReferencesTest() + throws SourceException, ReactorException, URISyntaxException { + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR + .newBuild(); + StmtTestUtils.addSources(reactor, ROOT_MODULE, IMPORTED_MODULE, + SUBMODULE_1, SUBMODULE_2, SUBMODULE_TO_SUBMODULE_1); + EffectiveSchemaContext result = reactor.buildEffective(); + + assertNotNull(result); + + Set modules = result.getModules(); + assertNotNull(modules); + assertEquals(2, modules.size()); + + Module root = null; + Module imported = null; + for (Module module : modules) { + switch (module.getName()) { + case "root-module": + root = module; + break; + case "imported-module": + imported = module; + break; + default: + } + StmtTestUtils.printReferences(module, false, ""); + StmtTestUtils.printChilds(module.getChildNodes(), " "); + } + + assertNotNull(root); + assertNotNull(imported); + + Collection rootChildNodes = root.getChildNodes(); + Collection importedChildNodes = imported + .getChildNodes(); + + assertNotNull(rootChildNodes); + assertNotNull(importedChildNodes); + + assertEquals(3, rootChildNodes.size()); + assertEquals(1, importedChildNodes.size()); + + Set rootSubmodules = root.getSubmodules(); + Set importedSubmodules = imported.getSubmodules(); + + assertNotNull(rootSubmodules); + assertNotNull(importedSubmodules); + + assertEquals(2, rootSubmodules.size()); + assertEquals(0, importedSubmodules.size()); + + Module sub1 = null; + Module sub2 = null; + for (Module rootSubmodule : rootSubmodules) { + switch (rootSubmodule.getName()) { + case "submodule-1": + sub1 = rootSubmodule; + break; + case "submodule-2": + sub2 = rootSubmodule; + break; + default: + } + } + + assertNotNull(sub1); + assertNotNull(sub2); + + assertEquals(QNameModule.create(new URI("root-module"), + SimpleDateFormatUtil.DEFAULT_DATE_REV), sub1.getQNameModule()); + assertEquals(QNameModule.create(new URI("root-module"), + SimpleDateFormatUtil.DEFAULT_DATE_REV), sub2.getQNameModule()); + + Collection sub1ChildNodes = sub1.getChildNodes(); + Collection sub2ChildNodes = sub2.getChildNodes(); + + assertNotNull(sub1ChildNodes); + assertNotNull(sub2ChildNodes); + + assertEquals(2, sub1ChildNodes.size()); + assertEquals(1, sub2ChildNodes.size()); + + Set sub1Submodules = sub1.getSubmodules(); + Set sub2Submodules = sub2.getSubmodules(); + + assertNotNull(sub1Submodules); + assertNotNull(sub2Submodules); + + assertEquals(1, sub1Submodules.size()); + assertEquals(0, sub2Submodules.size()); + + Module sub1Submodule = null; + for (Module submodule : sub1Submodules) { + switch (submodule.getName()) { + case "submodule-to-submodule-1": + sub1Submodule = submodule; + break; + default: + } + } + + assertNotNull(sub1Submodule); + + assertEquals(QNameModule.create(new URI("root-module"), + SimpleDateFormatUtil.DEFAULT_DATE_REV), + sub1Submodule.getQNameModule()); + + Collection sub1SubmoduleChildNodes = sub1Submodule + .getChildNodes(); + assertNotNull(sub1SubmoduleChildNodes); + assertEquals(1, sub1SubmoduleChildNodes.size()); + + Set sub1SubmoduleSubmodules = sub1Submodule.getSubmodules(); + assertNotNull(sub1SubmoduleSubmodules); + assertEquals(0, sub1SubmoduleSubmodules.size()); + + findModulesSubTest(result, root, imported); + + getDataChildByNameSubTest(result, root); + + } + + private void getDataChildByNameSubTest(EffectiveSchemaContext result, + Module root) { + DataSchemaNode containerInRoot = result.getDataChildByName(QName + .create(root.getQNameModule(), "container-in-root-module")); + assertNotNull(containerInRoot); + assertEquals("desc", containerInRoot.getDescription()); + } + + private void findModulesSubTest(EffectiveSchemaContext result, Module root, + Module imported) throws URISyntaxException { + Module foundRoot = result.findModuleByName("root-module", + SimpleDateFormatUtil.DEFAULT_DATE_REV); + Set foundRoots = result.findModuleByNamespace(new URI( + "root-module")); + Module foundRoot3 = result.findModuleByNamespaceAndRevision(new URI( + "root-module"), SimpleDateFormatUtil.DEFAULT_DATE_REV); + + assertNotNull(foundRoot); + assertNotNull(foundRoots); + assertEquals(1, foundRoots.size()); + Module foundRoot2 = foundRoots.iterator().next(); + + assertNotNull(foundRoot2); + assertNotNull(foundRoot3); + + assertEquals(root, foundRoot); + assertEquals(root, foundRoot2); + assertEquals(root, foundRoot3); + + Module foundImported = result.findModuleByName("imported-module", + SimpleDateFormatUtil.DEFAULT_DATE_REV); + Set foundImporteds = result.findModuleByNamespace(new URI( + "imported-module")); + Module foundImported3 = result.findModuleByNamespaceAndRevision( + new URI("imported-module"), + SimpleDateFormatUtil.DEFAULT_DATE_REV); + + assertNotNull(foundImported); + assertNotNull(foundImporteds); + assertEquals(1, foundImporteds.size()); + Module foundImported2 = foundImporteds.iterator().next(); + + assertNotNull(foundImported2); + assertNotNull(foundImported3); + + assertEquals(imported, foundImported); + assertEquals(imported, foundImported2); + assertEquals(imported, foundImported3); + + assertFalse(root.equals(imported)); + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveUsesRefineAndConstraintsTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveUsesRefineAndConstraintsTest.java new file mode 100644 index 0000000000..f24652f444 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/EffectiveUsesRefineAndConstraintsTest.java @@ -0,0 +1,185 @@ +package org.opendaylight.yangtools.yang.stmt.effective.build.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; + +import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.QNameModule; +import java.util.Set; +import org.opendaylight.yangtools.yang.model.api.Module; +import java.net.URISyntaxException; +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 org.opendaylight.yangtools.yang.stmt.test.StmtTestUtils; +import org.junit.Test; + +public class EffectiveUsesRefineAndConstraintsTest { + + private static final YangStatementSourceImpl REFINE_TEST = new YangStatementSourceImpl( + "/stmt-test/uses/refine-test.yang",false); + + @Test + public void refineTest() throws SourceException, ReactorException, + URISyntaxException { + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR + .newBuild(); + + StmtTestUtils.addSources(reactor, REFINE_TEST); + + EffectiveSchemaContext result = reactor.buildEffective(); + + assertNotNull(result); + + Set modules = result.getModules(); + assertNotNull(modules); + assertEquals(1, modules.size()); + + Module module = modules.iterator().next(); + + QNameModule qnameModule = module.getQNameModule(); + QName rootContainer = QName.create(qnameModule, "root-container"); + QName grp1 = QName.create(qnameModule, "grp-1"); + + QName containerFromGrouping = QName.create(qnameModule, + "container-from-grouping"); + QName listInContainer = QName.create(qnameModule, "list-in-container"); + QName choiceFromGrp = QName.create(qnameModule, "choice-from-grp"); + + QName containerFromGrouping2 = QName.create(qnameModule, + "container-from-grouping2"); + QName presenceContainer = QName.create(qnameModule, + "presence-container"); + + SchemaPath listInContainerPath = SchemaPath.create(true, rootContainer, + containerFromGrouping, listInContainer); + SchemaPath choiceFromGrpPath = SchemaPath.create(true, rootContainer, + containerFromGrouping, choiceFromGrp); + SchemaPath presenceContainerPath = SchemaPath.create(true, + rootContainer, containerFromGrouping2, presenceContainer); + + checkRefinedList(result, listInContainerPath); + checkRefinedChoice(result, choiceFromGrpPath); + checkRefinedContainer(result, presenceContainerPath); + + SchemaPath originalListInContainerPath = SchemaPath.create(true, grp1, + containerFromGrouping, listInContainer); + SchemaPath originalChoiceFromGrpPath = SchemaPath.create(true, grp1, + containerFromGrouping, choiceFromGrp); + SchemaPath originalPresenceContainerPath = SchemaPath.create(true, + grp1, containerFromGrouping2, presenceContainer); + + checkOriginalList(result, originalListInContainerPath); + checkOriginalChoice(result, originalChoiceFromGrpPath); + checkOriginalContainer(result, originalPresenceContainerPath); + + } + + private void checkOriginalContainer(EffectiveSchemaContext result, + SchemaPath path) { + SchemaNode containerInContainerNode = SchemaContextUtil + .findDataSchemaNode(result, path); + assertNotNull(containerInContainerNode); + + ContainerSchemaNode containerSchemaNode = (ContainerSchemaNode) containerInContainerNode; + assertNull(containerSchemaNode.getReference()); + assertNull(containerSchemaNode.getDescription()); + assertEquals(true, containerSchemaNode.isConfiguration()); + assertEquals(false, containerSchemaNode.isPresenceContainer()); + + ConstraintDefinition containerConstraints = containerSchemaNode + .getConstraints(); + assertEquals(0, containerConstraints.getMustConstraints().size()); + } + + private void checkOriginalChoice(EffectiveSchemaContext result, + SchemaPath path) { + SchemaNode choiceInContainerNode = SchemaContextUtil + .findDataSchemaNode(result, path); + assertNotNull(choiceInContainerNode); + + ChoiceSchemaNode choiceSchemaNode = (ChoiceSchemaNode) choiceInContainerNode; + + ConstraintDefinition choiceConstraints = choiceSchemaNode + .getConstraints(); + assertTrue(choiceConstraints.isMandatory() == false); + assertTrue(choiceConstraints.getMustConstraints().isEmpty()); + } + + private void checkOriginalList(EffectiveSchemaContext result, + SchemaPath path) { + SchemaNode listInContainerNode = SchemaContextUtil.findDataSchemaNode( + result, path); + assertNotNull(listInContainerNode); + + ListSchemaNode listSchemaNode = (ListSchemaNode) listInContainerNode; + assertEquals("original reference", listSchemaNode.getReference()); + assertEquals("original description", listSchemaNode.getDescription()); + assertEquals(false, listSchemaNode.isConfiguration()); + + ConstraintDefinition listConstraints = listSchemaNode.getConstraints(); + assertTrue(listConstraints.getMinElements() == 10); + assertTrue(listConstraints.getMaxElements() == 20); + assertEquals(1, listConstraints.getMustConstraints().size()); + } + + private void checkRefinedContainer(EffectiveSchemaContext result, + SchemaPath path) { + SchemaNode containerInContainerNode = SchemaContextUtil + .findDataSchemaNode(result, path); + assertNotNull(containerInContainerNode); + + ContainerSchemaNode containerSchemaNode = (ContainerSchemaNode) containerInContainerNode; + assertEquals("new reference", containerSchemaNode.getReference()); + assertEquals("new description", containerSchemaNode.getDescription()); + assertEquals(true, containerSchemaNode.isConfiguration()); + assertEquals(true, containerSchemaNode.isPresenceContainer()); + + ConstraintDefinition containerConstraints = containerSchemaNode + .getConstraints(); + assertEquals(1, containerConstraints.getMustConstraints().size()); + } + + private void checkRefinedChoice(EffectiveSchemaContext result, + SchemaPath path) { + SchemaNode choiceInContainerNode = SchemaContextUtil + .findDataSchemaNode(result, path); + assertNotNull(choiceInContainerNode); + + ChoiceSchemaNode choiceSchemaNode = (ChoiceSchemaNode) choiceInContainerNode; + + ConstraintDefinition choiceConstraints = choiceSchemaNode + .getConstraints(); + assertTrue(choiceConstraints.isMandatory()); + assertTrue(choiceConstraints.getMustConstraints().isEmpty()); + } + + private void checkRefinedList(EffectiveSchemaContext result, SchemaPath path) { + SchemaNode listInContainerNode = SchemaContextUtil.findDataSchemaNode( + result, path); + assertNotNull(listInContainerNode); + + ListSchemaNode listSchemaNode = (ListSchemaNode) listInContainerNode; + assertEquals("new reference", listSchemaNode.getReference()); + assertEquals("new description", listSchemaNode.getDescription()); + assertEquals(true, listSchemaNode.isConfiguration()); + + ConstraintDefinition listConstraints = listSchemaNode.getConstraints(); + assertTrue(listConstraints.getMinElements() == 5); + assertTrue(listConstraints.getMaxElements() == 7); + assertEquals(2, listConstraints.getMustConstraints().size()); + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/AugmentTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/AugmentTest.java new file mode 100644 index 0000000000..066ece47f8 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/AugmentTest.java @@ -0,0 +1,440 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import java.io.FileNotFoundException; +import java.net.URI; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +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.YangConstants; +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.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.RpcDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils; + +public class AugmentTest { + private static final URI fooNS = URI.create("urn:opendaylight.foo"); + private static final URI barNS = URI.create("urn:opendaylight.bar"); + private static final URI bazNS = URI.create("urn:opendaylight.baz"); + private static Date fooRev; + private static Date barRev; + private static Date bazRev; + private static QName q0; + private static QName q1; + private static QName q2; + + private Set modules; + + @BeforeClass + public static void init() throws FileNotFoundException, ParseException { + DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + fooRev = simpleDateFormat.parse("2013-10-13"); + barRev = simpleDateFormat.parse("2013-10-14"); + bazRev = simpleDateFormat.parse("2013-10-15"); + + q0 = QName.create(barNS, barRev, "interfaces"); + q1 = QName.create(barNS, barRev, "ifEntry"); + q2 = QName.create(bazNS, bazRev, "augment-holder"); + } + + @Test + public void testAugmentParsing() throws Exception { + modules = TestUtils.loadModules(getClass().getResource("/augment-test/augment-in-augment").toURI()); + SchemaPath expectedSchemaPath; + List qnames = new ArrayList<>(); + qnames.add(q0); + qnames.add(q1); + qnames.add(q2); + + // foo.yang + Module module1 = TestUtils.findModule(modules, "foo"); + Set augmentations = module1.getAugmentations(); + assertEquals(1, augmentations.size()); + AugmentationSchema augment = augmentations.iterator().next(); + assertNotNull(augment); + + expectedSchemaPath = SchemaPath.create(qnames, true); + assertEquals(expectedSchemaPath, augment.getTargetPath()); + + Collection augmentChildren = augment.getChildNodes(); + assertEquals(4, augmentChildren.size()); + for (DataSchemaNode dsn : augmentChildren) { + TestUtils.checkIsAugmenting(dsn, false); + } + + LeafSchemaNode ds0ChannelNumber = (LeafSchemaNode) augment.getDataChildByName("ds0ChannelNumber"); + LeafSchemaNode interfaceId = (LeafSchemaNode) augment.getDataChildByName("interface-id"); + ContainerSchemaNode schemas = (ContainerSchemaNode) augment.getDataChildByName("schemas"); + ChoiceSchemaNode odl = (ChoiceSchemaNode) augment.getDataChildByName("odl"); + + assertNotNull(ds0ChannelNumber); + assertNotNull(interfaceId); + assertNotNull(schemas); + assertNotNull(odl); + + // leaf ds0ChannelNumber + QName qname = QName.create(fooNS, fooRev, "ds0ChannelNumber"); + qnames.add(qname); + assertEquals(qname, ds0ChannelNumber.getQName()); + expectedSchemaPath = SchemaPath.create(qnames, true); + assertEquals(expectedSchemaPath, ds0ChannelNumber.getPath()); + assertFalse(ds0ChannelNumber.isAugmenting()); + // type of leaf ds0ChannelNumber + QName typeQName = QName.create(YangConstants.RFC6020_YANG_MODULE, TypeUtils.STRING); + List typePath = Collections.singletonList(typeQName); + expectedSchemaPath = SchemaPath.create(typePath, true); + assertEquals(expectedSchemaPath, ds0ChannelNumber.getType().getPath()); + + // leaf interface-id + qname = QName.create(fooNS, fooRev, "interface-id"); + assertEquals(qname, interfaceId.getQName()); + qnames.set(3, qname); + expectedSchemaPath = SchemaPath.create(qnames, true); + assertEquals(expectedSchemaPath, interfaceId.getPath()); + assertFalse(interfaceId.isAugmenting()); + + // container schemas + qname = QName.create(fooNS, fooRev, "schemas"); + assertEquals(qname, schemas.getQName()); + qnames.set(3, qname); + expectedSchemaPath = SchemaPath.create(qnames, true); + assertEquals(expectedSchemaPath, schemas.getPath()); + assertFalse(schemas.isAugmenting()); + + // choice odl + qname = QName.create(fooNS, fooRev, "odl"); + assertEquals(qname, odl.getQName()); + qnames.set(3, qname); + expectedSchemaPath = SchemaPath.create(qnames, true); + assertEquals(expectedSchemaPath, odl.getPath()); + assertFalse(odl.isAugmenting()); + + // baz.yang + Module module3 = TestUtils.findModule(modules, "baz"); + augmentations = module3.getAugmentations(); + assertEquals(3, augmentations.size()); + AugmentationSchema augment1 = null; + AugmentationSchema augment2 = null; + AugmentationSchema augment3 = null; + for (AugmentationSchema as : augmentations) { + if (as.getWhenCondition() == null) { + augment3 = as; + } else if ("if:ifType='ds0'".equals(as.getWhenCondition().toString())) { + augment1 = as; + } else if ("if:ifType='ds2'".equals(as.getWhenCondition().toString())) { + augment2 = as; + } + } + assertNotNull(augment1); + assertNotNull(augment2); + assertNotNull(augment3); + + assertEquals(1, augment1.getChildNodes().size()); + ContainerSchemaNode augmentHolder = (ContainerSchemaNode) augment1.getDataChildByName("augment-holder"); + assertNotNull(augmentHolder); + + assertEquals(1, augment2.getChildNodes().size()); + ContainerSchemaNode augmentHolder2 = (ContainerSchemaNode) augment2.getDataChildByName("augment-holder2"); + assertNotNull(augmentHolder2); + + assertEquals(1, augment3.getChildNodes().size()); + LeafSchemaNode pause = (LeafSchemaNode) augment3.getDataChildByName("pause"); + assertNotNull(pause); + } + + @Test + public void testAugmentResolving() throws Exception { + modules = TestUtils.loadModules(getClass().getResource("/augment-test/augment-in-augment").toURI()); + Module module2 = TestUtils.findModule(modules, "bar"); + ContainerSchemaNode interfaces = (ContainerSchemaNode) module2.getDataChildByName("interfaces"); + ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry"); + + SchemaPath expectedPath; + List qnames = new ArrayList<>(); + qnames.add(q0); + qnames.add(q1); + qnames.add(q2); + + // baz.yang + // augment "/br:interfaces/br:ifEntry" { + ContainerSchemaNode augmentHolder = (ContainerSchemaNode) ifEntry.getDataChildByName("augment-holder"); + TestUtils.checkIsAugmenting(augmentHolder, true); + assertEquals(q2, augmentHolder.getQName()); + expectedPath = SchemaPath.create(qnames, true); + assertEquals(expectedPath, augmentHolder.getPath()); + + // foo.yang + // augment "/br:interfaces/br:ifEntry/bz:augment-holder" + LeafSchemaNode ds0ChannelNumber = (LeafSchemaNode) augmentHolder.getDataChildByName("ds0ChannelNumber"); + LeafSchemaNode interfaceId = (LeafSchemaNode) augmentHolder.getDataChildByName("interface-id"); + ContainerSchemaNode schemas = (ContainerSchemaNode) augmentHolder.getDataChildByName("schemas"); + ChoiceSchemaNode odl = (ChoiceSchemaNode) augmentHolder.getDataChildByName("odl"); + + assertNotNull(ds0ChannelNumber); + assertNotNull(interfaceId); + assertNotNull(schemas); + assertNotNull(odl); + + // leaf ds0ChannelNumber + QName qname = QName.create(fooNS, fooRev, "ds0ChannelNumber"); + assertEquals(qname, ds0ChannelNumber.getQName()); + qnames.add(qname); + expectedPath = SchemaPath.create(qnames, true); + assertEquals(expectedPath, ds0ChannelNumber.getPath()); + + // leaf interface-id + qname = QName.create(fooNS, fooRev, "interface-id"); + assertEquals(qname, interfaceId.getQName()); + qnames.set(3, qname); + expectedPath = SchemaPath.create(qnames, true); + assertEquals(expectedPath, interfaceId.getPath()); + + // container schemas + qname = QName.create(fooNS, fooRev, "schemas"); + assertEquals(qname, schemas.getQName()); + qnames.set(3, qname); + expectedPath = SchemaPath.create(qnames, true); + assertEquals(expectedPath, schemas.getPath()); + + // choice odl + qname = QName.create(fooNS, fooRev, "odl"); + assertEquals(qname, odl.getQName()); + qnames.set(3, qname); + expectedPath = SchemaPath.create(qnames, true); + assertEquals(expectedPath, odl.getPath()); + } + + @Test + public void testAugmentedChoice() throws Exception { + modules = TestUtils.loadModules(getClass().getResource("/augment-test/augment-in-augment").toURI()); + Module module2 = TestUtils.findModule(modules, "bar"); + ContainerSchemaNode interfaces = (ContainerSchemaNode) module2.getDataChildByName("interfaces"); + ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry"); + ContainerSchemaNode augmentedHolder = (ContainerSchemaNode) ifEntry.getDataChildByName("augment-holder"); + TestUtils.checkIsAugmenting(augmentedHolder, true); + + // foo.yang + // augment "/br:interfaces/br:ifEntry/bz:augment-holder" + ChoiceSchemaNode odl = (ChoiceSchemaNode) augmentedHolder.getDataChildByName("odl"); + assertNotNull(odl); + Set cases = odl.getCases(); + assertEquals(4, cases.size()); + + ChoiceCaseNode id = null; + ChoiceCaseNode node1 = null; + ChoiceCaseNode node2 = null; + ChoiceCaseNode node3 = null; + + for (ChoiceCaseNode ccn : cases) { + if ("id".equals(ccn.getQName().getLocalName())) { + id = ccn; + } else if ("node1".equals(ccn.getQName().getLocalName())) { + node1 = ccn; + } else if ("node2".equals(ccn.getQName().getLocalName())) { + node2 = ccn; + } else if ("node3".equals(ccn.getQName().getLocalName())) { + node3 = ccn; + } + } + + assertNotNull(id); + assertNotNull(node1); + assertNotNull(node2); + assertNotNull(node3); + + SchemaPath expectedPath; + List qnames = new ArrayList<>(); + qnames.add(q0); + qnames.add(q1); + qnames.add(q2); + qnames.add(QName.create(fooNS, fooRev, "odl")); + + // case id + QName qname = QName.create(fooNS, fooRev, "id"); + assertEquals(qname, id.getQName()); + qnames.add(qname); + expectedPath = SchemaPath.create(qnames, true); + assertEquals(expectedPath, id.getPath()); + Collection idChildren = id.getChildNodes(); + assertEquals(1, idChildren.size()); + + // case node1 + qname = QName.create(fooNS, fooRev, "node1"); + assertEquals(qname, node1.getQName()); + qnames.set(4, qname); + expectedPath = SchemaPath.create(qnames, true); + assertEquals(expectedPath, node1.getPath()); + Collection node1Children = node1.getChildNodes(); + assertTrue(node1Children.isEmpty()); + + // case node2 + qname = QName.create(fooNS, fooRev, "node2"); + assertEquals(qname, node2.getQName()); + qnames.set(4, qname); + expectedPath = SchemaPath.create(qnames, true); + assertEquals(expectedPath, node2.getPath()); + Collection node2Children = node2.getChildNodes(); + assertTrue(node2Children.isEmpty()); + + // case node3 + qname = QName.create(fooNS, fooRev, "node3"); + assertEquals(qname, node3.getQName()); + qnames.set(4, qname); + expectedPath = SchemaPath.create(qnames, true); + assertEquals(expectedPath, node3.getPath()); + Collection node3Children = node3.getChildNodes(); + assertEquals(1, node3Children.size()); + + // test cases + qnames.clear(); + qnames.add(q0); + qnames.add(q1); + qnames.add(q2); + qnames.add(QName.create(fooNS, fooRev, "odl")); + + // case id child + qnames.add(QName.create(fooNS, fooRev, "id")); + qnames.add(QName.create(fooNS, fooRev, "id")); + LeafSchemaNode caseIdChild = (LeafSchemaNode) idChildren.iterator().next(); + assertNotNull(caseIdChild); + expectedPath = SchemaPath.create(qnames, true); + assertEquals(expectedPath, caseIdChild.getPath()); + + // case node3 child + qnames.set(4, QName.create(fooNS, fooRev, "node3")); + qnames.set(5, QName.create(fooNS, fooRev, "node3")); + ContainerSchemaNode caseNode3Child = (ContainerSchemaNode) node3Children.iterator().next(); + assertNotNull(caseNode3Child); + expectedPath = SchemaPath.create(qnames, true); + assertEquals(expectedPath, caseNode3Child.getPath()); + } + + @Test + public void testAugmentRpc() throws Exception { + modules = TestUtils.loadModules(getClass().getResource("/augment-test/rpc").toURI()); + final URI NS_BAR = URI.create("urn:opendaylight:bar"); + final URI NS_FOO = URI.create("urn:opendaylight:foo"); + final Date revision = new SimpleDateFormat("yyyy-MM-dd").parse("2013-10-11"); + + Module bar = TestUtils.findModule(modules, "bar"); + Set rpcs = bar.getRpcs(); + assertEquals(2, rpcs.size()); + + RpcDefinition submit = null; + for (RpcDefinition rpc : rpcs) { + if ("submit".equals(rpc.getQName().getLocalName())) { + submit = rpc; + break; + } + } + assertNotNull(submit); + + QName submitQName = QName.create(NS_BAR, revision, "submit"); + assertEquals(submitQName, submit.getQName()); + ContainerSchemaNode input = submit.getInput(); + QName inputQName = QName.create(NS_BAR, revision, "input"); + assertEquals(inputQName, input.getQName()); + ChoiceSchemaNode arguments = (ChoiceSchemaNode) input.getDataChildByName("arguments"); + QName argumentsQName = QName.create(NS_BAR, revision, "arguments"); + assertEquals(argumentsQName, arguments.getQName()); + assertFalse(arguments.isAugmenting()); + Set cases = arguments.getCases(); + assertEquals(3, cases.size()); + + ChoiceCaseNode attach = null; + ChoiceCaseNode create = null; + ChoiceCaseNode destroy = null; + for (ChoiceCaseNode child : cases) { + if ("attach".equals(child.getQName().getLocalName())) { + attach = child; + } else if ("create".equals(child.getQName().getLocalName())) { + create = child; + } else if ("destroy".equals(child.getQName().getLocalName())) { + destroy = child; + } + } + assertNotNull(attach); + assertNotNull(create); + assertNotNull(destroy); + + assertTrue(attach.isAugmenting()); + assertTrue(create.isAugmenting()); + assertTrue(destroy.isAugmenting()); + + SchemaPath expectedPath; + QName[] qnames = new QName[4]; + qnames[0] = submitQName; + qnames[1] = inputQName; + qnames[2] = argumentsQName; + + // case attach + qnames[3] = QName.create(NS_FOO, revision, "attach"); + assertEquals(qnames[3], attach.getQName()); + expectedPath = SchemaPath.create(Arrays.asList(qnames), true); + assertEquals(expectedPath, attach.getPath()); + Collection attachChildren = attach.getChildNodes(); + assertEquals(1, attachChildren.size()); + + // case create + qnames[3] = QName.create(NS_FOO, revision, "create"); + assertEquals(qnames[3], create.getQName()); + expectedPath = SchemaPath.create(Arrays.asList(qnames), true); + assertEquals(expectedPath, create.getPath()); + Collection createChildren = create.getChildNodes(); + assertEquals(1, createChildren.size()); + + // case attach + qnames[3] = QName.create(NS_FOO, revision, "destroy"); + assertEquals(qnames[3], destroy.getQName()); + expectedPath = SchemaPath.create(Arrays.asList(qnames), true); + assertEquals(expectedPath, destroy.getPath()); + Collection destroyChildren = destroy.getChildNodes(); + assertEquals(1, destroyChildren.size()); + } + + @Test + public void testAugmentInUsesResolving() throws Exception { + modules = TestUtils.loadModules(getClass().getResource("/augment-test/augment-in-uses").toURI()); + assertEquals(1, modules.size()); + + Module test = modules.iterator().next(); + DataNodeContainer links = (DataNodeContainer) test.getDataChildByName("links"); + DataNodeContainer link = (DataNodeContainer) links.getDataChildByName("link"); + DataNodeContainer nodes = (DataNodeContainer) link.getDataChildByName("nodes"); + ContainerSchemaNode node = (ContainerSchemaNode) nodes.getDataChildByName("node"); + Set augments = node.getAvailableAugmentations(); + assertEquals(1, augments.size()); + assertEquals(1, node.getChildNodes().size()); + LeafSchemaNode id = (LeafSchemaNode) node.getDataChildByName("id"); + assertTrue(id.isAugmenting()); + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/AugmentToExtensionTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/AugmentToExtensionTest.java new file mode 100644 index 0000000000..b76583b3c5 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/AugmentToExtensionTest.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.opendaylight.yangtools.yang.stmt.test.StmtTestUtils; +import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException; +import java.net.URISyntaxException; +import java.util.Set; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.UsesNode; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; +import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; + +public class AugmentToExtensionTest { + private Set modules; + + @Test(expected = SomeModifiersUnresolvedException.class) + public void testIncorrectPath() throws URISyntaxException, SourceException, ReactorException { + modules = TestUtils.loadModules(getClass().getResource("/augment-to-extension-test/incorrect-path").toURI()); + + } + + @Test + public void testCorrectPathIntoUnsupportedTarget() throws URISyntaxException, SourceException, ReactorException { + + try { + modules = TestUtils.loadModules(getClass().getResource( + "/augment-to-extension-test/correct-path-into-unsupported-target").toURI()); + } catch (Exception e) { + StmtTestUtils.log(e, " "); + } + + Module devicesModule = TestUtils.findModule(modules, "augment-module"); + + ContainerSchemaNode devicesContainer = (ContainerSchemaNode) devicesModule.getDataChildByName("my-container"); + Set uses = devicesContainer.getUses(); + + boolean augmentationIsInContainer = false; + for (UsesNode usesNode : uses) { + Set augmentations = usesNode.getAugmentations(); + for (AugmentationSchema augmentationSchema : augmentations) { + augmentationIsInContainer = true; + } + } + + assertFalse(augmentationIsInContainer); + } + + @Test + public void testCorrectAugment() throws URISyntaxException, SourceException, ReactorException { + modules = TestUtils.loadModules(getClass().getResource("/augment-to-extension-test/correct-augment").toURI()); + + Module devicesModule = TestUtils.findModule(modules, "augment-module"); + + ContainerSchemaNode devicesContainer = (ContainerSchemaNode) devicesModule.getDataChildByName("my-container"); + Set uses = devicesContainer.getUses(); + + boolean augmentationIsInContainer = false; + for (UsesNode usesNode : uses) { + Set augmentations = usesNode.getAugmentations(); + for (AugmentationSchema augmentationSchema : augmentations) { + augmentationIsInContainer = true; + } + } + + assertTrue(augmentationIsInContainer); + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/AugmentationSchemaBuilderImplTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/AugmentationSchemaBuilderImplTest.java new file mode 100644 index 0000000000..a386516284 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/AugmentationSchemaBuilderImplTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import com.google.common.base.Optional; +import com.google.common.collect.Iterables; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.parser.builder.impl.AugmentationSchemaBuilderImpl; + +public class AugmentationSchemaBuilderImplTest { + + private AugmentationSchemaBuilderImpl augmentSchemaBuilderImpl; + private AugmentationSchemaBuilderImpl augmentSchemaBuilderImpl2; + private AugmentationSchemaBuilderImpl augmentSchemaBuilderImpl3; + private AugmentationSchemaBuilderImpl augmentSchemaBuilderImpl4; + private AugmentationSchema augmentSchema; + + @Before + public void init() { + augmentSchemaBuilderImpl = new AugmentationSchemaBuilderImpl("test-module", 10, "augment-test/rpc", SchemaPath.ROOT, 1); + augmentSchemaBuilderImpl2 = new AugmentationSchemaBuilderImpl("test-module", 10, "augment-test/rpc2", SchemaPath.ROOT, 1); + augmentSchemaBuilderImpl3 = augmentSchemaBuilderImpl; + augmentSchemaBuilderImpl4 = new AugmentationSchemaBuilderImpl("test-module", 10, null, SchemaPath.ROOT, 1); + augmentSchema = augmentSchemaBuilderImpl.build(); + } + + @Test + public void testgetPath() { + assertTrue(Iterables.isEmpty(augmentSchemaBuilderImpl.getPath().getPathFromRoot())); + } + + @Test + public void testEquals() { + assertFalse(augmentSchemaBuilderImpl.equals("test")); + assertFalse(augmentSchemaBuilderImpl.equals(null)); + assertTrue(augmentSchemaBuilderImpl.equals(augmentSchemaBuilderImpl3)); + assertFalse(augmentSchemaBuilderImpl4.equals(augmentSchemaBuilderImpl)); + assertFalse(augmentSchemaBuilderImpl.equals(augmentSchemaBuilderImpl2)); + } + + @Test + public void testGetOriginalDefinition() { + augmentSchema = augmentSchemaBuilderImpl.build(); + Optional origDefinition = augmentSchema.getOriginalDefinition(); + assertFalse(origDefinition.isPresent()); + } + + @Test + public void testGetUnknownSchemaNodes() { + assertTrue(Iterables.isEmpty(augmentSchema.getUnknownSchemaNodes())); + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug1412Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug1412Test.java new file mode 100644 index 0000000000..7d51847c02 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug1412Test.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.net.URI; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Set; +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.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; + +/** + * Test ANTLR4 grammar capability to parse description statement in unknown node. + * + * Note: Everything under unknown node is unknown node. + */ +public class Bug1412Test { + + @Test + public void test() throws Exception { + + Set modules = null; + + + modules = TestUtils.loadModules(getClass().getResource("/bugs/bug1412").toURI()); + + + Module bug1412 = TestUtils.findModule(modules, "bug1412"); + assertNotNull(bug1412); + + ContainerSchemaNode node = (ContainerSchemaNode) bug1412.getDataChildByName("node"); + List unknownNodes = node.getUnknownSchemaNodes(); + assertEquals(1, unknownNodes.size()); + UnknownSchemaNode action = unknownNodes.get(0); + + Date revision = new SimpleDateFormat("yyyy-MM-dd").parse("2014-07-25"); + QNameModule qm = QNameModule.create(URI.create("urn:test:bug1412"), revision); + QName expectedNodeType = QName.create("urn:test:bug1412:ext:definitions", "2014-07-25", "action"); + assertEquals(expectedNodeType, action.getNodeType()); + assertEquals("hello", action.getNodeParameter()); + QName expectedQName = QName.create(qm, "hello"); + assertEquals(expectedQName, action.getQName()); + + unknownNodes = action.getUnknownSchemaNodes(); + assertEquals(2, unknownNodes.size()); + //FIXME: do fix in UnknownEffectiveStatementImpl class & uncomment once nature of nodes within unknown stmts is + //FIXME: clarified (new statement parser approach) +// assertEquals(4, unknownNodes.size()); +// UnknownSchemaNode info = null; +// UnknownSchemaNode description = null; +// UnknownSchemaNode actionPoint = null; +// UnknownSchemaNode output = null; +// for (UnknownSchemaNode un : unknownNodes) { +// if ("info".equals(un.getNodeType().getLocalName())) { +// info = un; +// } else if ("description".equals(un.getNodeType().getLocalName())) { +// description = un; +// } else if ("actionpoint".equals(un.getNodeType().getLocalName())) { +// actionPoint = un; +// } else if ("output".equals(un.getNodeType().getLocalName())) { +// output = un; +// } +// } +// assertNotNull(info); +// assertNotNull(description); +// assertNotNull(actionPoint); +// assertNotNull(output); + +// expectedNodeType = QName.create("urn:test:bug1412:ext:definitions", "2014-07-25", "info"); +// assertEquals(expectedNodeType, info.getNodeType()); +// assertEquals("greeting", info.getNodeParameter()); +// +// expectedNodeType = QName.create(qm, "description"); +// assertEquals(expectedNodeType, description.getNodeType()); +// assertEquals("say greeting", description.getNodeParameter()); +// +// expectedNodeType = QName.create("urn:test:bug1412:ext:definitions", "2014-07-25", "actionpoint"); +// assertEquals(expectedNodeType, actionPoint.getNodeType()); +// assertEquals("entry", actionPoint.getNodeParameter()); +// +// expectedNodeType = QName.create(qm, "output"); +// assertEquals(expectedNodeType, output.getNodeType()); +// assertEquals("", output.getNodeParameter()); + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug1413Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug1413Test.java new file mode 100644 index 0000000000..31825cf1d8 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug1413Test.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.Set; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition; +import org.opendaylight.yangtools.yang.model.api.Module; + +/** + * Test ANTLR4 grammar capability to parse unknown node in extension argument + * declaration. + * + * Note: Everything under unknown node is unknown node. + */ +public class Bug1413Test { + + @Test + public void test() throws Exception { + Set modules = TestUtils.loadModules(getClass().getResource("/bugs/bug1413").toURI()); + Module bug1413 = TestUtils.findModule(modules, "bug1413"); + assertNotNull(bug1413); + + List extensions = bug1413.getExtensionSchemaNodes(); + assertEquals(1, extensions.size()); + + ExtensionDefinition info = extensions.get(0); + assertEquals("text", info.getArgument()); + assertTrue(info.isYinElement()); + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug2219Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug2219Test.java new file mode 100644 index 0000000000..dc812cfa68 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug2219Test.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.CopyUtils; +import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder; + +/** + * NPE is rised during use of CopyUtils.copy operation for IdentityrefTypeBuilder. + * NPE occours in private getData method in CopyUtils.java during QName.create. + * + * The reason for exception is the old.getQName returns null since IdentityrefTypeBuilder.getQName() + * by implementation returns always null. + * + */ +public class Bug2219Test { + + private ModuleBuilder moduleBuilder; + + @Before + public void init() { + moduleBuilder = new ModuleBuilder("test-module", "somePath"); + } + + @Test + public void testCopyIdentityrefTypeBuilder() { + final String typedefLocalName = "identity-ref-test-type"; + final QName typedefQname = QName.create(moduleBuilder.getNamespace(), moduleBuilder.getRevision(), typedefLocalName); + final SchemaPath typedefPath = SchemaPath.create(true, typedefQname); + final IdentityrefTypeBuilder typeBuilder = new IdentityrefTypeBuilder(moduleBuilder.getModuleName(), 12, + "base:parent-identity", typedefPath); + + final TypeDefinitionBuilder copy = CopyUtils.copy(typeBuilder, moduleBuilder, true); + assertNotNull(copy); + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug394Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug394Test.java new file mode 100644 index 0000000000..82c3165c50 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/Bug394Test.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.Set; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; + +/** + * Test antlr grammar capability to parse nested unknown nodes. + */ +public class Bug394Test { + + @Test + public void testParseList() throws Exception { + Set modules = TestUtils.loadModules(getClass().getResource("/bugs/bug394-retest").toURI()); + Module bug394 = TestUtils.findModule(modules, "bug394"); + assertNotNull(bug394); + Module bug394_ext = TestUtils.findModule(modules, "bug394-ext"); + assertNotNull(bug394_ext); + + ContainerSchemaNode logrecords = (ContainerSchemaNode) bug394.getDataChildByName("logrecords"); + assertNotNull(logrecords); + + List nodes = logrecords.getUnknownSchemaNodes(); + assertEquals(2, nodes.size()); + + List extensions = bug394_ext.getExtensionSchemaNodes(); + assertEquals(3, extensions.size()); + + assertTrue(extensions.contains(nodes.get(0).getExtensionDefinition())); + assertTrue(extensions.contains(nodes.get(1).getExtensionDefinition())); + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/GroupingTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/GroupingTest.java new file mode 100644 index 0000000000..4104c39976 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/GroupingTest.java @@ -0,0 +1,588 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +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.net.URI; +import java.net.URISyntaxException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; +import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; +import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.MustDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.UsesNode; +import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; + +public class GroupingTest { + private Set modules; + + @Before + public void init() throws URISyntaxException, ReactorException { + modules = TestUtils.loadModules(getClass().getResource("/model").toURI()); + assertEquals(3, modules.size()); + } + + @Test + public void testRefine() { + Module testModule = TestUtils.findModule(modules, "foo"); + ContainerSchemaNode peer = (ContainerSchemaNode) testModule.getDataChildByName("peer"); + ContainerSchemaNode destination = (ContainerSchemaNode) peer.getDataChildByName("destination"); + + Set usesNodes = destination.getUses(); + assertEquals(1, usesNodes.size()); + UsesNode usesNode = usesNodes.iterator().next(); + Map refines = usesNode.getRefines(); + assertEquals(4, refines.size()); + + LeafSchemaNode refineLeaf = null; + ContainerSchemaNode refineContainer = null; + ListSchemaNode refineList = null; + LeafSchemaNode refineInnerLeaf = null; + for (Map.Entry entry : refines.entrySet()) { + SchemaNode value = entry.getValue(); + if ("address".equals(value.getQName().getLocalName())) { + refineLeaf = (LeafSchemaNode) destination.getDataChildByName(value.getQName()); + } else if ("port".equals(value.getQName().getLocalName())) { + refineContainer = (ContainerSchemaNode) destination.getDataChildByName(value.getQName()); + } else if ("addresses".equals(value.getQName().getLocalName())) { + refineList = (ListSchemaNode) destination.getDataChildByName(value.getQName()); + } + } + + assertNotNull(refineList); + for (Map.Entry entry : refines.entrySet()) { + SchemaNode value = entry.getValue(); + if ("id".equals(value.getQName().getLocalName())) { + refineInnerLeaf = (LeafSchemaNode) refineList.getDataChildByName(value.getQName()); + } + } + + // leaf address + assertNotNull(refineLeaf); + assertEquals("IP address of target node", refineLeaf.getDescription()); + assertEquals("address reference added by refine", refineLeaf.getReference()); + assertFalse(refineLeaf.isConfiguration()); + assertFalse(refineLeaf.getConstraints().isMandatory()); + Set leafMustConstraints = refineLeaf.getConstraints().getMustConstraints(); + assertEquals(1, leafMustConstraints.size()); + MustDefinition leafMust = leafMustConstraints.iterator().next(); + assertEquals("ifType != 'ethernet' or (ifType = 'ethernet' and ifMTU = 1500)", leafMust.toString()); + assertEquals(1, refineLeaf.getUnknownSchemaNodes().size()); + + // container port + assertNotNull(refineContainer); + Set mustConstraints = refineContainer.getConstraints().getMustConstraints(); + assertTrue(mustConstraints.isEmpty()); + assertEquals("description of port defined by refine", refineContainer.getDescription()); + assertEquals("port reference added by refine", refineContainer.getReference()); + assertFalse(refineContainer.isConfiguration()); + assertTrue(refineContainer.isPresenceContainer()); + + // list addresses + assertEquals("description of addresses defined by refine", refineList.getDescription()); + assertEquals("addresses reference added by refine", refineList.getReference()); + assertFalse(refineList.isConfiguration()); + assertEquals(2, (int) refineList.getConstraints().getMinElements()); + assertEquals(Integer.MAX_VALUE, (int) refineList.getConstraints().getMaxElements()); + + // leaf id + assertNotNull(refineInnerLeaf); + assertEquals("id of address", refineInnerLeaf.getDescription()); + } + + @Test + public void testGrouping() { + Module testModule = TestUtils.findModule(modules, "baz"); + Set groupings = testModule.getGroupings(); + assertEquals(1, groupings.size()); + GroupingDefinition grouping = groupings.iterator().next(); + Collection children = grouping.getChildNodes(); + assertEquals(5, children.size()); + } + + @Test + public void testUses() { + // suffix _u = added by uses + // suffix _g = defined in grouping + + Module testModule = TestUtils.findModule(modules, "baz"); + + // get grouping + Set groupings = testModule.getGroupings(); + assertEquals(1, groupings.size()); + GroupingDefinition grouping = groupings.iterator().next(); + + testModule = TestUtils.findModule(modules, "foo"); + + // get node containing uses + ContainerSchemaNode peer = (ContainerSchemaNode) testModule.getDataChildByName("peer"); + ContainerSchemaNode destination = (ContainerSchemaNode) peer.getDataChildByName("destination"); + + // check uses + Set uses = destination.getUses(); + assertEquals(1, uses.size()); + + // check uses process + AnyXmlSchemaNode data_u = (AnyXmlSchemaNode) destination.getDataChildByName("data"); + assertNotNull(data_u); + assertTrue(data_u.isAddedByUses()); + + AnyXmlSchemaNode data_g = (AnyXmlSchemaNode) grouping.getDataChildByName("data"); + assertNotNull(data_g); + assertFalse(data_g.isAddedByUses()); + assertFalse(data_u.equals(data_g)); + assertEquals(data_g, SchemaNodeUtils.getRootOriginalIfPossible(data_u)); + + ChoiceSchemaNode how_u = (ChoiceSchemaNode) destination.getDataChildByName("how"); + assertNotNull(how_u); + TestUtils.checkIsAddedByUses(how_u, true); + assertEquals(2, how_u.getCases().size()); + + ChoiceSchemaNode how_g = (ChoiceSchemaNode) grouping.getDataChildByName("how"); + assertNotNull(how_g); + TestUtils.checkIsAddedByUses(how_g, false); + assertEquals(2, how_g.getCases().size()); + assertFalse(how_u.equals(how_g)); + assertEquals(how_g, SchemaNodeUtils.getRootOriginalIfPossible(how_u)); + + LeafSchemaNode address_u = (LeafSchemaNode) destination.getDataChildByName("address"); + assertNotNull(address_u); + assertEquals("1.2.3.4", address_u.getDefault()); + assertEquals("IP address of target node", address_u.getDescription()); + assertEquals("address reference added by refine", address_u.getReference()); + assertFalse(address_u.isConfiguration()); + assertTrue(address_u.isAddedByUses()); + assertFalse(address_u.getConstraints().isMandatory()); + + LeafSchemaNode address_g = (LeafSchemaNode) grouping.getDataChildByName("address"); + assertNotNull(address_g); + assertFalse(address_g.isAddedByUses()); + assertNull(address_g.getDefault()); + assertEquals("Target IP address", address_g.getDescription()); + assertNull(address_g.getReference()); + assertTrue(address_g.isConfiguration()); + assertFalse(address_u.equals(address_g)); + assertTrue(address_g.getConstraints().isMandatory()); + assertEquals(address_g, SchemaNodeUtils.getRootOriginalIfPossible(address_u)); + + ContainerSchemaNode port_u = (ContainerSchemaNode) destination.getDataChildByName("port"); + assertNotNull(port_u); + TestUtils.checkIsAddedByUses(port_u, true); + + ContainerSchemaNode port_g = (ContainerSchemaNode) grouping.getDataChildByName("port"); + assertNotNull(port_g); + TestUtils.checkIsAddedByUses(port_g, false); + assertFalse(port_u.equals(port_g)); + assertEquals(port_g, SchemaNodeUtils.getRootOriginalIfPossible(port_u)); + + ListSchemaNode addresses_u = (ListSchemaNode) destination.getDataChildByName("addresses"); + assertNotNull(addresses_u); + TestUtils.checkIsAddedByUses(addresses_u, true); + + ListSchemaNode addresses_g = (ListSchemaNode) grouping.getDataChildByName("addresses"); + assertNotNull(addresses_g); + TestUtils.checkIsAddedByUses(addresses_g, false); + assertFalse(addresses_u.equals(addresses_g)); + assertEquals(addresses_g, SchemaNodeUtils.getRootOriginalIfPossible(addresses_u)); + + // grouping defined by 'uses' + Set groupings_u = destination.getGroupings(); + assertEquals(1, groupings_u.size()); + GroupingDefinition grouping_u = groupings_u.iterator().next(); + TestUtils.checkIsAddedByUses(grouping_u, true); + + // grouping defined in 'grouping' node + Set groupings_g = grouping.getGroupings(); + assertEquals(1, groupings_g.size()); + GroupingDefinition grouping_g = groupings_g.iterator().next(); + TestUtils.checkIsAddedByUses(grouping_g, false); + assertFalse(grouping_u.equals(grouping_g)); + + List nodes_u = destination.getUnknownSchemaNodes(); + assertEquals(1, nodes_u.size()); + UnknownSchemaNode node_u = nodes_u.get(0); + assertTrue(node_u.isAddedByUses()); + + List nodes_g = grouping.getUnknownSchemaNodes(); + assertEquals(1, nodes_g.size()); + UnknownSchemaNode node_g = nodes_g.get(0); + assertFalse(node_g.isAddedByUses()); + assertFalse(node_u.equals(node_g)); + } + + @Test + public void testUsesUnderModule() { + // suffix _u = added by uses + // suffix _g = defined in grouping + + Module testModule = TestUtils.findModule(modules, "baz"); + + // get grouping + Set groupings = testModule.getGroupings(); + assertEquals(1, groupings.size()); + GroupingDefinition grouping = groupings.iterator().next(); + + // get node containing uses + Module foo = TestUtils.findModule(modules, "foo"); + + // check uses + Set uses = foo.getUses(); + assertEquals(1, uses.size()); + + // check uses process + AnyXmlSchemaNode data_u = (AnyXmlSchemaNode) foo.getDataChildByName("data"); + assertNotNull(data_u); + assertTrue(data_u.isAddedByUses()); + + AnyXmlSchemaNode data_g = (AnyXmlSchemaNode) grouping.getDataChildByName("data"); + assertNotNull(data_g); + assertFalse(data_g.isAddedByUses()); + assertFalse(data_u.equals(data_g)); + assertEquals(data_g, SchemaNodeUtils.getRootOriginalIfPossible(data_u)); + + ChoiceSchemaNode how_u = (ChoiceSchemaNode) foo.getDataChildByName("how"); + assertNotNull(how_u); + TestUtils.checkIsAddedByUses(how_u, true); + assertFalse(how_u.isAugmenting()); + Set cases_u = how_u.getCases(); + assertEquals(2, cases_u.size()); + ChoiceCaseNode interval = how_u.getCaseNodeByName("interval"); + assertFalse(interval.isAugmenting()); + LeafSchemaNode name = (LeafSchemaNode) interval.getDataChildByName("name"); + assertTrue(name.isAugmenting()); + LeafSchemaNode intervalLeaf = (LeafSchemaNode) interval.getDataChildByName("interval"); + assertFalse(intervalLeaf.isAugmenting()); + + ChoiceSchemaNode how_g = (ChoiceSchemaNode) grouping.getDataChildByName("how"); + assertNotNull(how_g); + TestUtils.checkIsAddedByUses(how_g, false); + assertFalse(how_u.equals(how_g)); + assertEquals(how_g, SchemaNodeUtils.getRootOriginalIfPossible(how_u)); + + LeafSchemaNode address_u = (LeafSchemaNode) foo.getDataChildByName("address"); + assertNotNull(address_u); + assertNull(address_u.getDefault()); + assertEquals("Target IP address", address_u.getDescription()); + assertNull(address_u.getReference()); + assertTrue(address_u.isConfiguration()); + assertTrue(address_u.isAddedByUses()); + + LeafSchemaNode address_g = (LeafSchemaNode) grouping.getDataChildByName("address"); + assertNotNull(address_g); + assertFalse(address_g.isAddedByUses()); + assertNull(address_g.getDefault()); + assertEquals("Target IP address", address_g.getDescription()); + assertNull(address_g.getReference()); + assertTrue(address_g.isConfiguration()); + assertFalse(address_u.equals(address_g)); + assertEquals(address_g, SchemaNodeUtils.getRootOriginalIfPossible(address_u)); + + ContainerSchemaNode port_u = (ContainerSchemaNode) foo.getDataChildByName("port"); + assertNotNull(port_u); + TestUtils.checkIsAddedByUses(port_u, true); + + ContainerSchemaNode port_g = (ContainerSchemaNode) grouping.getDataChildByName("port"); + assertNotNull(port_g); + TestUtils.checkIsAddedByUses(port_g, false); + assertFalse(port_u.equals(port_g)); + assertEquals(port_g, SchemaNodeUtils.getRootOriginalIfPossible(port_u)); + + ListSchemaNode addresses_u = (ListSchemaNode) foo.getDataChildByName("addresses"); + assertNotNull(addresses_u); + TestUtils.checkIsAddedByUses(addresses_u, true); + + ListSchemaNode addresses_g = (ListSchemaNode) grouping.getDataChildByName("addresses"); + assertNotNull(addresses_g); + TestUtils.checkIsAddedByUses(addresses_g, false); + assertFalse(addresses_u.equals(addresses_g)); + assertEquals(addresses_g, SchemaNodeUtils.getRootOriginalIfPossible(addresses_u)); + + // grouping defined by 'uses' + Set groupings_u = foo.getGroupings(); + assertEquals(1, groupings_u.size()); + GroupingDefinition grouping_u = groupings_u.iterator().next(); + TestUtils.checkIsAddedByUses(grouping_u, true); + + // grouping defined in 'grouping' node + Set groupings_g = grouping.getGroupings(); + assertEquals(1, groupings_g.size()); + GroupingDefinition grouping_g = groupings_g.iterator().next(); + TestUtils.checkIsAddedByUses(grouping_g, false); + assertFalse(grouping_u.equals(grouping_g)); + + List nodes_u = foo.getUnknownSchemaNodes(); + assertEquals(1, nodes_u.size()); + UnknownSchemaNode node_u = nodes_u.get(0); + assertTrue(node_u.isAddedByUses()); + + List nodes_g = grouping.getUnknownSchemaNodes(); + assertEquals(1, nodes_g.size()); + UnknownSchemaNode node_g = nodes_g.get(0); + assertFalse(node_g.isAddedByUses()); + assertFalse(node_u.equals(node_g)); + + UsesNode un = uses.iterator().next(); + Set usesAugments = un.getAugmentations(); + assertEquals(1, usesAugments.size()); + AugmentationSchema augment = usesAugments.iterator().next(); + assertEquals("inner augment", augment.getDescription()); + Collection children = augment.getChildNodes(); + assertEquals(1, children.size()); + DataSchemaNode leaf = children.iterator().next(); + assertTrue(leaf instanceof LeafSchemaNode); + assertEquals("name", leaf.getQName().getLocalName()); + } + + @Test + public void testCascadeUses() throws ReactorException, ParseException { + modules = TestUtils.loadModules(Collections.singletonList(getClass().getResourceAsStream( + "/grouping-test/cascade-uses.yang"))); + assertEquals(1, modules.size()); + + Module testModule = TestUtils.findModule(modules, "cascade-uses"); + Set groupings = testModule.getGroupings(); + + GroupingDefinition gu = null; + GroupingDefinition gv = null; + GroupingDefinition gx = null; + GroupingDefinition gy = null; + GroupingDefinition gz = null; + GroupingDefinition gzz = null; + for (GroupingDefinition gd : groupings) { + String name = gd.getQName().getLocalName(); + switch (name) { + case "grouping-U": + gu = gd; + break; + case "grouping-V": + gv = gd; + break; + case "grouping-X": + gx = gd; + break; + case "grouping-Y": + gy = gd; + break; + case "grouping-Z": + gz = gd; + break; + case "grouping-ZZ": + gzz = gd; + break; + } + } + assertNotNull(gu); + assertNotNull(gv); + assertNotNull(gx); + assertNotNull(gy); + assertNotNull(gz); + assertNotNull(gzz); + + URI expectedNS = URI.create("urn:grouping:cascade-uses"); + Date expectedRev = new SimpleDateFormat("yyyy-MM-dd").parse("2013-07-18"); + String expectedPref = "cu"; + SchemaPath expectedPath; + + // grouping-U + Collection childNodes = gu.getChildNodes(); + assertEquals(7, childNodes.size()); + + LeafSchemaNode leafGroupingU = (LeafSchemaNode) gu.getDataChildByName("leaf-grouping-U"); + assertNotNull(leafGroupingU); + assertFalse(leafGroupingU.isAddedByUses()); + assertFalse(SchemaNodeUtils.getOriginalIfPossible(leafGroupingU).isPresent()); + + for (DataSchemaNode childNode : childNodes) { + if (!(childNode.getQName().equals(leafGroupingU.getQName()))) { + TestUtils.checkIsAddedByUses(childNode, true); + } + } + + // grouping-V + childNodes = gv.getChildNodes(); + assertEquals(4, childNodes.size()); + LeafSchemaNode leafGroupingV = null; + ContainerSchemaNode containerGroupingV = null; + for (DataSchemaNode childNode : childNodes) { + if ("leaf-grouping-V".equals(childNode.getQName().getLocalName())) { + leafGroupingV = (LeafSchemaNode) childNode; + } else if ("container-grouping-V".equals(childNode.getQName().getLocalName())) { + containerGroupingV = (ContainerSchemaNode) childNode; + } else { + TestUtils.checkIsAddedByUses(childNode, true); + } + } + assertNotNull(leafGroupingV); + assertFalse(leafGroupingV.isAddedByUses()); + + // grouping-V/container-grouping-V + assertNotNull(containerGroupingV); + assertFalse(containerGroupingV.isAddedByUses()); + expectedPath = TestUtils.createPath(true, expectedNS, expectedRev, expectedPref, "grouping-V", + "container-grouping-V"); + assertEquals(expectedPath, containerGroupingV.getPath()); + childNodes = containerGroupingV.getChildNodes(); + assertEquals(2, childNodes.size()); + for (DataSchemaNode childNode : childNodes) { + TestUtils.checkIsAddedByUses(childNode, true); + } + + // grouping-V/container-grouping-V/leaf-grouping-X + LeafSchemaNode leafXinContainerV = (LeafSchemaNode) containerGroupingV.getDataChildByName("leaf-grouping-X"); + assertNotNull(leafXinContainerV); + expectedPath = TestUtils.createPath(true, expectedNS, expectedRev, expectedPref, "grouping-V", + "container-grouping-V", "leaf-grouping-X"); + assertEquals(expectedPath, leafXinContainerV.getPath()); + // grouping-V/container-grouping-V/leaf-grouping-Y + LeafSchemaNode leafYinContainerV = (LeafSchemaNode) containerGroupingV.getDataChildByName("leaf-grouping-Y"); + assertNotNull(leafYinContainerV); + expectedPath = TestUtils.createPath(true, expectedNS, expectedRev, expectedPref, "grouping-V", + "container-grouping-V", "leaf-grouping-Y"); + assertEquals(expectedPath, leafYinContainerV.getPath()); + + // grouping-X + childNodes = gx.getChildNodes(); + assertEquals(2, childNodes.size()); + + // grouping-X/leaf-grouping-X + LeafSchemaNode leafXinGX = (LeafSchemaNode) gx.getDataChildByName("leaf-grouping-X"); + assertNotNull(leafXinGX); + assertFalse(leafXinGX.isAddedByUses()); + expectedPath = TestUtils.createPath(true, expectedNS, expectedRev, expectedPref, "grouping-X", + "leaf-grouping-X"); + assertEquals(expectedPath, leafXinGX.getPath()); + + // grouping-X/leaf-grouping-Y + LeafSchemaNode leafYinGX = (LeafSchemaNode) gx.getDataChildByName("leaf-grouping-Y"); + assertNotNull(leafYinGX); + assertTrue(leafYinGX.isAddedByUses()); + expectedPath = TestUtils.createPath(true, expectedNS, expectedRev, expectedPref, "grouping-X", + "leaf-grouping-Y"); + assertEquals(expectedPath, leafYinGX.getPath()); + + // grouping-Y + childNodes = gy.getChildNodes(); + assertEquals(1, childNodes.size()); + + // grouping-Y/leaf-grouping-Y + LeafSchemaNode leafYinGY = (LeafSchemaNode) gy.getDataChildByName("leaf-grouping-Y"); + assertNotNull(leafYinGY); + assertFalse(leafYinGY.isAddedByUses()); + expectedPath = TestUtils.createPath(true, expectedNS, expectedRev, expectedPref, "grouping-Y", + "leaf-grouping-Y"); + assertEquals(expectedPath, leafYinGY.getPath()); + + // grouping-Z + childNodes = gz.getChildNodes(); + assertEquals(1, childNodes.size()); + + // grouping-Z/leaf-grouping-Z + LeafSchemaNode leafZinGZ = (LeafSchemaNode) gz.getDataChildByName("leaf-grouping-Z"); + assertNotNull(leafZinGZ); + assertFalse(leafZinGZ.isAddedByUses()); + expectedPath = TestUtils.createPath(true, expectedNS, expectedRev, expectedPref, "grouping-Z", + "leaf-grouping-Z"); + assertEquals(expectedPath, leafZinGZ.getPath()); + + // grouping-ZZ + childNodes = gzz.getChildNodes(); + assertEquals(1, childNodes.size()); + + // grouping-ZZ/leaf-grouping-ZZ + LeafSchemaNode leafZZinGZZ = (LeafSchemaNode) gzz.getDataChildByName("leaf-grouping-ZZ"); + assertNotNull(leafZZinGZZ); + assertFalse(leafZZinGZZ.isAddedByUses()); + expectedPath = TestUtils.createPath(true, expectedNS, expectedRev, expectedPref, "grouping-ZZ", + "leaf-grouping-ZZ"); + assertEquals(expectedPath, leafZZinGZZ.getPath()); + + // TEST getOriginal from grouping-U + assertEquals(gv.getDataChildByName("leaf-grouping-V"), + SchemaNodeUtils.getRootOriginalIfPossible(gu.getDataChildByName("leaf-grouping-V"))); + containerGroupingV = (ContainerSchemaNode) gu.getDataChildByName("container-grouping-V"); + assertEquals(gv.getDataChildByName("container-grouping-V"), + SchemaNodeUtils.getRootOriginalIfPossible(containerGroupingV)); + assertEquals(gx.getDataChildByName("leaf-grouping-X"), + SchemaNodeUtils.getRootOriginalIfPossible(containerGroupingV.getDataChildByName("leaf-grouping-X"))); + assertEquals(gy.getDataChildByName("leaf-grouping-Y"), + SchemaNodeUtils.getRootOriginalIfPossible(containerGroupingV.getDataChildByName("leaf-grouping-Y"))); + + assertEquals(gz.getDataChildByName("leaf-grouping-Z"), + SchemaNodeUtils.getRootOriginalIfPossible(gu.getDataChildByName("leaf-grouping-Z"))); + assertEquals(gzz.getDataChildByName("leaf-grouping-ZZ"), + SchemaNodeUtils.getRootOriginalIfPossible(gu.getDataChildByName("leaf-grouping-ZZ"))); + + // TEST getOriginal from grouping-V + assertEquals(gz.getDataChildByName("leaf-grouping-Z"), + SchemaNodeUtils.getRootOriginalIfPossible(gv.getDataChildByName("leaf-grouping-Z"))); + assertEquals(gzz.getDataChildByName("leaf-grouping-ZZ"), + SchemaNodeUtils.getRootOriginalIfPossible(gv.getDataChildByName("leaf-grouping-ZZ"))); + + // TEST getOriginal from grouping-X + assertEquals(gy.getDataChildByName("leaf-grouping-Y"), + SchemaNodeUtils.getRootOriginalIfPossible(gx.getDataChildByName("leaf-grouping-Y"))); + } + + @Test + public void testAddedByUsesLeafTypeQName() throws URISyntaxException, ReactorException { + + Set loadModules = TestUtils.loadModules(getClass().getResource("/added-by-uses-leaf-test").toURI()); + + assertEquals(2, loadModules.size()); + + Module foo = null; + Module imp = null; + for (Module module : loadModules) { + if (module.getName().equals("foo")) { + foo = module; + } + if (module.getName().equals("import-module")) { + imp = module; + } + } + + LeafSchemaNode leaf = (LeafSchemaNode) ((ContainerSchemaNode) foo.getDataChildByName("my-container")) + .getDataChildByName("my-leaf"); + + TypeDefinition impType = null; + Set> typeDefinitions = imp.getTypeDefinitions(); + for (TypeDefinition typeDefinition : typeDefinitions) { + if (typeDefinition.getQName().getLocalName().equals("imp-type")) { + impType = typeDefinition; + break; + } + } + + assertEquals(leaf.getType().getQName(), impType.getQName()); + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/ListKeysTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/ListKeysTest.java new file mode 100644 index 0000000000..3073f3dfac --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/ListKeysTest.java @@ -0,0 +1,116 @@ +/** + * 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.stmt.retest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import java.io.IOException; +import java.net.URISyntaxException; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; +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; + +public class ListKeysTest { + + @Test + public void correctListKeysTest() throws ReactorException { + + final YangStatementSourceImpl yangFile = new YangStatementSourceImpl( + "/list-keys-test/correct-list-keys-test.yang", false); + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, yangFile); + + final EffectiveSchemaContext result = reactor.buildEffective(); + assertNotNull(result); + } + + @Test + public void incorrectListKeysTest1() throws IOException, YangSyntaxErrorException, URISyntaxException { + + final YangStatementSourceImpl yangFile = new YangStatementSourceImpl( + "/list-keys-test/incorrect-list-keys-test.yang", false); + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, yangFile); + + try { + reactor.buildEffective(); + fail("effective build should fail due to list instead of leaf referenced in list key"); + } catch (Exception e) { + assertEquals(IllegalArgumentException.class, e.getClass()); + assertTrue(e.getMessage().startsWith("Key 'test1_key1 test1_key2' misses node 'test1_key2'")); + } + } + + @Test + public void incorrectListKeysTest2() throws IOException, YangSyntaxErrorException, URISyntaxException { + + final YangStatementSourceImpl yangFile = new YangStatementSourceImpl( + "/list-keys-test/incorrect-list-keys-test2.yang", false); + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, yangFile); + + try { + reactor.buildEffective(); + fail("effective build should fail due to missing leaf referenced in list key"); + } catch (Exception e) { + assertEquals(IllegalArgumentException.class, e.getClass()); + assertTrue(e.getMessage().startsWith("Key 'test1_key1 test1_key2' misses node 'test1_key2'")); + } + } + + @Test + public void incorrectListKeysTest3() throws IOException, YangSyntaxErrorException, URISyntaxException { + + final YangStatementSourceImpl yangFile = new YangStatementSourceImpl( + "/list-keys-test/incorrect-list-keys-test3.yang", false); + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, yangFile); + + try { + reactor.buildEffective(); + fail("effective build should fail due to list instead of leaf in grouping referenced in list key"); + } catch (Exception e) { + assertEquals(IllegalArgumentException.class, e.getClass()); + assertTrue(e.getMessage().startsWith("Key 'grp_list' misses node 'grp_list'")); + } + } + + @Test + public void incorrectListKeysTest4() throws IOException, YangSyntaxErrorException, URISyntaxException { + + final YangStatementSourceImpl yangFile = new YangStatementSourceImpl( + "/list-keys-test/incorrect-list-keys-test4.yang", false); + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, yangFile); + + try { + reactor.buildEffective(); + fail("effective build should fail due to list instead of leaf in grouping augmented to list referenced in list key"); + } catch (Exception e) { + assertEquals(IllegalArgumentException.class, e.getClass()); + assertTrue(e.getMessage().startsWith("Key 'grp_leaf' misses node 'grp_leaf'")); + } + } + + 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/retest/ModuleIdentifierTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/ModuleIdentifierTest.java new file mode 100644 index 0000000000..36311dd9bb --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/ModuleIdentifierTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import com.google.common.base.Optional; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Date; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; +import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl; + +public class ModuleIdentifierTest { + + private ModuleIdentifier moduleIdentifier; + private ModuleIdentifier moduleIdentifier2; + private ModuleIdentifier moduleIdentifier3; + private ModuleIdentifier moduleIdentifier4; + private ModuleIdentifier moduleIdentifier5; + + @Before + public void init() throws URISyntaxException { + Optional uri = Optional.of(new URI("testURI")); + Optional uri2 = Optional.of(new URI("testURI2")); + Optional revision = Optional.absent(); + moduleIdentifier = new ModuleIdentifierImpl("test-modulue", uri, revision); + moduleIdentifier2 = new ModuleIdentifierImpl("test-modulue2", uri, revision); + moduleIdentifier3 = moduleIdentifier; + moduleIdentifier4 = new ModuleIdentifierImpl("test-modulue", uri2, revision); + moduleIdentifier5 = new ModuleIdentifierImpl("test-modulue", uri, revision); + } + + @Test + public void testGetQNameModule() { + assertEquals(null, moduleIdentifier.getQNameModule().getRevision()); + } + + @Test + public void testGetRevision() { + assertEquals(null, moduleIdentifier.getRevision()); + } + + @Test + public void testGetName() { + assertEquals("test-modulue", moduleIdentifier.getName()); + } + + @Test + public void getNamespace() throws URISyntaxException { + assertEquals(new URI("testURI"), moduleIdentifier.getNamespace()); + } + + @Test + public void toStringTest() { + assertTrue(moduleIdentifier.toString().contains("ModuleIdentifier")); + } + + @Test + public void testHashCode() { + assertFalse(moduleIdentifier.hashCode() == moduleIdentifier2.hashCode()); + } + + @Test + public void testEquals() { + assertTrue(moduleIdentifier.equals(moduleIdentifier3)); + assertFalse(moduleIdentifier.equals(null)); + assertFalse(moduleIdentifier.equals("test")); + assertFalse(moduleIdentifier.equals(moduleIdentifier2)); + assertFalse(moduleIdentifier.equals(moduleIdentifier4)); + assertTrue(moduleIdentifier.equals(moduleIdentifier5)); + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/OrderingTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/OrderingTest.java new file mode 100644 index 0000000000..7fa2df4e0b --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/OrderingTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.net.URISyntaxException; +import java.util.Collection; +import java.util.Set; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; +import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; + +public class OrderingTest { + + @Test + public void testOrderingTypedef() throws URISyntaxException, + SourceException, ReactorException { + Set modules = TestUtils.loadModules(getClass().getResource( + "/model").toURI()); + Module bar = TestUtils.findModule(modules, "bar"); + Set> typedefs = bar.getTypeDefinitions(); + String[] expectedOrder = new String[] { "int32-ext1", "int32-ext2", + "string-ext1", "string-ext2", "string-ext3", "string-ext4", + "invalid-string-pattern", "multiple-pattern-string", + "my-decimal-type", "my-union", "my-union-ext", "nested-union2" }; + String[] actualOrder = new String[typedefs.size()]; + + int i = 0; + for (TypeDefinition type : typedefs) { + actualOrder[i] = type.getQName().getLocalName(); + i++; + } + assertArrayEquals(expectedOrder, actualOrder); + } + + @Test + public void testOrderingChildNodes() throws URISyntaxException, + SourceException, ReactorException { + Set modules = TestUtils.loadModules(getClass().getResource( + "/model").toURI()); + Module foo = TestUtils.findModule(modules, "foo"); + AugmentationSchema augment1 = null; + for (AugmentationSchema as : foo.getAugmentations()) { + if (as.getChildNodes().size() == 5) { + augment1 = as; + break; + } + } + assertNotNull(augment1); + + String[] expectedOrder = new String[] { "ds0ChannelNumber", + "interface-id", "my-type", "schemas", "odl" }; + String[] actualOrder = new String[expectedOrder.length]; + + int i = 0; + for (DataSchemaNode augmentChild : augment1.getChildNodes()) { + actualOrder[i] = augmentChild.getQName().getLocalName(); + i++; + } + + assertArrayEquals(expectedOrder, actualOrder); + } + + @Test + public void testOrderingNestedChildNodes1() throws URISyntaxException, + SourceException, ReactorException { + Set modules = TestUtils.loadModules(getClass().getResource( + "/model").toURI()); + Module foo = TestUtils.findModule(modules, "foo"); + + Collection childNodes = foo.getChildNodes(); + String[] expectedOrder = new String[] { "int32-leaf", "string-leaf", + "invalid-pattern-string-leaf", + "invalid-direct-string-pattern-def-leaf", + "multiple-pattern-string-leaf", + "multiple-pattern-direct-string-def-leaf", "length-leaf", + "decimal-leaf", "decimal-leaf2", "ext", "union-leaf", + "custom-union-leaf", "transfer", "datas", "mycont", "data", + "how", "address", "port", "addresses", "peer", "id", "foo-id", + "sub-ext", "sub-transfer", "sub-datas" }; + String[] actualOrder = new String[childNodes.size()]; + + int i = 0; + for (DataSchemaNode child : childNodes) { + actualOrder[i] = child.getQName().getLocalName(); + i++; + } + assertArrayEquals(expectedOrder, actualOrder); + } + + @Test + public void testOrderingNestedChildNodes2() throws URISyntaxException, + SourceException, ReactorException { + Set modules = TestUtils.loadModules(getClass().getResource( + "/model").toURI()); + Module baz = TestUtils.findModule(modules, "baz"); + Set groupings = baz.getGroupings(); + assertEquals(1, groupings.size()); + GroupingDefinition target = groupings.iterator().next(); + + Collection childNodes = target.getChildNodes(); + String[] expectedOrder = new String[] { "data", "how", "address", + "port", "addresses" }; + String[] actualOrder = new String[childNodes.size()]; + + int i = 0; + for (DataSchemaNode child : childNodes) { + actualOrder[i] = child.getQName().getLocalName(); + i++; + } + assertArrayEquals(expectedOrder, actualOrder); + } + + @Test + public void testOrderingNestedChildNodes3() throws Exception { + Module baz = TestUtils.loadModule(getClass().getResourceAsStream( + "/ordering/foo.yang")); + ContainerSchemaNode x = (ContainerSchemaNode) baz + .getDataChildByName("x"); + Collection childNodes = x.getChildNodes(); + + String[] expectedOrder = new String[] { "x15", "x10", "x5", "x1", "a5", + "a1", "x2", "b5", "b1", "x3", "ax15", "ax5" }; + String[] actualOrder = new String[childNodes.size()]; + + int i = 0; + for (DataSchemaNode child : childNodes) { + actualOrder[i] = child.getQName().getLocalName(); + i++; + } + assertArrayEquals(expectedOrder, actualOrder); + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/ParsingExtensionValueTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/ParsingExtensionValueTest.java new file mode 100644 index 0000000000..f2db310aa4 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/ParsingExtensionValueTest.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.api.Module; + +/** + * Test for testing of extensions and their arguments. + * + * @author Lukas Sedlak + */ +public class ParsingExtensionValueTest { + + private Set modules; + + @Before + public void init() throws Exception { + //TODO: change test or create new module in order to respect new statement parser validations + DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + + try { + modules = TestUtils.loadModules(getClass().getResource("/extensions").toURI()); + } catch (Exception e) { + assertEquals(IllegalArgumentException.class, e.getClass()); + assertTrue(e.getMessage().startsWith("ext:id is not a YANG statement or use of extension")); + } + } + + @Test + public void parsingExtensionArgsTest() { + + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/SameQNamesInChoiceTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/SameQNamesInChoiceTest.java new file mode 100644 index 0000000000..33e8dcb44e --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/SameQNamesInChoiceTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertNotNull; + +import java.io.File; +import java.net.URI; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser; +import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; +import org.opendaylight.yangtools.yang.parser.util.YangParseException; + +public class SameQNamesInChoiceTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testSameQNameInChoice() throws Exception { + thrown.expect(YangParseException.class); + thrown.expectMessage("Choice has two nodes case with same qnames"); + + SchemaContext context; + File yangFile = new File(getClass().getResource("/bugs/qnameDuplicity/two-same-node-in-choice/two-same-nodes-in-choice-case.yang").toURI()); + File dependenciesDir = new File(getClass().getResource("/bugs/qnameDuplicity/two-same-node-in-choice").toURI()); + YangContextParser parser = new YangParserImpl(); + context = parser.parseFile(yangFile, dependenciesDir); + + Module testModule = context.findModuleByNamespace(URI.create("urn:test:two:same-nodes-in-choice-case")).iterator().next(); + assertNotNull(testModule); + } + + + @Test + public void testAugmentedNodeIntoChoiceCase() throws Exception { + thrown.expect(YangParseException.class); + thrown.expectMessage("Choice has two nodes case with same qnames"); + + SchemaContext context; + File yangFile = new File(getClass().getResource("/bugs/qnameDuplicity/augment/two-cases.yang").toURI()); + File dependenciesDir = new File(getClass().getResource("/bugs/qnameDuplicity/augment").toURI()); + YangContextParser parser = new YangParserImpl(); + context = parser.parseFile(yangFile, dependenciesDir); + + Module testModule = context.findModuleByNamespace(URI.create("urn:test:two:cases")).iterator().next(); + assertNotNull(testModule); + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/SchemaContextTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/SchemaContextTest.java new file mode 100644 index 0000000000..c42bbb95f5 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/SchemaContextTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import org.junit.Before; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; +//import org.opendaylight.yangtools.yang.parser.impl.SchemaContextImpl; + +import java.net.URI; +import java.net.URISyntaxException; +import java.text.ParseException; +import java.util.Collections; +import java.util.Date; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.doReturn; + +public class SchemaContextTest { + @Mock + private Module oldModule; + + @Mock + private Module newModule; + + private Map sources; + + private URI ns; + private Date oldDate; + private Date newDate; + + @Before + public void setUp() throws ParseException, URISyntaxException { + MockitoAnnotations.initMocks(this); + + ns = new URI("http://abc"); + oldDate = SimpleDateFormatUtil.getRevisionFormat().parse("2014-07-20"); + newDate = SimpleDateFormatUtil.getRevisionFormat().parse("2014-07-22"); + + doReturn("abc").when(oldModule).getName(); + doReturn(oldDate).when(oldModule).getRevision(); + doReturn(ns).when(oldModule).getNamespace(); + doReturn("abc").when(newModule).getName(); + doReturn(newDate).when(newModule).getRevision(); + doReturn(ns).when(newModule).getNamespace(); + + sources = Collections.emptyMap(); + } + +// @Test +// public void testModuleOrdering() { +// SchemaContext sc; +// Module m; +// +// sc = SchemaContextImpl(ImmutableSet.of(newModule, oldModule), sources); +// m = sc.findModuleByName("abc", null); +// assertEquals(newDate, m.getRevision()); +// m = sc.findModuleByNamespaceAndRevision(ns, null); +// assertEquals(newDate, m.getRevision()); +// +// sc = new SchemaContextImpl(ImmutableSet.of(oldModule, newModule), sources); +// m = sc.findModuleByName("abc", null); +// assertEquals(newDate, m.getRevision()); +// m = sc.findModuleByNamespaceAndRevision(ns, null); +// assertEquals(newDate, m.getRevision()); +// } + + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/TestUtils.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/TestUtils.java new file mode 100644 index 0000000000..21326d67c8 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/TestUtils.java @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertEquals; +import java.io.File; +import java.io.InputStream; +import java.net.URI; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Set; +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.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.ModuleImport; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +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; + +final class TestUtils { + + private TestUtils() { + } + + public static Set loadModules(final URI resourceDirectory) throws SourceException, ReactorException { + final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + File[] files = new File(resourceDirectory).listFiles(); + + for (File file : files) { + addSources(reactor, new YangStatementSourceImpl(file.getPath(), true)); + } + + EffectiveSchemaContext ctx = reactor.buildEffective(); + return ctx.getModules(); + } + + public static Set loadModules(final List streams) throws SourceException, ReactorException { + final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + for (InputStream inputStream : streams) { + addSources(reactor, new YangStatementSourceImpl(inputStream)); + } + + EffectiveSchemaContext ctx = reactor.buildEffective(); + return ctx.getModules(); + } + + public static Module loadModule(final InputStream stream) throws SourceException, ReactorException { + final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, new YangStatementSourceImpl(stream)); + EffectiveSchemaContext ctx = reactor.buildEffective(); + return ctx.getModules().iterator().next(); + } + + public static Module findModule(final Set modules, final String moduleName) { + Module result = null; + for (Module module : modules) { + if (module.getName().equals(moduleName)) { + result = module; + break; + } + } + return result; + } + + public static ModuleImport findImport(final Set imports, final String prefix) { + ModuleImport result = null; + for (ModuleImport moduleImport : imports) { + if (moduleImport.getPrefix().equals(prefix)) { + result = moduleImport; + break; + } + } + return result; + } + + public static TypeDefinition findTypedef(final Set> typedefs, final String name) { + TypeDefinition result = null; + for (TypeDefinition td : typedefs) { + if (td.getQName().getLocalName().equals(name)) { + result = td; + break; + } + } + return result; + } + + public static SchemaPath createPath(final boolean absolute, final URI namespace, final Date revision, + final String prefix, final String... names) { + List path = new ArrayList<>(); + for (String name : names) { + path.add(QName.create(namespace, revision, name)); + } + return SchemaPath.create(path, absolute); + } + + public static Date createDate(final String date) { + Date result; + final DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + try { + result = simpleDateFormat.parse(date); + } catch (ParseException e) { + result = null; + } + return result; + } + + /** + * Test if node has augmenting flag set to expected value. In case this is DataNodeContainer/ChoiceNode, check its + * child nodes/case nodes too. + * + * @param node + * node to check + * @param expected + * expected value + */ + public static void checkIsAugmenting(final DataSchemaNode node, final boolean expected) { + assertEquals(expected, node.isAugmenting()); + if (node instanceof DataNodeContainer) { + for (DataSchemaNode child : ((DataNodeContainer) node).getChildNodes()) { + checkIsAugmenting(child, expected); + } + } else if (node instanceof ChoiceSchemaNode) { + for (ChoiceCaseNode caseNode : ((ChoiceSchemaNode) node).getCases()) { + checkIsAugmenting(caseNode, expected); + } + } + } + + /** + * Check if node has addedByUses flag set to expected value. In case this is DataNodeContainer/ChoiceNode, check its + * child nodes/case nodes too. + * + * @param node + * node to check + * @param expected + * expected value + */ + public static void checkIsAddedByUses(final DataSchemaNode node, final boolean expected) { + assertEquals(expected, node.isAddedByUses()); + if (node instanceof DataNodeContainer) { + for (DataSchemaNode child : ((DataNodeContainer) node).getChildNodes()) { + checkIsAddedByUses(child, expected); + } + } else if (node instanceof ChoiceSchemaNode) { + for (ChoiceCaseNode caseNode : ((ChoiceSchemaNode) node).getCases()) { + checkIsAddedByUses(caseNode, expected); + } + } + } + + public static void checkIsAddedByUses(final GroupingDefinition node, final boolean expected) { + assertEquals(expected, node.isAddedByUses()); + for (DataSchemaNode child : ((DataNodeContainer) node).getChildNodes()) { + checkIsAddedByUses(child, expected); + } + } + + public static List findModules(final Set modules, final String moduleName) { + List result = new ArrayList<>(); + for (Module module : modules) { + if (module.getName().equals(moduleName)) { + result.add(module); + } + } + return result; + } + + private static 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/retest/TwoRevisionsTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/TwoRevisionsTest.java new file mode 100644 index 0000000000..7e6c419926 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/TwoRevisionsTest.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertEquals; + +import java.util.Set; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.api.Module; + +public class TwoRevisionsTest { + + @Test + public void testTwoRevisions() throws Exception { + Set modules = TestUtils.loadModules(getClass().getResource("/ietf").toURI()); + //FIXME: following assert needs module revisions .equals() solution first + assertEquals(2, TestUtils.findModules(modules, "network-topology").size()); + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/TypesResolutionTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/TypesResolutionTest.java new file mode 100644 index 0000000000..44a3bbcf4c --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/TypesResolutionTest.java @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +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.junit.Assert.fail; + +import java.io.File; +import java.math.BigInteger; +import java.net.URI; +import java.util.List; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit; +import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair; +import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; +import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; +import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition; +import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser; +import org.opendaylight.yangtools.yang.model.util.BitsType; +import org.opendaylight.yangtools.yang.model.util.EnumerationType; +import org.opendaylight.yangtools.yang.model.util.ExtendedType; +import org.opendaylight.yangtools.yang.model.util.IdentityrefType; +import org.opendaylight.yangtools.yang.model.util.InstanceIdentifierType; +import org.opendaylight.yangtools.yang.model.util.UnionType; +import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; +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; + +public class TypesResolutionTest { + private Set testedModules; + + @Before + public void init() throws Exception { + File yangFile = new File(getClass().getResource("/types/custom-types-test@2012-4-4.yang").toURI()); + File dependenciesDir = new File(getClass().getResource("/ietf").toURI()); + YangContextParser parser = new YangParserImpl(); + testedModules = parser.parseFile(yangFile, dependenciesDir).getModules(); + assertEquals(4, testedModules.size()); + } + + @Test + public void testIPVersion() { + Module tested = TestUtils.findModule(testedModules, "ietf-inet-types"); + Set> typedefs = tested.getTypeDefinitions(); + assertEquals(14, typedefs.size()); + + TypeDefinition type = TestUtils.findTypedef(typedefs, "ip-version"); + assertTrue(type.getDescription().contains("This value represents the version of the IP protocol.")); + assertTrue(type.getReference().contains("RFC 2460: Internet Protocol, Version 6 (IPv6) Specification")); + + EnumerationType enumType = (EnumerationType) type.getBaseType(); + List values = enumType.getValues(); + assertEquals(3, values.size()); + + EnumPair value0 = values.get(0); + assertEquals("unknown", value0.getName()); + assertEquals(0, (int) value0.getValue()); + assertEquals("An unknown or unspecified version of the Internet protocol.", value0.getDescription()); + + EnumPair value1 = values.get(1); + assertEquals("ipv4", value1.getName()); + assertEquals(1, (int) value1.getValue()); + assertEquals("The IPv4 protocol as defined in RFC 791.", value1.getDescription()); + + EnumPair value2 = values.get(2); + assertEquals("ipv6", value2.getName()); + assertEquals(2, (int) value2.getValue()); + assertEquals("The IPv6 protocol as defined in RFC 2460.", value2.getDescription()); + } + + @Test + public void testEnumeration() { + Module tested = TestUtils.findModule(testedModules, "custom-types-test"); + Set> typedefs = tested.getTypeDefinitions(); + + TypeDefinition type = TestUtils.findTypedef(typedefs, "ip-version"); + EnumerationType enumType = (EnumerationType) type.getBaseType(); + List values = enumType.getValues(); + assertEquals(4, values.size()); + + EnumPair value0 = values.get(0); + assertEquals("unknown", value0.getName()); + assertEquals(0, (int) value0.getValue()); + assertEquals("An unknown or unspecified version of the Internet protocol.", value0.getDescription()); + + EnumPair value1 = values.get(1); + assertEquals("ipv4", value1.getName()); + assertEquals(19, (int) value1.getValue()); + assertEquals("The IPv4 protocol as defined in RFC 791.", value1.getDescription()); + + EnumPair value2 = values.get(2); + assertEquals("ipv6", value2.getName()); + assertEquals(7, (int) value2.getValue()); + assertEquals("The IPv6 protocol as defined in RFC 2460.", value2.getDescription()); + + EnumPair value3 = values.get(3); + assertEquals("default", value3.getName()); + assertEquals(20, (int) value3.getValue()); + assertEquals("default ip", value3.getDescription()); + } + + @Test + public void testIpAddress() { + Module tested = TestUtils.findModule(testedModules, "ietf-inet-types"); + Set> typedefs = tested.getTypeDefinitions(); + TypeDefinition type = TestUtils.findTypedef(typedefs, "ip-address"); + UnionType baseType = (UnionType) type.getBaseType(); + List> unionTypes = baseType.getTypes(); + + ExtendedType ipv4 = (ExtendedType) unionTypes.get(0); + assertTrue(ipv4.getBaseType() instanceof StringTypeDefinition); + String expectedPattern = "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}" + + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])" + "(%[\\p{N}\\p{L}]+)?$"; + assertEquals(expectedPattern, ipv4.getPatternConstraints().get(0).getRegularExpression()); + + ExtendedType ipv6 = (ExtendedType) unionTypes.get(1); + assertTrue(ipv6.getBaseType() instanceof StringTypeDefinition); + List ipv6Patterns = ipv6.getPatternConstraints(); + expectedPattern = "^((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}" + + "((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|" + "(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}" + + "(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))" + "(%[\\p{N}\\p{L}]+)?$"; + assertEquals(expectedPattern, ipv6Patterns.get(0).getRegularExpression()); + + expectedPattern = "^(([^:]+:){6}(([^:]+:[^:]+)|(.*\\..*)))|" + "((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)" + + "(%.+)?$"; + assertEquals(expectedPattern, ipv6Patterns.get(1).getRegularExpression()); + } + + @Test + public void testDomainName() { + Module tested = TestUtils.findModule(testedModules, "ietf-inet-types"); + Set> typedefs = tested.getTypeDefinitions(); + ExtendedType type = (ExtendedType) TestUtils.findTypedef(typedefs, "domain-name"); + assertTrue(type.getBaseType() instanceof StringTypeDefinition); + List patterns = type.getPatternConstraints(); + assertEquals(1, patterns.size()); + String expectedPattern = "^((([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.)*" + + "([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.?)" + "|\\.$"; + assertEquals(expectedPattern, patterns.get(0).getRegularExpression()); + + List lengths = type.getLengthConstraints(); + assertEquals(1, lengths.size()); + LengthConstraint length = type.getLengthConstraints().get(0); + assertEquals(BigInteger.ONE, length.getMin()); + assertEquals(BigInteger.valueOf(253), length.getMax()); + } + + @Test + public void testInstanceIdentifier1() { + Module tested = TestUtils.findModule(testedModules, "custom-types-test"); + LeafSchemaNode leaf = (LeafSchemaNode) tested.getDataChildByName("inst-id-leaf1"); + InstanceIdentifierType leafType = (InstanceIdentifierType) leaf.getType(); + assertFalse(leafType.requireInstance()); + assertEquals(1, leaf.getUnknownSchemaNodes().size()); + } + + @Test + public void testInstanceIdentifier2() { + Module tested = TestUtils.findModule(testedModules, "custom-types-test"); + LeafSchemaNode leaf = (LeafSchemaNode) tested.getDataChildByName("inst-id-leaf2"); + InstanceIdentifierType leafType = (InstanceIdentifierType) leaf.getType(); + assertTrue(leafType.requireInstance()); + } + + @Test + public void testIdentity() { + Module tested = TestUtils.findModule(testedModules, "custom-types-test"); + Set identities = tested.getIdentities(); + assertEquals(5, identities.size()); + IdentitySchemaNode cryptoAlg = null; + IdentitySchemaNode cryptoBase = null; + IdentitySchemaNode cryptoId = null; + for (IdentitySchemaNode id : identities) { + if (id.getQName().getLocalName().equals("crypto-alg")) { + cryptoAlg = id; + } else if ("crypto-base".equals(id.getQName().getLocalName())) { + cryptoBase = id; + } else if ("crypto-id".equals(id.getQName().getLocalName())) { + cryptoId = id; + } + } + assertNotNull(cryptoAlg); + IdentitySchemaNode baseIdentity = cryptoAlg.getBaseIdentity(); + assertEquals("crypto-base", baseIdentity.getQName().getLocalName()); + assertTrue(cryptoAlg.getDerivedIdentities().isEmpty()); + assertNull(baseIdentity.getBaseIdentity()); + + assertNotNull(cryptoBase); + assertNull(cryptoBase.getBaseIdentity()); + assertEquals(3, cryptoBase.getDerivedIdentities().size()); + + assertNotNull(cryptoId); + assertEquals(1, cryptoId.getUnknownSchemaNodes().size()); + } + + @Test + public void testBitsType1() { + Module tested = TestUtils.findModule(testedModules, "custom-types-test"); + LeafSchemaNode leaf = (LeafSchemaNode) tested.getDataChildByName("mybits"); + BitsType leafType = (BitsType) leaf.getType(); + List bits = leafType.getBits(); + assertEquals(3, bits.size()); + + Bit bit1 = bits.get(0); + assertEquals("disable-nagle", bit1.getName()); + assertEquals(0L, (long) bit1.getPosition()); + + Bit bit2 = bits.get(1); + assertEquals("auto-sense-speed", bit2.getName()); + assertEquals(1L, (long) bit2.getPosition()); + + Bit bit3 = bits.get(2); + assertEquals("10-Mb-only", bit3.getName()); + assertEquals(2L, (long) bit3.getPosition()); + } + + @Test + public void testBitsType2() { + Module tested = TestUtils.findModule(testedModules, "custom-types-test"); + Set> typedefs = tested.getTypeDefinitions(); + TypeDefinition testedType = TestUtils.findTypedef(typedefs, "access-operations-type"); + + BitsType bitsType = (BitsType) testedType.getBaseType(); + List bits = bitsType.getBits(); + assertEquals(5, bits.size()); + + Bit bit0 = bits.get(0); + assertEquals(0L, (long) bit0.getPosition()); + + Bit bit1 = bits.get(1); + assertEquals(500L, (long) bit1.getPosition()); + + Bit bit2 = bits.get(2); + assertEquals(501L, (long) bit2.getPosition()); + + Bit bit3 = bits.get(3); + assertEquals(365L, (long) bit3.getPosition()); + + Bit bit4 = bits.get(4); + assertEquals(502L, (long) bit4.getPosition()); + } + + @Test + public void testIanaTimezones() { + Module tested = TestUtils.findModule(testedModules, "iana-timezones"); + Set> typedefs = tested.getTypeDefinitions(); + TypeDefinition testedType = TestUtils.findTypedef(typedefs, "iana-timezone"); + + String expectedDesc = "A timezone location as defined by the IANA timezone"; + assertTrue(testedType.getDescription().contains(expectedDesc)); + assertTrue(testedType.getReference().isEmpty()); + assertEquals(Status.CURRENT, testedType.getStatus()); + + QName testedTypeQName = testedType.getQName(); + assertEquals(URI.create("urn:ietf:params:xml:ns:yang:iana-timezones"), testedTypeQName.getNamespace()); + assertEquals(TestUtils.createDate("2012-07-09"), testedTypeQName.getRevision()); + assertEquals("iana-timezone", testedTypeQName.getLocalName()); + + EnumerationType enumType = (EnumerationType) testedType.getBaseType(); + List values = enumType.getValues(); + assertEquals(415, values.size()); // 0-414 + + EnumPair enum168 = values.get(168); + assertEquals("America/Danmarkshavn", enum168.getName()); + assertEquals(168, (int) enum168.getValue()); + assertEquals("east coast, north of Scoresbysund", enum168.getDescription()); + + EnumPair enum374 = values.get(374); + assertEquals("America/Indiana/Winamac", enum374.getName()); + assertEquals(374, (int) enum374.getValue()); + assertEquals("Eastern Time - Indiana - Pulaski County", enum374.getDescription()); + } + + @Test + public void testObjectId128() { + Module tested = TestUtils.findModule(testedModules, "ietf-yang-types"); + Set> typedefs = tested.getTypeDefinitions(); + ExtendedType testedType = (ExtendedType) TestUtils.findTypedef(typedefs, "object-identifier-128"); + + List patterns = testedType.getPatternConstraints(); + assertEquals(1, patterns.size()); + PatternConstraint pattern = patterns.get(0); + assertEquals("^\\d*(\\.\\d*){1,127}$", pattern.getRegularExpression()); + + QName testedTypeQName = testedType.getQName(); + assertEquals(URI.create("urn:ietf:params:xml:ns:yang:ietf-yang-types"), testedTypeQName.getNamespace()); + assertEquals(TestUtils.createDate("2010-09-24"), testedTypeQName.getRevision()); + assertEquals("object-identifier-128", testedTypeQName.getLocalName()); + + ExtendedType testedTypeBase = (ExtendedType) testedType.getBaseType(); + patterns = testedTypeBase.getPatternConstraints(); + assertEquals(1, patterns.size()); + + pattern = patterns.get(0); + assertEquals("^(([0-1](\\.[1-3]?[0-9]))|(2\\.(0|([1-9]\\d*))))(\\.(0|([1-9]\\d*)))*$", + pattern.getRegularExpression()); + + QName testedTypeBaseQName = testedTypeBase.getQName(); + assertEquals(URI.create("urn:ietf:params:xml:ns:yang:ietf-yang-types"), testedTypeBaseQName.getNamespace()); + assertEquals(TestUtils.createDate("2010-09-24"), testedTypeBaseQName.getRevision()); + assertEquals("object-identifier", testedTypeBaseQName.getLocalName()); + } + + @Test + public void testIdentityref() { + Module tested = TestUtils.findModule(testedModules, "custom-types-test"); + Set> typedefs = tested.getTypeDefinitions(); + TypeDefinition testedType = TestUtils.findTypedef(typedefs, "service-type-ref"); + IdentityrefType baseType = (IdentityrefType) testedType.getBaseType(); + QName identity = baseType.getIdentity().getQName(); + assertEquals(URI.create("urn:custom.types.demo"), identity.getNamespace()); + assertEquals(TestUtils.createDate("2012-04-16"), identity.getRevision()); + assertEquals("service-type", identity.getLocalName()); + + LeafSchemaNode type = (LeafSchemaNode) tested.getDataChildByName("type"); + assertNotNull(type); + } + + @Test + public void testUnionWithExt() throws ReactorException { + + final YangStatementSourceImpl yangFile1 = new YangStatementSourceImpl("/types/union-with-ext/extdef.yang", + false); + final YangStatementSourceImpl yangFile2 = new YangStatementSourceImpl("/types/union-with-ext/unionbug.yang", + false); + final YangStatementSourceImpl yangFile3 = new YangStatementSourceImpl("/ietf/ietf-inet-types@2010-09-24.yang", + false); + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, yangFile1, yangFile2, yangFile3); + + final EffectiveSchemaContext result = reactor.buildEffective(); + assertNotNull(result); + } + + @Test + public void testUnionWithBits() throws ReactorException { + + final YangStatementSourceImpl yangFile = new YangStatementSourceImpl( + "/types/union-with-bits/union-bits-model.yang", false); + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, yangFile); + + final EffectiveSchemaContext result = reactor.buildEffective(); + assertNotNull(result); + } + + @Test + public void testUnionInList() { + final YangStatementSourceImpl yangFile = new YangStatementSourceImpl( + "/types/union-in-list/unioninlisttest.yang", false); + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, yangFile); + + try { + final EffectiveSchemaContext result = reactor.buildEffective(); + fail("effective build should fail due to union in list; this is not allowed"); + } catch (Exception e) { + assertEquals(IllegalArgumentException.class, e.getClass()); + assertTrue(e.getMessage().startsWith("union is not a YANG statement or use of extension")); + } + } + + 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/retest/UsesAugmentTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/UsesAugmentTest.java new file mode 100644 index 0000000000..69b3a1a5bd --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/UsesAugmentTest.java @@ -0,0 +1,650 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import com.google.common.collect.Lists; +import java.io.FileNotFoundException; +import java.net.URI; +import java.net.URISyntaxException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.util.BaseTypes; +import org.opendaylight.yangtools.yang.model.util.BooleanType; +import org.opendaylight.yangtools.yang.model.util.ExtendedType; +import org.opendaylight.yangtools.yang.model.util.Uint32; +import org.opendaylight.yangtools.yang.model.util.Uint8; +import org.opendaylight.yangtools.yang.model.util.UnionType; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; +import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; + +public class UsesAugmentTest { + private static final URI UG_NS = URI.create("urn:opendaylight:params:xml:ns:yang:uses-grouping"); + private static final URI GD_NS = URI.create("urn:opendaylight:params:xml:ns:yang:grouping-definitions"); + private Date UG_REV; + private Date GD_REV; + + private Set modules; + + @Before + public void init() throws FileNotFoundException, ParseException { + DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + UG_REV = simpleDateFormat.parse("2013-07-30"); + GD_REV = simpleDateFormat.parse("2013-09-04"); + } + + /** + * Structure of testing model: + * + * notification pcreq + * |-- leaf version (U) + * |-- leaf type (U) + * |-- list requests + * |-- |-- container rp + * |-- |-- |-- leaf priority (U) + * |-- |-- |-- container box (U) + * |-- |-- |-- |-- container order (A) + * |-- |-- |-- |-- |-- leaf delete (U) + * |-- |-- |-- |-- |-- |-- leaf setup (U) + * |-- |-- |-- leaf processing-rule (U) + * |-- |-- |-- leaf ignore (U) + * |-- |-- path-key-expansion + * |-- |-- |-- container path-key + * |-- |-- |-- |-- list path-keys (U) + * |-- |-- |-- |-- |-- leaf version (U) + * |-- |-- |-- |-- |-- leaf type (U) + * |-- |-- |-- |-- |-- leaf processing-rule (U) + * |-- |-- |-- |-- |-- leaf ignore (U) + * |-- |-- container segment-computation + * |-- |-- |-- container p2p + * |-- |-- |-- |-- container endpoints + * |-- |-- |-- |-- |-- leaf processing-rule (U) + * |-- |-- |-- |-- |-- leaf ignore (U) + * |-- |-- |-- |-- |-- container box (U) + * |-- |-- |-- |-- |-- choice address-family (U) + * |-- |-- |-- |-- |-- |-- case ipv4 + * |-- |-- |-- |-- |-- |-- |-- leaf source-ipv4-address + * |-- |-- |-- |-- |-- |-- case ipv6 + * |-- |-- |-- |-- |-- |-- |-- leaf source-ipv6-address + * |-- |-- |-- |-- container reported-route + * |-- |-- |-- |-- |-- container bandwidth + * |-- |-- |-- |-- |-- list subobjects(U) + * |-- |-- |-- |-- |-- leaf processing-rule (U) + * |-- |-- |-- |-- |-- leaf ignore (U) + * |-- |-- |-- |-- container bandwidth (U) + * |-- |-- |-- |-- |-- container bandwidth (U) + * |-- |-- |-- |-- |-- leaf processing-rule (U) + * |-- |-- |-- |-- |-- leaf ignore (U) + * |-- list svec + * |-- |-- list metric + * |-- |-- |-- leaf metric-type (U) + * |-- |-- |-- container box (U) + * |-- |-- |-- leaf processing-rule (U) + * |-- |-- |-- leaf ignore (U) + * |-- |-- leaf link-diverse (U) + * |-- |-- leaf processing-rule (U) + * |-- |-- leaf ignore (U) + * + * U = added by uses A = added by augment + */ + @Test + public void testAugmentInUses() throws Exception { + modules = TestUtils.loadModules(getClass().getResource("/grouping-test").toURI()); + Module testModule = TestUtils.findModule(modules, "uses-grouping"); + + LinkedList path = new LinkedList<>(); + + // * notification pcreq + Set notifications = testModule.getNotifications(); + assertEquals(1, notifications.size()); + NotificationDefinition pcreq = notifications.iterator().next(); + assertNotNull(pcreq); + QName expectedQName = QName.create(UG_NS, UG_REV, "pcreq"); + path.offer(expectedQName); + SchemaPath expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, pcreq.getPath()); + Collection childNodes = pcreq.getChildNodes(); + assertEquals(4, childNodes.size()); + // * |-- leaf version + LeafSchemaNode version = (LeafSchemaNode) pcreq.getDataChildByName("version"); + assertNotNull(version); + expectedQName = QName.create(UG_NS, UG_REV, "version"); + path.offer(expectedQName); + expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, version.getPath()); + expectedQName = QName.create(GD_NS, GD_REV, "protocol-version"); + path.offer(expectedQName); + expectedPath = SchemaPath.create(Lists.newArrayList(expectedQName), true); + assertEquals(expectedPath, version.getType().getPath()); + assertEquals(Uint8.getInstance(), version.getType().getBaseType()); + assertTrue(version.isAddedByUses()); + // * |-- leaf type + LeafSchemaNode type = (LeafSchemaNode) pcreq.getDataChildByName("type"); + assertNotNull(type); + expectedQName = QName.create(UG_NS, UG_REV, "type"); + assertTrue(type.isAddedByUses()); + path.pollLast(); + path.pollLast(); + path.offer(expectedQName); + expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, type.getPath()); + expectedQName = QName.create(GD_NS, GD_REV, "int-ext"); + path.offer(expectedQName); + expectedPath = SchemaPath.create(Lists.newArrayList(expectedQName), true); + assertEquals(expectedPath, type.getType().getPath()); + UnionType union = (UnionType)type.getType().getBaseType(); + assertEquals(SchemaPath.create(true, BaseTypes.constructQName("union")), union.getPath()); + assertEquals(2, union.getTypes().size()); + // * |-- list requests + ListSchemaNode requests = (ListSchemaNode) pcreq.getDataChildByName("requests"); + assertNotNull(requests); + expectedQName = QName.create(UG_NS, UG_REV, "requests"); + assertEquals(expectedQName, requests.getQName()); + path.pollLast(); + path.pollLast(); + path.offer(expectedQName); + expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, requests.getPath()); + assertFalse(requests.isAddedByUses()); + childNodes = requests.getChildNodes(); + assertEquals(3, childNodes.size()); + // * |-- |-- container rp + ContainerSchemaNode rp = (ContainerSchemaNode) requests.getDataChildByName("rp"); + assertNotNull(rp); + expectedQName = QName.create(UG_NS, UG_REV, "rp"); + path.offer(expectedQName); + expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, rp.getPath()); + assertFalse(rp.isAddedByUses()); + childNodes = rp.getChildNodes(); + assertEquals(4, childNodes.size()); + // * |-- |-- |-- leaf processing-rule + LeafSchemaNode processingRule = (LeafSchemaNode) rp.getDataChildByName("processing-rule"); + assertNotNull(processingRule); + expectedQName = QName.create(UG_NS, UG_REV, "processing-rule"); + assertEquals(expectedQName, processingRule.getQName()); + path.offer(expectedQName); + expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, processingRule.getPath()); + assertEquals(BooleanType.getInstance(), processingRule.getType()); + assertTrue(processingRule.isAddedByUses()); + // * |-- |-- |-- leaf ignore + LeafSchemaNode ignore = (LeafSchemaNode) rp.getDataChildByName("ignore"); + assertNotNull(ignore); + expectedQName = QName.create(UG_NS, UG_REV, "ignore"); + assertEquals(expectedQName, ignore.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, ignore.getPath()); + assertEquals(BooleanType.getInstance(), ignore.getType()); + assertTrue(ignore.isAddedByUses()); + // * |-- |-- |-- leaf priority + LeafSchemaNode priority = (LeafSchemaNode) rp.getDataChildByName("priority"); + assertNotNull(priority); + expectedQName = QName.create(UG_NS, UG_REV, "priority"); + assertEquals(expectedQName, priority.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, priority.getPath()); + expectedQName = QName.create(UG_NS, UG_REV, "uint8"); + path.offer(expectedQName); + expectedPath = SchemaPath.create(path, true); + // TODO + //assertEquals(expectedPath, priority.getType().getPath()); + assertEquals(Uint8.getInstance(), priority.getType().getBaseType()); + assertTrue(priority.isAddedByUses()); + // * |-- |-- |-- container box + ContainerSchemaNode box = (ContainerSchemaNode) rp.getDataChildByName("box"); + assertNotNull(box); + expectedQName = QName.create(UG_NS, UG_REV, "box"); + assertEquals(expectedQName, box.getQName()); + path.pollLast(); + path.pollLast(); + path.offer(expectedQName); + expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, box.getPath()); + assertTrue(box.isAddedByUses()); + // * |-- |-- |-- |-- container order + ContainerSchemaNode order = (ContainerSchemaNode) box.getDataChildByName("order"); + assertNotNull(order); + expectedQName = QName.create(UG_NS, UG_REV, "order"); + assertEquals(expectedQName, order.getQName()); + path.offer(expectedQName); + expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, order.getPath()); + assertTrue(order.isAddedByUses()); + assertTrue(order.isAugmenting()); + assertEquals(2, order.getChildNodes().size()); + // * |-- |-- |-- |-- |-- leaf delete + LeafSchemaNode delete = (LeafSchemaNode) order.getDataChildByName("delete"); + assertNotNull(delete); + expectedQName = QName.create(UG_NS, UG_REV, "delete"); + assertEquals(expectedQName, delete.getQName()); + path.offer(expectedQName); + expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, delete.getPath()); + assertEquals(Uint32.getInstance(), delete.getType()); + assertTrue(delete.isAddedByUses()); + // * |-- |-- |-- |-- |-- leaf setup + LeafSchemaNode setup = (LeafSchemaNode) order.getDataChildByName("setup"); + assertNotNull(setup); + expectedQName = QName.create(UG_NS, UG_REV, "setup"); + assertEquals(expectedQName, setup.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, setup.getPath()); + assertEquals(Uint32.getInstance(), setup.getType()); + assertTrue(setup.isAddedByUses()); + // * |-- |-- path-key-expansion + ContainerSchemaNode pke = (ContainerSchemaNode) requests.getDataChildByName("path-key-expansion"); + assertNotNull(pke); + expectedQName = QName.create(UG_NS, UG_REV, "path-key-expansion"); + assertEquals(expectedQName, pke.getQName()); + path.pollLast(); + path.pollLast(); + path.pollLast(); + path.pollLast(); + path.offer(expectedQName); + expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, pke.getPath()); + assertFalse(pke.isAddedByUses()); + // * |-- |-- |-- path-key + ContainerSchemaNode pathKey = (ContainerSchemaNode) pke.getDataChildByName("path-key"); + assertNotNull(pathKey); + expectedQName = QName.create(UG_NS, UG_REV, "path-key"); + assertEquals(expectedQName, pathKey.getQName()); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, pathKey.getPath()); + assertFalse(pathKey.isAddedByUses()); + assertEquals(3, pathKey.getChildNodes().size()); + // * |-- |-- |-- |-- leaf processing-rule + processingRule = (LeafSchemaNode) pathKey.getDataChildByName("processing-rule"); + assertNotNull(processingRule); + expectedQName = QName.create(UG_NS, UG_REV, "processing-rule"); + assertEquals(expectedQName, processingRule.getQName()); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, processingRule.getPath()); + assertEquals(BooleanType.getInstance(), processingRule.getType()); + assertTrue(processingRule.isAddedByUses()); + // * |-- |-- |-- |-- leaf ignore + ignore = (LeafSchemaNode) pathKey.getDataChildByName("ignore"); + assertNotNull(ignore); + expectedQName = QName.create(UG_NS, UG_REV, "ignore"); + assertEquals(expectedQName, ignore.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, ignore.getPath()); + assertEquals(BooleanType.getInstance(), ignore.getType()); + assertTrue(ignore.isAddedByUses()); + // * |-- |-- |-- |-- list path-keys + ListSchemaNode pathKeys = (ListSchemaNode) pathKey.getDataChildByName("path-keys"); + assertNotNull(pathKeys); + expectedQName = QName.create(UG_NS, UG_REV, "path-keys"); + assertEquals(expectedQName, pathKeys.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, pathKeys.getPath()); + assertTrue(pathKeys.isAddedByUses()); + childNodes = pathKeys.getChildNodes(); + assertEquals(2, childNodes.size()); + // * |-- |-- |-- |-- |-- leaf version + version = (LeafSchemaNode) pathKeys.getDataChildByName("version"); + assertNotNull(version); + expectedQName = QName.create(UG_NS, UG_REV, "version"); + assertEquals(expectedQName, version.getQName()); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, version.getPath()); + assertTrue(version.getType() instanceof ExtendedType); + assertEquals(Uint8.getInstance(), version.getType().getBaseType()); + assertTrue(version.isAddedByUses()); + assertTrue(version.isAugmenting()); + // * |-- |-- |-- |-- |-- leaf type + type = (LeafSchemaNode) pathKeys.getDataChildByName("type"); + assertNotNull(type); + expectedQName = QName.create(UG_NS, UG_REV, "type"); + assertEquals(expectedQName, type.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, type.getPath()); + assertTrue(type.getType() instanceof ExtendedType); + assertTrue(type.isAddedByUses()); + assertTrue(type.isAugmenting()); + // * |-- |-- container segment-computation + ContainerSchemaNode sc = (ContainerSchemaNode) requests.getDataChildByName("segment-computation"); + assertNotNull(sc); + expectedQName = QName.create(UG_NS, UG_REV, "segment-computation"); + assertEquals(expectedQName, sc.getQName()); + path.pollLast(); + path.pollLast(); + path.pollLast(); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, sc.getPath()); + assertFalse(sc.isAddedByUses()); + // * |-- |-- |-- container p2p + ContainerSchemaNode p2p = (ContainerSchemaNode) sc.getDataChildByName("p2p"); + assertNotNull(p2p); + expectedQName = QName.create(UG_NS, UG_REV, "p2p"); + assertEquals(expectedQName, p2p.getQName()); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, p2p.getPath()); + assertFalse(p2p.isAddedByUses()); + // * |-- |-- |-- |-- container endpoints + ContainerSchemaNode endpoints = (ContainerSchemaNode) p2p.getDataChildByName("endpoints"); + assertNotNull(endpoints); + expectedQName = QName.create(UG_NS, UG_REV, "endpoints"); + assertEquals(expectedQName, endpoints.getQName()); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, endpoints.getPath()); + assertFalse(endpoints.isAddedByUses()); + // * |-- |-- |-- |-- |-- leaf processing-rule + processingRule = (LeafSchemaNode) endpoints.getDataChildByName("processing-rule"); + assertNotNull(processingRule); + expectedQName = QName.create(UG_NS, UG_REV, "processing-rule"); + assertEquals(expectedQName, processingRule.getQName()); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, processingRule.getPath()); + assertEquals(BooleanType.getInstance(), processingRule.getType()); + assertTrue(processingRule.isAddedByUses()); + // * |-- |-- |-- |-- |-- leaf ignore + ignore = (LeafSchemaNode) endpoints.getDataChildByName("ignore"); + assertNotNull(ignore); + expectedQName = QName.create(UG_NS, UG_REV, "ignore"); + assertEquals(expectedQName, ignore.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, ignore.getPath()); + assertEquals(BooleanType.getInstance(), ignore.getType()); + assertTrue(ignore.isAddedByUses()); + // * |-- |-- |-- |-- |-- container box + box = (ContainerSchemaNode) endpoints.getDataChildByName("box"); + assertNotNull(box); + expectedQName = QName.create(UG_NS, UG_REV, "box"); + assertEquals(expectedQName, box.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, box.getPath()); + assertTrue(box.isAddedByUses()); + // * |-- |-- |-- |-- |-- choice address-family + ChoiceSchemaNode af = (ChoiceSchemaNode) endpoints.getDataChildByName("address-family"); + assertNotNull(af); + expectedQName = QName.create(UG_NS, UG_REV, "address-family"); + assertEquals(expectedQName, af.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, af.getPath()); + assertTrue(af.isAddedByUses()); + // * |-- |-- |-- |-- container reported-route + ContainerSchemaNode reportedRoute = (ContainerSchemaNode) p2p.getDataChildByName("reported-route"); + assertNotNull(reportedRoute); + expectedQName = QName.create(UG_NS, UG_REV, "reported-route"); + assertEquals(expectedQName, reportedRoute.getQName()); + path.pollLast(); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, reportedRoute.getPath()); + assertFalse(reportedRoute.isAddedByUses()); + // * |-- |-- |-- |-- |-- leaf processing-rule + processingRule = (LeafSchemaNode) reportedRoute.getDataChildByName("processing-rule"); + assertNotNull(processingRule); + expectedQName = QName.create(UG_NS, UG_REV, "processing-rule"); + assertEquals(expectedQName, processingRule.getQName()); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, processingRule.getPath()); + assertEquals(BooleanType.getInstance(), processingRule.getType()); + assertTrue(processingRule.isAddedByUses()); + // * |-- |-- |-- |-- |-- leaf ignore + ignore = (LeafSchemaNode) reportedRoute.getDataChildByName("ignore"); + assertNotNull(ignore); + expectedQName = QName.create(UG_NS, UG_REV, "ignore"); + assertEquals(expectedQName, ignore.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, ignore.getPath()); + assertEquals(BooleanType.getInstance(), ignore.getType()); + assertTrue(ignore.isAddedByUses()); + // * |-- |-- |-- |-- |-- list subobjects + ListSchemaNode subobjects = (ListSchemaNode) reportedRoute.getDataChildByName("subobjects"); + assertNotNull(subobjects); + expectedQName = QName.create(UG_NS, UG_REV, "subobjects"); + assertEquals(expectedQName, subobjects.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, subobjects.getPath()); + assertTrue(subobjects.isAddedByUses()); + // * |-- |-- |-- |-- |-- container bandwidth + ContainerSchemaNode bandwidth = (ContainerSchemaNode) reportedRoute.getDataChildByName("bandwidth"); + assertNotNull(bandwidth); + expectedQName = QName.create(UG_NS, UG_REV, "bandwidth"); + assertEquals(expectedQName, bandwidth.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, bandwidth.getPath()); + assertFalse(bandwidth.isAddedByUses()); + // * |-- |-- |-- |-- container bandwidth + bandwidth = (ContainerSchemaNode) p2p.getDataChildByName("bandwidth"); + assertNotNull(bandwidth); + expectedQName = QName.create(UG_NS, UG_REV, "bandwidth"); + assertEquals(expectedQName, bandwidth.getQName()); + path.pollLast(); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, bandwidth.getPath()); + assertTrue(bandwidth.isAddedByUses()); + // * |-- |-- |-- |-- |-- leaf processing-rule + processingRule = (LeafSchemaNode) bandwidth.getDataChildByName("processing-rule"); + assertNotNull(processingRule); + expectedQName = QName.create(UG_NS, UG_REV, "processing-rule"); + assertEquals(expectedQName, processingRule.getQName()); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, processingRule.getPath()); + assertEquals(BooleanType.getInstance(), processingRule.getType()); + assertTrue(processingRule.isAddedByUses()); + // * |-- |-- |-- |-- |-- leaf ignore + ignore = (LeafSchemaNode) bandwidth.getDataChildByName("ignore"); + assertNotNull(ignore); + expectedQName = QName.create(UG_NS, UG_REV, "ignore"); + assertEquals(expectedQName, ignore.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, ignore.getPath()); + assertEquals(BooleanType.getInstance(), ignore.getType()); + assertTrue(ignore.isAddedByUses()); + // * |-- |-- |-- |-- |-- container bandwidth + ContainerSchemaNode bandwidthInner = (ContainerSchemaNode) bandwidth.getDataChildByName("bandwidth"); + assertNotNull(bandwidthInner); + expectedQName = QName.create(UG_NS, UG_REV, "bandwidth"); + assertEquals(expectedQName, bandwidth.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, bandwidthInner.getPath()); + assertTrue(bandwidthInner.isAddedByUses()); + // * |-- list svec + ListSchemaNode svec = (ListSchemaNode) pcreq.getDataChildByName("svec"); + assertNotNull(svec); + expectedQName = QName.create(UG_NS, UG_REV, "svec"); + assertEquals(expectedQName, svec.getQName()); + path.pollLast(); + path.pollLast(); + path.pollLast(); + path.pollLast(); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, svec.getPath()); + assertFalse(svec.isAddedByUses()); + // * |-- |-- leaf link-diverse + LeafSchemaNode linkDiverse = (LeafSchemaNode) svec.getDataChildByName("link-diverse"); + assertNotNull(linkDiverse); + expectedQName = QName.create(UG_NS, UG_REV, "link-diverse"); + assertEquals(expectedQName, linkDiverse.getQName()); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, linkDiverse.getPath()); + assertEquals(BooleanType.getInstance(), linkDiverse.getType()); + assertTrue(linkDiverse.isAddedByUses()); + // * |-- |-- leaf processing-rule + processingRule = (LeafSchemaNode) svec.getDataChildByName("processing-rule"); + assertNotNull(processingRule); + expectedQName = QName.create(UG_NS, UG_REV, "processing-rule"); + assertEquals(expectedQName, processingRule.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, processingRule.getPath()); + assertEquals(BooleanType.getInstance(), processingRule.getType()); + assertTrue(processingRule.isAddedByUses()); + // * |-- |-- leaf ignore + ignore = (LeafSchemaNode) svec.getDataChildByName("ignore"); + assertNotNull(ignore); + expectedQName = QName.create(UG_NS, UG_REV, "ignore"); + assertEquals(expectedQName, ignore.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, ignore.getPath()); + assertEquals(BooleanType.getInstance(), ignore.getType()); + assertTrue(ignore.isAddedByUses()); + // * |-- |-- list metric + ListSchemaNode metric = (ListSchemaNode) svec.getDataChildByName("metric"); + assertNotNull(metric); + expectedQName = QName.create(UG_NS, UG_REV, "metric"); + assertEquals(expectedQName, metric.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, metric.getPath()); + assertFalse(metric.isAddedByUses()); + // * |-- |-- |-- leaf metric-type + LeafSchemaNode metricType = (LeafSchemaNode) metric.getDataChildByName("metric-type"); + assertNotNull(metricType); + expectedQName = QName.create(UG_NS, UG_REV, "metric-type"); + assertEquals(expectedQName, metricType.getQName()); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, metricType.getPath()); + assertEquals(Uint8.getInstance(), metricType.getType()); + assertTrue(metricType.isAddedByUses()); + // * |-- |-- |-- box + box = (ContainerSchemaNode) metric.getDataChildByName("box"); + assertNotNull(box); + expectedQName = QName.create(UG_NS, UG_REV, "box"); + assertEquals(expectedQName, box.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, box.getPath()); + assertTrue(box.isAddedByUses()); + // * |-- |-- |-- leaf processing-rule + processingRule = (LeafSchemaNode) metric.getDataChildByName("processing-rule"); + assertNotNull(processingRule); + expectedQName = QName.create(UG_NS, UG_REV, "processing-rule"); + assertEquals(expectedQName, processingRule.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, processingRule.getPath()); + assertEquals(BooleanType.getInstance(), processingRule.getType()); + assertTrue(processingRule.isAddedByUses()); + // * |-- |-- |-- leaf ignore + ignore = (LeafSchemaNode) metric.getDataChildByName("ignore"); + assertNotNull(ignore); + expectedQName = QName.create(UG_NS, UG_REV, "ignore"); + assertEquals(expectedQName, ignore.getQName()); + path.pollLast(); + path.offer(expectedQName); + expectedPath= SchemaPath.create(path, true); + assertEquals(expectedPath, ignore.getPath()); + assertEquals(BooleanType.getInstance(), ignore.getType()); + assertTrue(ignore.isAddedByUses()); + } + + @Test + public void testTypedefs() throws URISyntaxException, SourceException, ReactorException { + modules = TestUtils.loadModules(getClass().getResource("/grouping-test").toURI()); + Module testModule = TestUtils.findModule(modules, "grouping-definitions"); + Set> types = testModule.getTypeDefinitions(); + + TypeDefinition intExt = null; + for(TypeDefinition td : types) { + if("int-ext".equals(td.getQName().getLocalName())) { + intExt = td; + } + } + assertNotNull(intExt); + + List path = Lists.newArrayList(QName.create(GD_NS, GD_REV, "int-ext")); + SchemaPath expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, intExt.getPath()); + + UnionType union = (UnionType)intExt.getBaseType(); + + TypeDefinition uint8 = null; + TypeDefinition pv = null; + for(TypeDefinition td : union.getTypes()) { + if("uint8".equals(td.getQName().getLocalName())) { + uint8 = td; + } else if("protocol-version".equals(td.getQName().getLocalName())) { + pv = td; + } + } + assertNotNull(uint8); + assertNotNull(pv); + + QName q1 = BaseTypes.constructQName("union"); + expectedPath = SchemaPath.create(Lists.newArrayList(q1), true); + assertEquals(expectedPath, union.getPath()); + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationListTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationListTest.java new file mode 100644 index 0000000000..70a9926836 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationListTest.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Default_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Key_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Leaf_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.List_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Mandatory_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Ordered_by_argContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Type_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Unique_stmtContext; +import org.opendaylight.yangtools.yang.parser.impl.YangModelBasicValidationListener; +import org.opendaylight.yangtools.yang.parser.util.YangValidationException; + +public class YangModelValidationListTest { + + private YangModelBasicValidationListener valid; + + @Before + public void setUp() { + valid = new YangModelBasicValidationListener(); + } + + @Test(expected = YangValidationException.class) + public void testKeyValidationDuplicates() { + + List_stmtContext list = YangModelValidationTest.mockStatement( + List_stmtContext.class, "list"); + Key_stmtContext key = YangModelValidationTest.mockStatement( + Key_stmtContext.class, "leaf1 leaf2 leaf1 leaf1"); + YangModelValidationTest.addChild(list, key); + + try { + valid.enterKey_stmt(key); + } catch (YangValidationException e) { + assertThat(e.getMessage(), + containsString("contains duplicates:[leaf1]")); + throw e; + } + } + + @Test(expected = YangValidationException.class) + public void testUniqueValidationDuplicates() { + List_stmtContext list =YangModelValidationTest.mockStatement( + List_stmtContext.class, "list"); + Unique_stmtContext unique = YangModelValidationTest.mockStatement( + Unique_stmtContext.class, "leaf1/a leaf2/n leaf1/a leaf1"); + YangModelValidationTest.addChild(list, unique); + + try { + valid.enterUnique_stmt(unique); + } catch (YangValidationException e) { + assertThat(e.getMessage(), + containsString("contains duplicates:[leaf1/a]")); + throw e; + } + } + + @Test(expected = YangValidationException.class) + public void testOrderBy() { + Ordered_by_argContext ctx = YangModelValidationTest.mockStatement( + Ordered_by_argContext.class, "unknown"); + + try { + valid.enterOrdered_by_arg(ctx); + } catch (YangValidationException e) { + assertThat( + e.getMessage(), + containsString("Ordered-by:unknown, illegal value for Ordered-by statement, only permitted:")); + throw e; + } + } + + @Test(expected = YangValidationException.class) + public void testLeaf() { + Leaf_stmtContext ctx = YangModelValidationTest.mockStatement( + Leaf_stmtContext.class, "leaf1"); + Default_stmtContext def = YangModelValidationTest.mockStatement( + Default_stmtContext.class, "default"); + YangModelValidationTest.addChild(ctx, def); + Type_stmtContext typ = YangModelValidationTest.mockStatement( + Type_stmtContext.class, "type"); + YangModelValidationTest.addChild(ctx, def); + YangModelValidationTest.addChild(ctx, typ); + + Mandatory_stmtContext mand = YangModelValidationTest.mockStatement( + Mandatory_stmtContext.class, null); + YangModelValidationTest.addChild(ctx, mand); + + try { + valid.enterLeaf_stmt(ctx); + } catch (YangValidationException e) { + assertThat( + e.getMessage(), + containsString("Both Mandatory and Default statement present")); + throw e; + } + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationModuleTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationModuleTest.java new file mode 100644 index 0000000000..6088ec569c --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationModuleTest.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Module_header_stmtsContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Module_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Namespace_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtsContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Yang_version_stmtContext; +import org.opendaylight.yangtools.yang.parser.impl.YangModelBasicValidationListener; +import org.opendaylight.yangtools.yang.parser.util.YangValidationException; + +public class YangModelValidationModuleTest { + + private YangModelBasicValidationListener valid; + + @Before + public void setUp() { + valid = new YangModelBasicValidationListener(); + } + + @Test(expected = YangValidationException.class) + public void testRevisionInvalidDateFormat() { + Revision_stmtContext mockedRev = mockModuleWithRevision("badFormat", + "module1"); + + try { + valid.enterRevision_stmt(mockedRev); + } catch (YangValidationException e) { + assertThat( + e.getMessage(), + containsString("Revision:badFormat, invalid date format expected date format is:")); + throw e; + } + } + + @Test + public void testRevisionValidDateFormat() { + Revision_stmtContext mockedRev = mockModuleWithRevision( + YangModelValidationTest.getFormattedDate(), "module1"); + + valid.enterRevision_stmt(mockedRev); + } + + @Test(expected = YangValidationException.class) + public void testNoHeaderStmts() { + Revision_stmtContext rev = mockModuleWithRevision("1999-4-5", "module1"); + + try { + valid.enterModule_stmt((Module_stmtContext) rev.getParent() + .getParent()); + } catch (YangValidationException e) { + assertThat( + e.getMessage(), + containsString("Missing Module-header statement in Module:module1")); + throw e; + } + } + + @Test(expected = YangValidationException.class) + public void testMultipleModulesPerSession() { + Module_stmtContext module1 = (Module_stmtContext) mockModuleWithRevision( + "1999-09-10", "m1").getParent().getParent(); + YangModelValidationTest.addChild(module1, YangModelValidationTest + .mockStatement(Namespace_stmtContext.class, "")); + + Module_stmtContext module2 = (Module_stmtContext) mockModuleWithRevision( + "1999-09-10", "m2").getParent().getParent(); + YangModelValidationTest.addChild(module1, YangModelValidationTest + .mockStatement(Namespace_stmtContext.class, "")); + valid.enterModule_stmt(module1); + + try { + valid.enterModule_stmt(module2); + } catch (YangValidationException e) { + assertThat(e.getMessage(), + containsString("Multiple (sub)modules per file")); + throw e; + } + } + + @Test(expected = YangValidationException.class) + public void testNoNamespace() { + Module_header_stmtsContext header = YangModelValidationTest + .mockStatement(Module_header_stmtsContext.class, null); + Module_stmtContext mod = YangModelValidationTest.mockStatement( + Module_stmtContext.class, "module1"); + YangModelValidationTest.addChild(mod, header); + + try { + valid.enterModule_header_stmts(header); + } catch (YangValidationException e) { + assertThat( + e.getMessage(), + containsString("Missing Namespace statement in Module-header:")); + throw e; + } + } + + @Test(expected = YangValidationException.class) + public void testNoPrefix() { + Module_header_stmtsContext header = YangModelValidationTest + .mockStatement(Module_header_stmtsContext.class, null); + Namespace_stmtContext nmspc = YangModelValidationTest.mockStatement( + Namespace_stmtContext.class, "http://test"); + Module_stmtContext mod = YangModelValidationTest.mockStatement( + Module_stmtContext.class, "module1"); + YangModelValidationTest.addChild(mod, header); + YangModelValidationTest.addChild(header, nmspc); + + try { + valid.enterModule_header_stmts(header); + } catch (YangValidationException e) { + assertThat( + e.getMessage(), + containsString("Missing Prefix statement in Module-header:")); + throw e; + } + } + +// @Test(expected = YangValidationException.class) +// public void testInvalidYangVersion() { +// +// Yang_version_stmtContext yangVersion = YangModelValidationTest +// .mockStatement(Yang_version_stmtContext.class, "55Unsup"); +// +// Module_stmtContext mod = YangModelValidationTest.mockStatement( +// Module_stmtContext.class, "module1"); +// YangModelValidationTest.addChild(mod, yangVersion); +// +// try { +// valid.enterYang_version_stmt(yangVersion); +// } catch (YangValidationException e) { +// assertThat( +// e.getMessage(), +// containsString("Unsupported yang version:55Unsup, supported version:" +// + BasicValidations.SUPPORTED_YANG_VERSION)); +// throw e; +// } +// } + + @Test + public void testValidYangVersion() { + + Yang_version_stmtContext ctx = mock(Yang_version_stmtContext.class); + doReturn(1).when(ctx).getChildCount(); + YangModelValidationTest.mockName(ctx, "1"); + + valid.enterYang_version_stmt(ctx); + } + + private static Revision_stmtContext mockModuleWithRevision(final String date, + final String moduleName) { + Revision_stmtContext mockedRev = YangModelValidationTest.mockStatement( + Revision_stmtContext.class, date); + Revision_stmtsContext revs = YangModelValidationTest.mockStatement( + Revision_stmtsContext.class, null); + Module_stmtContext mod = YangModelValidationTest.mockStatement( + Module_stmtContext.class, moduleName); + + YangModelValidationTest.addChild(revs, mockedRev); + YangModelValidationTest.addChild(mod, revs); + return mockedRev; + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationSubModuleTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationSubModuleTest.java new file mode 100644 index 0000000000..fc29bc7728 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationSubModuleTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; + +import org.antlr.v4.runtime.tree.ParseTree; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Belongs_to_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Submodule_header_stmtsContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Submodule_stmtContext; +import org.opendaylight.yangtools.yang.parser.impl.YangModelBasicValidationListener; +import org.opendaylight.yangtools.yang.parser.util.YangValidationException; + +public class YangModelValidationSubModuleTest { + + private YangModelBasicValidationListener valid; + + @Before + public void setUp() { + valid = new YangModelBasicValidationListener(); + } + + @Test(expected = YangValidationException.class) + public void testNoRevision() { + + Submodule_stmtContext ctx = YangModelValidationTest.mockStatement( + Submodule_stmtContext.class, "submodule1"); + + try { + valid.enterSubmodule_stmt(ctx); + } catch (YangValidationException e) { + assertThat( + e.getMessage(), + containsString("Missing Submodule-header statement in Submodule:submodule")); + throw e; + } + } + + @Test(expected = YangValidationException.class) + public void testNoBelongsTo() { + Submodule_header_stmtsContext header = mock(Submodule_header_stmtsContext.class); + mockSubmoduleParent(header, "submodule"); + + try { + valid.enterSubmodule_header_stmts(header); + } catch (YangValidationException e) { + assertThat( + e.getMessage(), + containsString("Missing Belongs-to statement in Submodule-header:")); + throw e; + } + } + + @Test(expected = YangValidationException.class) + public void testBelongsToNoPrefix() { + Belongs_to_stmtContext belongsTo = YangModelValidationTest + .mockStatement(Belongs_to_stmtContext.class, "supermodule"); + + mockSubmoduleParent(belongsTo, "submodule"); + + try { + valid.enterBelongs_to_stmt(belongsTo); + } catch (YangValidationException e) { + assertThat( + e.getMessage(), + containsString("Missing Prefix statement in Belongs-to:supermodule")); + throw e; + } + } + + private Submodule_stmtContext mockSubmoduleParent(final ParseTree child, + final String moduleName) { + Submodule_stmtContext ctx = YangModelValidationTest.mockStatement( + Submodule_stmtContext.class, moduleName); + YangModelValidationTest.addChild(ctx, child); + return ctx; + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationTest.java new file mode 100644 index 0000000000..7f3fa64c00 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangModelValidationTest.java @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Date; + +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.tree.TerminalNode; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Augment_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Import_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Include_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Module_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Namespace_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Prefix_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_date_stmtContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Status_argContext; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.StringContext; +//import org.opendaylight.yangtools.yang.parser.impl.BasicValidations; +//import org.opendaylight.yangtools.yang.parser.impl.ValidationUtil; +import org.opendaylight.yangtools.yang.parser.impl.YangModelBasicValidationListener; +import org.opendaylight.yangtools.yang.parser.util.YangValidationException; + +public class YangModelValidationTest { + + private YangModelBasicValidationListener valid; + + @Before + public void setUp() { + + valid = new YangModelBasicValidationListener(); + } + + @Test + public void testPrefixes() { + Prefix_stmtContext pref = mockStatement(Prefix_stmtContext.class, "unique1"); + Module_stmtContext module = mockStatement(Module_stmtContext.class, "module1"); + addChild(module, pref); + + valid.enterPrefix_stmt(pref); + + pref = mockStatement(Prefix_stmtContext.class, "unique1"); + module = mockStatement(Module_stmtContext.class, "module1"); + addChild(module, pref); + + try { + valid.enterPrefix_stmt(pref); + } catch (Exception e) { + return; + } + + fail("Validation Exception should have occured"); + } + + @Test + public void testNamespace() { + + Namespace_stmtContext namespace = mockStatement(Namespace_stmtContext.class, "http://test.parsing.uri.com"); + Module_stmtContext module = mockStatement(Module_stmtContext.class, "module1"); + addChild(module, namespace); + + valid.enterNamespace_stmt(namespace); + + namespace = mockStatement(Namespace_stmtContext.class, "invalid uri"); + module = mockStatement(Module_stmtContext.class, "module1"); + addChild(module, namespace); + + try { + valid.enterNamespace_stmt(namespace); + } catch (YangValidationException e) { + assertThat(e.getMessage(), containsString("Namespace:invalid uri cannot be parsed as URI")); + return; + } + + fail("Validation Exception should have occured"); + } + + @Test + public void testImports() { + Import_stmtContext impor = mockImport("unique1", "p1"); + Module_stmtContext mod = mockStatement(Module_stmtContext.class, "module1"); + addChild(mod, impor); + + valid.enterImport_stmt(impor); + + impor = mockImport("unique1", "p2"); + mod = mockStatement(Module_stmtContext.class, "module1"); + addChild(mod, impor); + + try { + valid.enterImport_stmt(impor); + } catch (YangValidationException e) { + assertThat(e.getMessage(), containsString("Import:unique1 not unique")); + return; + } + + fail("Validation Exception should have occured"); + } + + @Test + public void testIncludes() { + Include_stmtContext incl = mockInclude("unique1"); + Module_stmtContext mod = mockStatement(Module_stmtContext.class, "module1"); + addChild(mod, incl); + valid.enterInclude_stmt(incl); + + incl = mockInclude("unique1"); + mod = mockStatement(Module_stmtContext.class, "module1"); + addChild(mod, incl); + + try { + valid.enterInclude_stmt(incl); + } catch (YangValidationException e) { + assertThat(e.getMessage(), containsString("Include:unique1 not unique in (sub)module")); + return; + } + + fail("Validation Exception should have occured"); + } + +// @Test +// public void testIdentifierMatching() { +// List ids = new ArrayList(); +// // valid +// ids.add("_ok98-.87.-.8...88-asdAD"); +// ids.add("AA.bcd"); +// ids.add("a"); +// // invalid +// ids.add("9aa"); +// ids.add("-"); +// ids.add("."); +// +// int thrown = 0; +// for (String id : ids) { +// try { +// Module_stmtContext module = mock(Module_stmtContext.class); +// Token token = mock(Token.class); +// when(module.getStart()).thenReturn(token); +// BasicValidat ions.checkIdentifierInternal(module, id); +// } catch (YangValidationException e) { +// thrown++; +// } +// } +// +// assertEquals(3, thrown); +// } + + @Test(expected = YangValidationException.class) + public void testAugument() { + Augment_stmtContext augument = mockStatement(Augment_stmtContext.class, "/a:*abc/a:augument1"); + Module_stmtContext mod1 = mockStatement(Module_stmtContext.class, "mod1"); + addChild(mod1, augument); + + Token token = mock(Token.class); + when(augument.getStart()).thenReturn(token); + + try { + valid.enterAugment_stmt(augument); + } catch (YangValidationException e) { + assertThat( + e.getMessage(), + containsString("Schema node id:/a:*abc/a:augument1 not in required format, details:Prefixed id:a:*abc not in required format")); + throw e; + } + } + +// @Test +// public void testDeviate() { +// Deviation_stmtContext ctx = mockStatement(Deviation_stmtContext.class, "deviations"); +// Deviate_add_stmtContext add = mockStatement(Deviate_add_stmtContext.class, "add"); +// Deviate_delete_stmtContext del = mockStatement(Deviate_delete_stmtContext.class, "delete"); +// +// addChild(ctx, add); +// addChild(ctx, del); +// +// valid.enterDeviation_stmt(ctx); +// +// HashSet> types = Sets.newHashSet(); +// types.add(Deviate_add_stmtContext.class); +// types.add(Deviate_delete_stmtContext.class); +// +// int count = ValidationUtil.countPresentChildrenOfType(ctx, types); +// assertEquals(2, count); +// } + + @Test(expected = YangValidationException.class) + public void testStatus() throws Exception { + Status_argContext status = mockStatement(Status_argContext.class, "unknown"); + try { + valid.enterStatus_arg(status); + } catch (YangValidationException e) { + assertThat(e.getMessage(), containsString("illegal value for Status statement, only permitted:")); + throw e; + } + } + + private Import_stmtContext mockImport(final String name, final String prefixName) { + Import_stmtContext impor = mockStatement(Import_stmtContext.class, name); + + Prefix_stmtContext prefix = mockStatement(Prefix_stmtContext.class, prefixName); + Revision_date_stmtContext revDate = mockStatement(Revision_date_stmtContext.class, getFormattedDate()); + + addChild(impor, prefix); + addChild(impor, revDate); + return impor; + } + + static String getFormattedDate() { + return new SimpleDateFormat("yyyy-MM-dd").format(new Date()); + } + + private Include_stmtContext mockInclude(final String name) { + Include_stmtContext incl = mockStatement(Include_stmtContext.class, name); + + Revision_date_stmtContext revDate = mockStatement(Revision_date_stmtContext.class, getFormattedDate()); + + addChild(incl, revDate); + return incl; + } + + static void mockName(final ParseTree stmt, final String name) { + doReturn(1).when(stmt).getChildCount(); + + TerminalNode terminalNode = mock(TerminalNode.class); + doReturn(name).when(terminalNode).getText(); + + StringContext nameCtx = mock(StringContext.class); + doReturn(nameCtx).when(stmt).getChild(0); + doReturn(terminalNode).when(nameCtx).getChild(0); + doReturn(name).when(terminalNode).getText(); + + doReturn(Collections.singletonList(terminalNode)).when(nameCtx).STRING(); + } + + static T mockStatement(final Class stmtType, final String name) { + T stmt = stmtType.cast(mock(stmtType)); + + doReturn(0).when(stmt).getChildCount(); + + if (name != null) { + mockName(stmt, name); + } + return stmt; + } + + static void addChild(final ParseTree parent, final ParseTree child) { + int childCount = parent.getChildCount() + 1; + doReturn(childCount).when(parent).getChildCount(); + doReturn(child).when(parent).getChild(childCount - 1); + doReturn(parent).when(child).getParent(); + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserIdentityTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserIdentityTest.java new file mode 100644 index 0000000000..5021e89e92 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserIdentityTest.java @@ -0,0 +1,60 @@ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.util.Set; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.ModuleImport; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; +import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException; +import org.opendaylight.yangtools.yang.stmt.test.StmtTestUtils; + +public class YangParserIdentityTest { + + // base identity name equals identity name + @Test(expected = SomeModifiersUnresolvedException.class) + public void testParsingIdentityTestModule() throws URISyntaxException, + ReactorException, FileNotFoundException { + File yang = new File(getClass().getResource("/identity/identitytest.yang").toURI()); + InputStream stream = new FileInputStream(yang); + try { + TestUtils.loadModule(stream); + } catch (SomeModifiersUnresolvedException e) { + StmtTestUtils.log(e, " "); + throw e; + } + } + + // same module prefixed base identity name equals identity name + @Test(expected = SomeModifiersUnresolvedException.class) + public void testParsingPrefixIdentityTestModule() throws URISyntaxException, + ReactorException, FileNotFoundException { + File yang = new File(getClass().getResource("/identity/prefixidentitytest.yang").toURI()); + InputStream stream = new FileInputStream(yang); + try { + TestUtils.loadModule(stream); + } catch (SomeModifiersUnresolvedException e) { + StmtTestUtils.log(e, " "); + throw e; + } + } + + // imported module prefixed base identity name equals identity name, but + // prefix differs + @Test + public void testParsingImportPrefixIdentityTestModule() throws URISyntaxException, + ReactorException { + Set modules = TestUtils.loadModules(getClass().getResource("/identity/import").toURI()); + Module module = TestUtils.findModule(modules, "prefiximportidentitytest"); + Set imports = module.getImports(); + assertEquals(imports.size(), 1); + ModuleImport dummy = TestUtils.findImport(imports, "dummy"); + assertNotEquals(dummy.getPrefix(), module.getPrefix()); + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserNegativeTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserNegativeTest.java new file mode 100644 index 0000000000..bfaea689bc --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserNegativeTest.java @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser; +import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; +import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException; +import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException; +import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; +import org.opendaylight.yangtools.yang.parser.util.YangParseException; +import org.opendaylight.yangtools.yang.parser.util.YangValidationException; + +public class YangParserNegativeTest { + + @Test + public void testInvalidImport() throws Exception { + File yang = new File(getClass().getResource("/negative-scenario/testfile1.yang").toURI()); + try { + try (InputStream stream = new FileInputStream(yang)) { + TestUtils.loadModule(stream); + fail("SomeModifiersUnresolvedException should be thrown"); + } + } catch (SomeModifiersUnresolvedException e) { + final Throwable suppressed2levelsDown = e.getSuppressed()[0].getSuppressed()[0]; + assertTrue(suppressed2levelsDown instanceof InferenceException); + assertTrue(suppressed2levelsDown.getMessage().startsWith("Imported module")); + assertTrue(suppressed2levelsDown.getMessage().endsWith("was not found.")); + } + } + + @Test + public void testTypeNotFound() throws Exception { + File yang = new File(getClass().getResource("/negative-scenario/testfile2.yang").toURI()); + try { + try (InputStream stream = new FileInputStream(yang)) { + TestUtils.loadModule(stream); + fail("IllegalArgumentException should be thrown"); + } + } catch (IllegalStateException e) { + assertTrue(e.getMessage().startsWith( + "Type '(urn:simple.types.data.demo?revision=2013-02-27)int-ext' was not found")); + } + } + + @Test + public void testInvalidAugmentTarget() throws Exception { + File yang1 = new File(getClass().getResource("/negative-scenario/testfile0.yang").toURI()); + File yang2 = new File(getClass().getResource("/negative-scenario/testfile3.yang").toURI()); + try { + final List streams = new ArrayList<>(2); + try (InputStream testFile0 = new FileInputStream(yang1)) { + streams.add(testFile0); + try (InputStream testFile3 = new FileInputStream(yang2)) { + streams.add(testFile3); + assertEquals("Expected loaded files count is 2", 2, streams.size()); + TestUtils.loadModules(streams); + fail("SomeModifiersUnresolvedException should be thrown"); + } + } + } catch (SomeModifiersUnresolvedException e) { + final Throwable suppressed2levelsDown = e.getSuppressed()[0].getSuppressed()[0]; + assertTrue(suppressed2levelsDown instanceof InferenceException); + assertEquals( + "Augment target not found: Absolute{path=[(urn:simple.container.demo?revision=1970-01-01)unknown]}", + suppressed2levelsDown.getMessage()); + } + } + + @Test + public void testInvalidRefine() throws Exception { + File yang = new File(getClass().getResource("/negative-scenario/testfile4.yang").toURI()); + try { + try (InputStream stream = new FileInputStream(yang)) { + TestUtils.loadModule(stream); + fail("SourceException should be thrown"); + } + } catch (SourceException e) { + assertTrue(e + .getMessage() + .contains( + "Error in module 'test4' in the refine of uses 'Relative{path=[(urn:simple.container.demo?revision=1970-01-01)node]}': can not perform refine of 'PRESENCE' for the target 'LEAF_LIST'.")); + } + } + + @Test + public void testInvalidLength() throws Exception { + File yang = new File(getClass().getResource("/negative-scenario/testfile5.yang").toURI()); + try { + try (InputStream stream = new FileInputStream(yang)) { + TestUtils.loadModule(stream); + fail("YangParseException should be thrown"); + } + } catch (YangParseException e) { + assertTrue(e.getMessage().contains("Invalid length constraint: <4, 10>")); + } + } + + @Test + public void testInvalidRange() throws Exception { + File yang = new File(getClass().getResource("/negative-scenario/testfile6.yang").toURI()); + try { + try (InputStream stream = new FileInputStream(yang)) { + TestUtils.loadModule(stream); + fail("Exception should be thrown"); + } + } catch (YangParseException e) { + assertTrue(e.getMessage().contains("Invalid range constraint: <5, 20>")); + } + } + + @Test + public void testDuplicateContainer() throws Exception { + File yang = new File(getClass().getResource("/negative-scenario/duplicity/container.yang").toURI()); + try { + try (InputStream stream = new FileInputStream(yang)) { + TestUtils.loadModule(stream); + fail("SourceException should be thrown"); + } + } catch (SourceException e) { + String expected = "Error in module 'container': can not add '(urn:simple.container.demo?revision=1970-01-01)foo'. Node name collision: '(urn:simple.container.demo?revision=1970-01-01)foo' already declared."; + assertEquals(expected, e.getMessage()); + } + } + + @Test + public void testDuplicateContainerList() throws Exception { + File yang = new File(getClass().getResource("/negative-scenario/duplicity/container-list.yang").toURI()); + try { + try (InputStream stream = new FileInputStream(yang)) { + TestUtils.loadModule(stream); + fail("SourceException should be thrown"); + } + } catch (SourceException e) { + String expected = "Error in module 'container-list': can not add '(urn:simple.container.demo?revision=1970-01-01)foo'. Node name collision: '(urn:simple.container.demo?revision=1970-01-01)foo' already declared."; + assertEquals(expected, e.getMessage()); + } + } + + @Test + public void testDuplicateContainerLeaf() throws Exception { + File yang = new File(getClass().getResource("/negative-scenario/duplicity/container-leaf.yang").toURI()); + try { + try (InputStream stream = new FileInputStream(yang)) { + TestUtils.loadModule(stream); + fail("SourceException should be thrown"); + } + } catch (SourceException e) { + String expected = "Error in module 'container-leaf': can not add '(urn:simple.container.demo?revision=1970-01-01)foo'. Node name collision: '(urn:simple.container.demo?revision=1970-01-01)foo' already declared."; + assertEquals(expected, e.getMessage()); + } + } + + @Test + public void testDuplicateTypedef() throws Exception { + File yang = new File(getClass().getResource("/negative-scenario/duplicity/typedef.yang").toURI()); + try { + try (InputStream stream = new FileInputStream(yang)) { + TestUtils.loadModule(stream); + fail("IllegalArgumentException should be thrown"); + } + } catch (IllegalArgumentException e) { + String expected = "Duplicate name for typedef (urn:simple.container.demo?revision=1970-01-01)int-ext"; + assertEquals(expected, e.getMessage()); + } + } + + @Test + public void testDuplicityInAugmentTarget1() throws Exception { + File yang1 = new File(getClass().getResource("/negative-scenario/duplicity/augment0.yang").toURI()); + File yang2 = new File(getClass().getResource("/negative-scenario/duplicity/augment1.yang").toURI()); + try { + try (InputStream stream1 = new FileInputStream(yang1); InputStream stream2 = new FileInputStream(yang2)) { + TestUtils.loadModules(Arrays.asList(stream1, stream2)); + fail("IllegalStateException should be thrown"); + } + } catch (IllegalStateException e) { + assertEquals(e.getMessage(), + "An augment cannot add node named 'id' because this name is already used in target"); + } + } + + @Test + public void testDuplicityInAugmentTarget2() throws Exception { + File yang1 = new File(getClass().getResource("/negative-scenario/duplicity/augment0.yang").toURI()); + File yang2 = new File(getClass().getResource("/negative-scenario/duplicity/augment2.yang").toURI()); + try { + try (InputStream stream1 = new FileInputStream(yang1); InputStream stream2 = new FileInputStream(yang2)) { + TestUtils.loadModules(Arrays.asList(stream1, stream2)); + fail("IllegalStateException should be thrown"); + } + } catch (IllegalStateException e) { + assertEquals(e.getMessage(), + "An augment cannot add node named 'delta' because this name is already used in target"); + } + } + + @Test + public void testMandatoryInAugment() throws Exception { + File yang1 = new File(getClass().getResource("/negative-scenario/testfile8.yang").toURI()); + File yang2 = new File(getClass().getResource("/negative-scenario/testfile7.yang").toURI()); + try { + try (InputStream stream1 = new FileInputStream(yang1); InputStream stream2 = new FileInputStream(yang2)) { + TestUtils.loadModules(Arrays.asList(stream1, stream2)); + fail("IllegalArgumentException should be thrown"); + } + } catch (IllegalArgumentException e) { + String expected = "An augment cannot add node 'linkleaf' because it is mandatory and in module different from target"; + assertEquals(expected, e.getMessage()); + } + } + + @Test + public void testWrongDependenciesDir() throws Exception { + try { + File yangFile = new File(getClass().getResource("/types/custom-types-test@2012-4-4.yang").toURI()); + File dependenciesDir = new File("/invalid"); + YangContextParser parser = new YangParserImpl(); + parser.parseFile(yangFile, dependenciesDir); + fail("Exception should be thrown"); + } catch (IllegalStateException e) { + String expected = File.separator + "invalid does not exists"; + assertEquals(expected, e.getMessage()); + } + } + + @Test + public void testWrongDependenciesDir2() throws Exception { + try { + File yangFile = new File(getClass().getResource("/types/custom-types-test@2012-4-4.yang").toURI()); + File dependenciesDir = new File(getClass().getResource("/model").toURI()); + YangContextParser parser = new YangParserImpl(); + parser.parseFile(yangFile, dependenciesDir); + fail("Exception should be thrown"); + } catch (YangValidationException e) { + String expected = "Not existing module imported"; + assertTrue(e.getMessage().contains(expected)); + } + } + + @Test + public void testInvalidListKeyDefinition() throws Exception { + File yang1 = new File(getClass().getResource("/negative-scenario/invalid-list-key-def.yang").toURI()); + try { + try (InputStream stream1 = new FileInputStream(yang1)) { + TestUtils.loadModule(stream1); + fail("IllegalArgumentException should be thrown"); + } + } catch (IllegalArgumentException e) { + String expected = "Key 'rib-id' misses node 'rib-id' in list '(invalid:list:key:def?revision=1970-01-01)application-map'"; + assertTrue(e.getMessage().startsWith(expected)); + } + } + +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserSimpleTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserSimpleTest.java new file mode 100644 index 0000000000..15077ae232 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserSimpleTest.java @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +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.net.URI; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.MustDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UsesNode; + +public class YangParserSimpleTest { + private final URI snNS = URI.create("urn:opendaylight:simple-nodes"); + private Date snRev; + private final String snPref = "sn"; + + private final DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + private Set modules; + + @Before + public void init() throws Exception { + snRev = simpleDateFormat.parse("2013-07-30"); + modules = TestUtils.loadModules(getClass().getResource("/simple-test").toURI()); + } + + @Test + public void testParseAnyXml() { + Module testModule = TestUtils.findModule(modules, "simple-nodes"); + AnyXmlSchemaNode data = (AnyXmlSchemaNode) testModule.getDataChildByName("data"); + assertNotNull("'anyxml data not found'", data); + + // test SchemaNode args + QName qname = data.getQName(); + assertEquals("data", qname.getLocalName()); + assertEquals(snNS, qname.getNamespace()); + assertEquals(snRev, qname.getRevision()); + assertEquals("anyxml desc", data.getDescription()); + assertEquals("data ref", data.getReference()); + assertEquals(Status.OBSOLETE, data.getStatus()); + assertEquals(0, data.getUnknownSchemaNodes().size()); + // test DataSchemaNode args + assertFalse(data.isAugmenting()); + assertFalse(data.isConfiguration()); + ConstraintDefinition constraints = data.getConstraints(); + assertEquals("class != 'wheel'", constraints.getWhenCondition().toString()); + Set mustConstraints = constraints.getMustConstraints(); + assertEquals(2, constraints.getMustConstraints().size()); + + String must1 = "ifType != 'ethernet' or (ifType = 'ethernet' and ifMTU = 1500)"; + String errMsg1 = "An ethernet MTU must be 1500"; + String must2 = "ifType != 'atm' or (ifType = 'atm' and ifMTU <= 17966 and ifMTU >= 64)"; + String errMsg2 = "An atm MTU must be 64 .. 17966"; + + boolean found1 = false; + boolean found2 = false; + for (MustDefinition must : mustConstraints) { + if (must1.equals(must.toString())) { + found1 = true; + assertEquals(errMsg1, must.getErrorMessage()); + } else if (must2.equals(must.toString())) { + found2 = true; + assertEquals(errMsg2, must.getErrorMessage()); + assertEquals("anyxml data error-app-tag", must.getErrorAppTag()); + assertEquals("an error occured in data", must.getDescription()); + assertEquals("data must ref", must.getReference()); + } + } + assertTrue(found1); + assertTrue(found2); + + assertTrue(constraints.isMandatory()); + assertTrue(0 == constraints.getMinElements()); + assertTrue(Integer.MAX_VALUE == constraints.getMaxElements()); + } + + @Test + public void testParseContainer() { + Module test = TestUtils.findModule(modules, "simple-nodes"); + + ContainerSchemaNode nodes = (ContainerSchemaNode) test.getDataChildByName("nodes"); + // test SchemaNode args + QName expectedQName = QName.create(snNS, snRev, "nodes"); + assertEquals(expectedQName, nodes.getQName()); + SchemaPath expectedPath = TestUtils.createPath(true, snNS, snRev, snPref, "nodes"); + assertEquals(expectedPath, nodes.getPath()); + assertEquals("nodes collection", nodes.getDescription()); + assertEquals("nodes ref", nodes.getReference()); + assertEquals(Status.CURRENT, nodes.getStatus()); + assertEquals(0, nodes.getUnknownSchemaNodes().size()); + // test DataSchemaNode args + assertFalse(nodes.isAugmenting()); + assertFalse(nodes.isConfiguration()); + + // constraints + ConstraintDefinition constraints = nodes.getConstraints(); + assertEquals("class != 'wheel'", constraints.getWhenCondition().toString()); + Set mustConstraints = constraints.getMustConstraints(); + assertEquals(2, constraints.getMustConstraints().size()); + + String must1 = "ifType != 'atm' or (ifType = 'atm' and ifMTU <= 17966 and ifMTU >= 64)"; + String errMsg1 = "An atm MTU must be 64 .. 17966"; + String must2 = "ifId != 0"; + + boolean found1 = false; + boolean found2 = false; + for (MustDefinition must : mustConstraints) { + if (must1.equals(must.toString())) { + found1 = true; + assertEquals(errMsg1, must.getErrorMessage()); + } else if (must2.equals(must.toString())) { + found2 = true; + assertNull(must.getErrorMessage()); + assertNull(must.getErrorAppTag()); + assertNull(must.getDescription()); + assertNull(must.getReference()); + } + } + assertTrue(found1); + assertTrue(found2); + + assertFalse(constraints.isMandatory()); + assertTrue(0 == constraints.getMinElements()); + assertTrue(Integer.MAX_VALUE == constraints.getMaxElements()); + assertTrue(nodes.isPresenceContainer()); + + // typedef + Set> typedefs = nodes.getTypeDefinitions(); + assertEquals(1, typedefs.size()); + TypeDefinition nodesType = typedefs.iterator().next(); + QName typedefQName = QName.create(snNS, snRev, "nodes-type"); + assertEquals(typedefQName, nodesType.getQName()); + SchemaPath nodesTypePath = TestUtils.createPath(true, snNS, snRev, snPref, "nodes", "nodes-type"); + assertEquals(nodesTypePath, nodesType.getPath()); + assertTrue(nodesType.getDescription().isEmpty()); + assertTrue(nodesType.getReference().isEmpty()); + assertEquals(Status.CURRENT, nodesType.getStatus()); + assertEquals(0, nodesType.getUnknownSchemaNodes().size()); + + // child nodes + // total size = 8: defined 6, inserted by uses 2 + assertEquals(8, nodes.getChildNodes().size()); + LeafListSchemaNode added = (LeafListSchemaNode)nodes.getDataChildByName("added"); + assertEquals(createPath("nodes", "added"), added.getPath()); + assertEquals(createPath("mytype"), added.getType().getPath()); + + ListSchemaNode links = (ListSchemaNode) nodes.getDataChildByName("links"); + assertFalse(links.isUserOrdered()); + + Set groupings = nodes.getGroupings(); + assertEquals(1, groupings.size()); + GroupingDefinition nodeGroup = groupings.iterator().next(); + QName groupQName = QName.create(snNS, snRev, "node-group"); + assertEquals(groupQName, nodeGroup.getQName()); + SchemaPath nodeGroupPath = TestUtils.createPath(true, snNS, snRev, snPref, "nodes", "node-group"); + assertEquals(nodeGroupPath, nodeGroup.getPath()); + + Set uses = nodes.getUses(); + assertEquals(1, uses.size()); + UsesNode use = uses.iterator().next(); + assertEquals(nodeGroupPath, use.getGroupingPath()); + } + + + private final URI ns = URI.create("urn:opendaylight:simple-nodes"); + private Date rev; + private final String prefix = "sn"; + + private SchemaPath createPath(final String... names) { + try { + rev = new SimpleDateFormat("yyyy-MM-dd").parse("2013-07-30"); + } catch (ParseException e) { + e.printStackTrace(); + } + + List path = new ArrayList<>(); + for (String name : names) { + path.add(QName.create(ns, rev, name)); + } + return SchemaPath.create(path, true); + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserTest.java new file mode 100644 index 0000000000..7d1e329beb --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserTest.java @@ -0,0 +1,988 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +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.junit.Assert.fail; +import java.io.File; +import java.io.IOException; +import java.math.BigInteger; +import java.net.URI; +import java.net.URISyntaxException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; +import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; +import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Deviation; +import org.opendaylight.yangtools.yang.model.api.Deviation.Deviate; +import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition; +import org.opendaylight.yangtools.yang.model.api.FeatureDefinition; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.ModuleImport; +import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; +import org.opendaylight.yangtools.yang.model.api.RpcDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; +import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; +import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser; +import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException; +import org.opendaylight.yangtools.yang.model.util.Decimal64; +import org.opendaylight.yangtools.yang.model.util.ExtendedType; +import org.opendaylight.yangtools.yang.model.util.Int16; +import org.opendaylight.yangtools.yang.model.util.Int32; +import org.opendaylight.yangtools.yang.model.util.StringType; +import org.opendaylight.yangtools.yang.model.util.Uint32; +import org.opendaylight.yangtools.yang.model.util.UnionType; +import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; +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 org.opendaylight.yangtools.yang.parser.util.YangParseException; + +public class YangParserTest { + public static final String FS = File.separator; + + private final URI fooNS = URI.create("urn:opendaylight.foo"); + private final URI barNS = URI.create("urn:opendaylight.bar"); + private final URI bazNS = URI.create("urn:opendaylight.baz"); + private Date fooRev; + private Date barRev; + private Date bazRev; + + private Set modules; + + @Before + public void init() throws Exception { + DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + fooRev = simpleDateFormat.parse("2013-02-27"); + barRev = simpleDateFormat.parse("2013-07-03"); + bazRev = simpleDateFormat.parse("2013-02-27"); + + modules = TestUtils.loadModules(getClass().getResource("/model").toURI()); + assertEquals(3, modules.size()); + } + + @Test + public void testHeaders() throws ParseException { + Module foo = TestUtils.findModule(modules, "foo"); + + assertEquals("foo", foo.getName()); + assertEquals("1", foo.getYangVersion()); + assertEquals(fooNS, foo.getNamespace()); + assertEquals("foo", foo.getPrefix()); + + Set imports = foo.getImports(); + assertEquals(2, imports.size()); + + ModuleImport import2 = TestUtils.findImport(imports, "br"); + assertEquals("bar", import2.getModuleName()); + assertEquals(barRev, import2.getRevision()); + + ModuleImport import3 = TestUtils.findImport(imports, "bz"); + assertEquals("baz", import3.getModuleName()); + assertEquals(bazRev, import3.getRevision()); + + assertEquals("opendaylight", foo.getOrganization()); + assertEquals("http://www.opendaylight.org/", foo.getContact()); + Date expectedRevision = TestUtils.createDate("2013-02-27"); + assertEquals(expectedRevision, foo.getRevision()); + assertEquals(" WILL BE DEFINED LATER", foo.getReference()); + } + + @Test + public void testParseList() { + Module bar = TestUtils.findModule(modules, "bar"); + URI expectedNamespace = URI.create("urn:opendaylight.bar"); + String expectedPrefix = "bar"; + + ContainerSchemaNode interfaces = (ContainerSchemaNode) bar.getDataChildByName("interfaces"); + + ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry"); + // test SchemaNode args + QName expectedQName = QName.create(expectedNamespace, barRev, "ifEntry"); + assertEquals(expectedQName, ifEntry.getQName()); + SchemaPath expectedPath = TestUtils.createPath(true, expectedNamespace, barRev, expectedPrefix, "interfaces", + "ifEntry"); + assertEquals(expectedPath, ifEntry.getPath()); + assertNull(ifEntry.getDescription()); + assertNull(ifEntry.getReference()); + assertEquals(Status.CURRENT, ifEntry.getStatus()); + assertEquals(0, ifEntry.getUnknownSchemaNodes().size()); + // test DataSchemaNode args + assertFalse(ifEntry.isAugmenting()); + assertTrue(ifEntry.isConfiguration()); + ConstraintDefinition constraints = ifEntry.getConstraints(); + // :TODO augment to ifEntry have when condition and so in consequence + // ifEntry should be a context node ? + // assertNull(constraints.getWhenCondition()); + assertEquals(0, constraints.getMustConstraints().size()); + assertFalse(constraints.isMandatory()); + assertEquals(1, (int) constraints.getMinElements()); + assertEquals(11, (int) constraints.getMaxElements()); + // test AugmentationTarget args + Set availableAugmentations = ifEntry.getAvailableAugmentations(); + assertEquals(2, availableAugmentations.size()); + // test ListSchemaNode args + List expectedKey = new ArrayList<>(); + expectedKey.add(QName.create(expectedNamespace, barRev, "ifIndex")); + assertEquals(expectedKey, ifEntry.getKeyDefinition()); + assertFalse(ifEntry.isUserOrdered()); + // test DataNodeContainer args + assertEquals(0, ifEntry.getTypeDefinitions().size()); + assertEquals(4, ifEntry.getChildNodes().size()); + assertEquals(0, ifEntry.getGroupings().size()); + assertEquals(0, ifEntry.getUses().size()); + + LeafSchemaNode ifIndex = (LeafSchemaNode) ifEntry.getDataChildByName("ifIndex"); + assertEquals(ifEntry.getKeyDefinition().get(0), ifIndex.getQName()); + assertTrue(ifIndex.getType() instanceof Uint32); + LeafSchemaNode ifMtu = (LeafSchemaNode) ifEntry.getDataChildByName("ifMtu"); + assertTrue(ifMtu.getType() instanceof Int32); + } + + @Test + public void testTypedefRangesResolving() throws ParseException { + Module foo = TestUtils.findModule(modules, "foo"); + LeafSchemaNode int32Leaf = (LeafSchemaNode) foo.getDataChildByName("int32-leaf"); + + ExtendedType leafType = (ExtendedType) int32Leaf.getType(); + QName leafTypeQName = leafType.getQName(); + assertEquals("int32-ext2", leafTypeQName.getLocalName()); + assertEquals(fooNS, leafTypeQName.getNamespace()); + assertEquals(fooRev, leafTypeQName.getRevision()); + assertNull(leafType.getUnits()); + assertNull(leafType.getDefaultValue()); + assertTrue(leafType.getLengthConstraints().isEmpty()); + assertTrue(leafType.getPatternConstraints().isEmpty()); + List ranges = leafType.getRangeConstraints(); + assertEquals(1, ranges.size()); + RangeConstraint range = ranges.get(0); + assertEquals(BigInteger.valueOf(12), range.getMin()); + assertEquals(BigInteger.valueOf(20), range.getMax()); + + ExtendedType baseType = (ExtendedType) leafType.getBaseType(); + QName baseTypeQName = baseType.getQName(); + assertEquals("int32-ext2", baseTypeQName.getLocalName()); + assertEquals(barNS, baseTypeQName.getNamespace()); + assertEquals(barRev, baseTypeQName.getRevision()); + assertEquals("mile", baseType.getUnits()); + assertEquals("11", baseType.getDefaultValue()); + assertTrue(leafType.getLengthConstraints().isEmpty()); + assertTrue(leafType.getPatternConstraints().isEmpty()); + List baseTypeRanges = baseType.getRangeConstraints(); + assertEquals(2, baseTypeRanges.size()); + RangeConstraint baseTypeRange1 = baseTypeRanges.get(0); + assertEquals(BigInteger.valueOf(3), baseTypeRange1.getMin()); + assertEquals(BigInteger.valueOf(9), baseTypeRange1.getMax()); + RangeConstraint baseTypeRange2 = baseTypeRanges.get(1); + assertEquals(BigInteger.valueOf(11), baseTypeRange2.getMin()); + assertEquals(BigInteger.valueOf(20), baseTypeRange2.getMax()); + + ExtendedType base = (ExtendedType) baseType.getBaseType(); + QName baseQName = base.getQName(); + assertEquals("int32-ext1", baseQName.getLocalName()); + assertEquals(barNS, baseQName.getNamespace()); + assertEquals(barRev, baseQName.getRevision()); + assertNull(base.getUnits()); + assertNull(base.getDefaultValue()); + assertTrue(leafType.getLengthConstraints().isEmpty()); + assertTrue(leafType.getPatternConstraints().isEmpty()); + List baseRanges = base.getRangeConstraints(); + assertEquals(1, baseRanges.size()); + RangeConstraint baseRange = baseRanges.get(0); + assertEquals(BigInteger.valueOf(2), baseRange.getMin()); + assertEquals(BigInteger.valueOf(20), baseRange.getMax()); + + assertTrue(base.getBaseType() instanceof Int32); + } + + @Test + public void testTypedefPatternsResolving() { + Module foo = TestUtils.findModule(modules, "foo"); + LeafSchemaNode stringleaf = (LeafSchemaNode) foo.getDataChildByName("string-leaf"); + + ExtendedType type = (ExtendedType) stringleaf.getType(); + QName typeQName = type.getQName(); + assertEquals("string-ext4", typeQName.getLocalName()); + assertEquals(barNS, typeQName.getNamespace()); + assertEquals(barRev, typeQName.getRevision()); + assertNull(type.getUnits()); + assertNull(type.getDefaultValue()); + List patterns = type.getPatternConstraints(); + assertEquals(1, patterns.size()); + PatternConstraint pattern = patterns.iterator().next(); + assertEquals("^[e-z]*$", pattern.getRegularExpression()); + assertTrue(type.getLengthConstraints().isEmpty()); + assertTrue(type.getRangeConstraints().isEmpty()); + + ExtendedType baseType1 = (ExtendedType) type.getBaseType(); + QName baseType1QName = baseType1.getQName(); + assertEquals("string-ext3", baseType1QName.getLocalName()); + assertEquals(barNS, baseType1QName.getNamespace()); + assertEquals(barRev, baseType1QName.getRevision()); + assertNull(baseType1.getUnits()); + assertNull(baseType1.getDefaultValue()); + patterns = baseType1.getPatternConstraints(); + assertEquals(1, patterns.size()); + pattern = patterns.iterator().next(); + assertEquals("^[b-u]*$", pattern.getRegularExpression()); + assertTrue(baseType1.getLengthConstraints().isEmpty()); + assertTrue(baseType1.getRangeConstraints().isEmpty()); + + ExtendedType baseType2 = (ExtendedType) baseType1.getBaseType(); + QName baseType2QName = baseType2.getQName(); + assertEquals("string-ext2", baseType2QName.getLocalName()); + assertEquals(barNS, baseType2QName.getNamespace()); + assertEquals(barRev, baseType2QName.getRevision()); + assertNull(baseType2.getUnits()); + assertNull(baseType2.getDefaultValue()); + assertTrue(baseType2.getPatternConstraints().isEmpty()); + List baseType2Lengths = baseType2.getLengthConstraints(); + assertEquals(1, baseType2Lengths.size()); + LengthConstraint length = baseType2Lengths.get(0); + assertEquals(BigInteger.valueOf(6), length.getMin()); + assertEquals(BigInteger.TEN, length.getMax()); + assertTrue(baseType2.getRangeConstraints().isEmpty()); + + ExtendedType baseType3 = (ExtendedType) baseType2.getBaseType(); + QName baseType3QName = baseType3.getQName(); + assertEquals("string-ext1", baseType3QName.getLocalName()); + assertEquals(barNS, baseType3QName.getNamespace()); + assertEquals(barRev, baseType3QName.getRevision()); + assertNull(baseType3.getUnits()); + assertNull(baseType3.getDefaultValue()); + patterns = baseType3.getPatternConstraints(); + assertEquals(1, patterns.size()); + pattern = patterns.iterator().next(); + assertEquals("^[a-k]*$", pattern.getRegularExpression()); + List baseType3Lengths = baseType3.getLengthConstraints(); + assertEquals(1, baseType3Lengths.size()); + length = baseType3Lengths.get(0); + assertEquals(BigInteger.valueOf(5), length.getMin()); + assertEquals(BigInteger.valueOf(11), length.getMax()); + assertTrue(baseType3.getRangeConstraints().isEmpty()); + + assertTrue(baseType3.getBaseType() instanceof StringType); + } + + @Test + public void testTypedefInvalidPatternsResolving() { + Module foo = TestUtils.findModule(modules, "foo"); + final LeafSchemaNode invalidPatternStringLeaf = (LeafSchemaNode) foo + .getDataChildByName("invalid-pattern-string-leaf"); + ExtendedType type = (ExtendedType) invalidPatternStringLeaf.getType(); + QName typeQName = type.getQName(); + assertEquals("invalid-string-pattern", typeQName.getLocalName()); + assertEquals(barNS, typeQName.getNamespace()); + assertEquals(barRev, typeQName.getRevision()); + assertNull(type.getUnits()); + assertNull(type.getDefaultValue()); + List patterns = type.getPatternConstraints(); + assertTrue(patterns.isEmpty()); + + final LeafSchemaNode invalidDirectStringPatternDefLeaf = (LeafSchemaNode) foo + .getDataChildByName("invalid-direct-string-pattern-def-leaf"); + type = (ExtendedType) invalidDirectStringPatternDefLeaf.getType(); + typeQName = type.getQName(); + assertEquals("string", typeQName.getLocalName()); + assertEquals(fooNS, typeQName.getNamespace()); + assertEquals(fooRev, typeQName.getRevision()); + assertNull(type.getUnits()); + assertNull(type.getDefaultValue()); + patterns = type.getPatternConstraints(); + assertTrue(patterns.isEmpty()); + + final LeafSchemaNode multiplePatternStringLeaf = (LeafSchemaNode) foo + .getDataChildByName("multiple-pattern-string-leaf"); + type = (ExtendedType) multiplePatternStringLeaf.getType(); + typeQName = type.getQName(); + assertEquals("multiple-pattern-string", typeQName.getLocalName()); + assertEquals(barNS, typeQName.getNamespace()); + assertEquals(barRev, typeQName.getRevision()); + assertNull(type.getUnits()); + assertNull(type.getDefaultValue()); + patterns = type.getPatternConstraints(); + assertTrue(!patterns.isEmpty()); + assertEquals(1, patterns.size()); + PatternConstraint pattern = patterns.iterator().next(); + assertEquals("^[e-z]*$", pattern.getRegularExpression()); + assertTrue(type.getLengthConstraints().isEmpty()); + assertTrue(type.getRangeConstraints().isEmpty()); + + final LeafSchemaNode multiplePatternDirectStringDefLeaf = (LeafSchemaNode) foo + .getDataChildByName("multiple-pattern-direct-string-def-leaf"); + type = (ExtendedType) multiplePatternDirectStringDefLeaf.getType(); + typeQName = type.getQName(); + assertEquals("string", typeQName.getLocalName()); + assertEquals(fooNS, typeQName.getNamespace()); + assertEquals(fooRev, typeQName.getRevision()); + assertNull(type.getUnits()); + assertNull(type.getDefaultValue()); + patterns = type.getPatternConstraints(); + assertTrue(!patterns.isEmpty()); + assertEquals(2, patterns.size()); + + boolean isEZPattern = false; + boolean isADPattern = false; + for (final PatternConstraint patternConstraint : patterns) { + if (patternConstraint.getRegularExpression().equals("^[e-z]*$")) { + isEZPattern = true; + } else if (patternConstraint.getRegularExpression().equals("^[a-d]*$")) { + isADPattern = true; + } + } + assertTrue(isEZPattern); + assertTrue(isADPattern); + } + + @Test + public void testTypedefLengthsResolving() { + Module foo = TestUtils.findModule(modules, "foo"); + + LeafSchemaNode lengthLeaf = (LeafSchemaNode) foo.getDataChildByName("length-leaf"); + ExtendedType type = (ExtendedType) lengthLeaf.getType(); + + QName typeQName = type.getQName(); + assertEquals("string-ext2", typeQName.getLocalName()); + assertEquals(fooNS, typeQName.getNamespace()); + assertEquals(fooRev, typeQName.getRevision()); + assertNull(type.getUnits()); + assertNull(type.getDefaultValue()); + assertTrue(type.getPatternConstraints().isEmpty()); + List typeLengths = type.getLengthConstraints(); + assertEquals(1, typeLengths.size()); + LengthConstraint length = typeLengths.get(0); + assertEquals(BigInteger.valueOf(7), length.getMin()); + assertEquals(BigInteger.TEN, length.getMax()); + assertTrue(type.getRangeConstraints().isEmpty()); + + ExtendedType baseType1 = (ExtendedType) type.getBaseType(); + QName baseType1QName = baseType1.getQName(); + assertEquals("string-ext2", baseType1QName.getLocalName()); + assertEquals(barNS, baseType1QName.getNamespace()); + assertEquals(barRev, baseType1QName.getRevision()); + assertNull(baseType1.getUnits()); + assertNull(baseType1.getDefaultValue()); + assertTrue(baseType1.getPatternConstraints().isEmpty()); + List baseType2Lengths = baseType1.getLengthConstraints(); + assertEquals(1, baseType2Lengths.size()); + length = baseType2Lengths.get(0); + assertEquals(BigInteger.valueOf(6), length.getMin()); + assertEquals(BigInteger.TEN, length.getMax()); + assertTrue(baseType1.getRangeConstraints().isEmpty()); + + ExtendedType baseType2 = (ExtendedType) baseType1.getBaseType(); + QName baseType2QName = baseType2.getQName(); + assertEquals("string-ext1", baseType2QName.getLocalName()); + assertEquals(barNS, baseType2QName.getNamespace()); + assertEquals(barRev, baseType2QName.getRevision()); + assertNull(baseType2.getUnits()); + assertNull(baseType2.getDefaultValue()); + List patterns = baseType2.getPatternConstraints(); + assertEquals(1, patterns.size()); + PatternConstraint pattern = patterns.iterator().next(); + assertEquals("^[a-k]*$", pattern.getRegularExpression()); + List baseType3Lengths = baseType2.getLengthConstraints(); + assertEquals(1, baseType3Lengths.size()); + length = baseType3Lengths.get(0); + assertEquals(BigInteger.valueOf(5), length.getMin()); + assertEquals(BigInteger.valueOf(11), length.getMax()); + assertTrue(baseType2.getRangeConstraints().isEmpty()); + + assertTrue(baseType2.getBaseType() instanceof StringType); + } + + @Test + public void testTypedefDecimal1() { + Module foo = TestUtils.findModule(modules, "foo"); + LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("decimal-leaf"); + + ExtendedType type = (ExtendedType) testleaf.getType(); + QName typeQName = type.getQName(); + assertEquals("my-decimal-type", typeQName.getLocalName()); + assertEquals(fooNS, typeQName.getNamespace()); + assertEquals(fooRev, typeQName.getRevision()); + assertNull(type.getUnits()); + assertNull(type.getDefaultValue()); + assertEquals(4, (int) type.getFractionDigits()); + assertTrue(type.getLengthConstraints().isEmpty()); + assertTrue(type.getPatternConstraints().isEmpty()); + assertTrue(type.getRangeConstraints().isEmpty()); + + ExtendedType typeBase = (ExtendedType) type.getBaseType(); + QName typeBaseQName = typeBase.getQName(); + assertEquals("my-decimal-type", typeBaseQName.getLocalName()); + assertEquals(barNS, typeBaseQName.getNamespace()); + assertEquals(barRev, typeBaseQName.getRevision()); + assertNull(typeBase.getUnits()); + assertNull(typeBase.getDefaultValue()); + assertNull(typeBase.getFractionDigits()); + assertTrue(typeBase.getLengthConstraints().isEmpty()); + assertTrue(typeBase.getPatternConstraints().isEmpty()); + assertTrue(typeBase.getRangeConstraints().isEmpty()); + + Decimal64 decimal = (Decimal64) typeBase.getBaseType(); + assertEquals(6, (int) decimal.getFractionDigits()); + } + + @Test + public void testTypedefDecimal2() { + Module foo = TestUtils.findModule(modules, "foo"); + LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("decimal-leaf2"); + + ExtendedType type = (ExtendedType) testleaf.getType(); + QName typeQName = type.getQName(); + assertEquals("my-decimal-type", typeQName.getLocalName()); + assertEquals(barNS, typeQName.getNamespace()); + assertEquals(barRev, typeQName.getRevision()); + assertNull(type.getUnits()); + assertNull(type.getDefaultValue()); + assertNull(type.getFractionDigits()); + assertTrue(type.getLengthConstraints().isEmpty()); + assertTrue(type.getPatternConstraints().isEmpty()); + assertTrue(type.getRangeConstraints().isEmpty()); + + Decimal64 baseTypeDecimal = (Decimal64) type.getBaseType(); + assertEquals(6, (int) baseTypeDecimal.getFractionDigits()); + } + + @Test + public void testTypedefUnion() { + Module foo = TestUtils.findModule(modules, "foo"); + LeafSchemaNode unionleaf = (LeafSchemaNode) foo.getDataChildByName("union-leaf"); + + ExtendedType type = (ExtendedType) unionleaf.getType(); + QName typeQName = type.getQName(); + assertEquals("my-union-ext", typeQName.getLocalName()); + assertEquals(barNS, typeQName.getNamespace()); + assertEquals(barRev, typeQName.getRevision()); + assertNull(type.getUnits()); + assertNull(type.getDefaultValue()); + assertNull(type.getFractionDigits()); + assertTrue(type.getLengthConstraints().isEmpty()); + assertTrue(type.getPatternConstraints().isEmpty()); + assertTrue(type.getRangeConstraints().isEmpty()); + + ExtendedType baseType = (ExtendedType) type.getBaseType(); + QName baseTypeQName = baseType.getQName(); + assertEquals("my-union", baseTypeQName.getLocalName()); + assertEquals(barNS, baseTypeQName.getNamespace()); + assertEquals(barRev, baseTypeQName.getRevision()); + assertNull(baseType.getUnits()); + assertNull(baseType.getDefaultValue()); + assertNull(baseType.getFractionDigits()); + assertTrue(baseType.getLengthConstraints().isEmpty()); + assertTrue(baseType.getPatternConstraints().isEmpty()); + assertTrue(baseType.getRangeConstraints().isEmpty()); + + UnionType unionType = (UnionType) baseType.getBaseType(); + List> unionTypes = unionType.getTypes(); + assertEquals(2, unionTypes.size()); + + ExtendedType unionType1 = (ExtendedType) unionTypes.get(0); + QName unionType1QName = baseType.getQName(); + assertEquals("my-union", unionType1QName.getLocalName()); + assertEquals(barNS, unionType1QName.getNamespace()); + assertEquals(barRev, unionType1QName.getRevision()); + assertNull(unionType1.getUnits()); + assertNull(unionType1.getDefaultValue()); + assertNull(unionType1.getFractionDigits()); + assertTrue(unionType1.getLengthConstraints().isEmpty()); + assertTrue(unionType1.getPatternConstraints().isEmpty()); + List ranges = unionType1.getRangeConstraints(); + assertEquals(1, ranges.size()); + RangeConstraint range = ranges.get(0); + assertEquals(BigInteger.ONE, range.getMin()); + assertEquals(BigInteger.valueOf(100), range.getMax()); + assertTrue(unionType1.getBaseType() instanceof Int16); + + assertTrue(unionTypes.get(1) instanceof Int32); + } + + @Test + public void testNestedUnionResolving() { + Module foo = TestUtils.findModule(modules, "foo"); + LeafSchemaNode testleaf = (LeafSchemaNode) foo.getDataChildByName("custom-union-leaf"); + + ExtendedType type = (ExtendedType) testleaf.getType(); + QName testleafTypeQName = type.getQName(); + assertEquals(bazNS, testleafTypeQName.getNamespace()); + assertEquals(bazRev, testleafTypeQName.getRevision()); + assertEquals("union1", testleafTypeQName.getLocalName()); + assertNull(type.getUnits()); + assertNull(type.getDefaultValue()); + assertNull(type.getFractionDigits()); + assertTrue(type.getLengthConstraints().isEmpty()); + assertTrue(type.getPatternConstraints().isEmpty()); + assertTrue(type.getRangeConstraints().isEmpty()); + + ExtendedType typeBase = (ExtendedType) type.getBaseType(); + QName typeBaseQName = typeBase.getQName(); + assertEquals(bazNS, typeBaseQName.getNamespace()); + assertEquals(bazRev, typeBaseQName.getRevision()); + assertEquals("union2", typeBaseQName.getLocalName()); + assertNull(typeBase.getUnits()); + assertNull(typeBase.getDefaultValue()); + assertNull(typeBase.getFractionDigits()); + assertTrue(typeBase.getLengthConstraints().isEmpty()); + assertTrue(typeBase.getPatternConstraints().isEmpty()); + assertTrue(typeBase.getRangeConstraints().isEmpty()); + + UnionType union = (UnionType) typeBase.getBaseType(); + List> unionTypes = union.getTypes(); + assertEquals(2, unionTypes.size()); + assertTrue(unionTypes.get(0) instanceof Int32); + assertTrue(unionTypes.get(1) instanceof ExtendedType); + + ExtendedType unionType1 = (ExtendedType) unionTypes.get(1); + QName uniontType1QName = unionType1.getQName(); + assertEquals(barNS, uniontType1QName.getNamespace()); + assertEquals(barRev, uniontType1QName.getRevision()); + assertEquals("nested-union2", uniontType1QName.getLocalName()); + assertNull(unionType1.getUnits()); + assertNull(unionType1.getDefaultValue()); + assertNull(unionType1.getFractionDigits()); + assertTrue(unionType1.getLengthConstraints().isEmpty()); + assertTrue(unionType1.getPatternConstraints().isEmpty()); + assertTrue(unionType1.getRangeConstraints().isEmpty()); + + UnionType nestedUnion = (UnionType) unionType1.getBaseType(); + List> nestedUnion2Types = nestedUnion.getTypes(); + assertEquals(2, nestedUnion2Types.size()); + assertTrue(nestedUnion2Types.get(0) instanceof StringType); + assertTrue(nestedUnion2Types.get(1) instanceof ExtendedType); + + ExtendedType myUnionExt = (ExtendedType) nestedUnion2Types.get(1); + QName myUnionExtQName = myUnionExt.getQName(); + assertEquals(barNS, myUnionExtQName.getNamespace()); + assertEquals(barRev, myUnionExtQName.getRevision()); + assertEquals("my-union-ext", myUnionExtQName.getLocalName()); + assertNull(myUnionExt.getUnits()); + assertNull(myUnionExt.getDefaultValue()); + assertNull(myUnionExt.getFractionDigits()); + assertTrue(myUnionExt.getLengthConstraints().isEmpty()); + assertTrue(myUnionExt.getPatternConstraints().isEmpty()); + assertTrue(myUnionExt.getRangeConstraints().isEmpty()); + + ExtendedType myUnion = (ExtendedType) myUnionExt.getBaseType(); + QName myUnionQName = myUnion.getQName(); + assertEquals(barNS, myUnionQName.getNamespace()); + assertEquals(barRev, myUnionQName.getRevision()); + assertEquals("my-union", myUnionQName.getLocalName()); + assertNull(myUnion.getUnits()); + assertNull(myUnion.getDefaultValue()); + assertNull(myUnion.getFractionDigits()); + assertTrue(myUnion.getLengthConstraints().isEmpty()); + assertTrue(myUnion.getPatternConstraints().isEmpty()); + assertTrue(myUnion.getRangeConstraints().isEmpty()); + + UnionType myUnionBase = (UnionType) myUnion.getBaseType(); + List> myUnionBaseTypes = myUnionBase.getTypes(); + assertEquals(2, myUnionBaseTypes.size()); + assertTrue(myUnionBaseTypes.get(0) instanceof ExtendedType); + assertTrue(myUnionBaseTypes.get(1) instanceof Int32); + + ExtendedType int16Ext = (ExtendedType) myUnionBaseTypes.get(0); + QName int16ExtQName = int16Ext.getQName(); + assertEquals(barNS, int16ExtQName.getNamespace()); + assertEquals(barRev, int16ExtQName.getRevision()); + assertEquals("int16", int16ExtQName.getLocalName()); + assertNull(int16Ext.getUnits()); + assertNull(int16Ext.getDefaultValue()); + assertNull(int16Ext.getFractionDigits()); + assertTrue(int16Ext.getLengthConstraints().isEmpty()); + assertTrue(int16Ext.getPatternConstraints().isEmpty()); + List ranges = int16Ext.getRangeConstraints(); + assertEquals(1, ranges.size()); + RangeConstraint range = ranges.get(0); + assertEquals(BigInteger.ONE, range.getMin()); + assertEquals(BigInteger.valueOf(100), range.getMax()); + + assertTrue(int16Ext.getBaseType() instanceof Int16); + } + + @Test + public void testChoice() { + Module foo = TestUtils.findModule(modules, "foo"); + ContainerSchemaNode transfer = (ContainerSchemaNode) foo.getDataChildByName("transfer"); + ChoiceSchemaNode how = (ChoiceSchemaNode) transfer.getDataChildByName("how"); + Set cases = how.getCases(); + assertEquals(5, cases.size()); + ChoiceCaseNode input = null; + ChoiceCaseNode output = null; + for (ChoiceCaseNode caseNode : cases) { + if ("input".equals(caseNode.getQName().getLocalName())) { + input = caseNode; + } else if ("output".equals(caseNode.getQName().getLocalName())) { + output = caseNode; + } + } + assertNotNull(input); + assertNotNull(input.getPath()); + assertNotNull(output); + assertNotNull(output.getPath()); + } + + @Test + public void testDeviation() { + Module foo = TestUtils.findModule(modules, "foo"); + Set deviations = foo.getDeviations(); + assertEquals(1, deviations.size()); + Deviation dev = deviations.iterator().next(); + assertEquals("system/user ref", dev.getReference()); + + List path = new ArrayList<>(); + path.add(QName.create(barNS, barRev, "interfaces")); + path.add(QName.create(barNS, barRev, "ifEntry")); + SchemaPath expectedPath = SchemaPath.create(path, true); + + assertEquals(expectedPath, dev.getTargetPath()); + assertEquals(Deviate.ADD, dev.getDeviate()); + } + + @Test + public void testUnknownNode() { + Module baz = TestUtils.findModule(modules, "baz"); + ContainerSchemaNode network = (ContainerSchemaNode) baz.getDataChildByName("network"); + List unknownNodes = network.getUnknownSchemaNodes(); + assertEquals(1, unknownNodes.size()); + UnknownSchemaNode unknownNode = unknownNodes.get(0); + assertNotNull(unknownNode.getNodeType()); + assertEquals("point", unknownNode.getNodeParameter()); + } + + @Test + public void testFeature() { + Module baz = TestUtils.findModule(modules, "baz"); + Set features = baz.getFeatures(); + assertEquals(1, features.size()); + } + + @Test + public void testExtension() { + Module baz = TestUtils.findModule(modules, "baz"); + List extensions = baz.getExtensionSchemaNodes(); + assertEquals(1, extensions.size()); + ExtensionDefinition extension = extensions.get(0); + assertEquals("name", extension.getArgument()); + assertEquals("Takes as argument a name string. Makes the code generator use the given name in the #define.", + extension.getDescription()); + assertTrue(extension.isYinElement()); + } + + @Test + public void testNotification() { + Module baz = TestUtils.findModule(modules, "baz"); + String expectedPrefix = "c"; + + Set notifications = baz.getNotifications(); + assertEquals(1, notifications.size()); + + NotificationDefinition notification = notifications.iterator().next(); + // test SchemaNode args + QName expectedQName = QName.create(bazNS, bazRev, "event"); + assertEquals(expectedQName, notification.getQName()); + SchemaPath expectedPath = TestUtils.createPath(true, bazNS, bazRev, expectedPrefix, "event"); + assertEquals(expectedPath, notification.getPath()); + assertNull(notification.getDescription()); + assertNull(notification.getReference()); + assertEquals(Status.CURRENT, notification.getStatus()); + assertEquals(0, notification.getUnknownSchemaNodes().size()); + // test DataNodeContainer args + assertEquals(0, notification.getTypeDefinitions().size()); + assertEquals(3, notification.getChildNodes().size()); + assertEquals(0, notification.getGroupings().size()); + assertEquals(0, notification.getUses().size()); + + LeafSchemaNode eventClass = (LeafSchemaNode) notification.getDataChildByName("event-class"); + assertTrue(eventClass.getType() instanceof StringType); + LeafSchemaNode severity = (LeafSchemaNode) notification.getDataChildByName("severity"); + assertTrue(severity.getType() instanceof StringType); + } + + @Test + public void testRpc() { + Module baz = TestUtils.findModule(modules, "baz"); + + Set rpcs = baz.getRpcs(); + assertEquals(1, rpcs.size()); + + RpcDefinition rpc = rpcs.iterator().next(); + assertEquals("Retrieve all or part of a specified configuration.", rpc.getDescription()); + assertEquals("RFC 6241, Section 7.1", rpc.getReference()); + } + + @Test + public void testTypePath() throws ParseException { + Module bar = TestUtils.findModule(modules, "bar"); + Set> types = bar.getTypeDefinitions(); + + // int32-ext1 + ExtendedType int32ext1 = (ExtendedType) TestUtils.findTypedef(types, "int32-ext1"); + QName int32TypedefQName = int32ext1.getQName(); + + assertEquals(barNS, int32TypedefQName.getNamespace()); + assertEquals(barRev, int32TypedefQName.getRevision()); + assertEquals("int32-ext1", int32TypedefQName.getLocalName()); + + SchemaPath typeSchemaPath = int32ext1.getPath(); + Iterable typePath = typeSchemaPath.getPathFromRoot(); + Iterator typePathIt = typePath.iterator(); + assertEquals(int32TypedefQName, typePathIt.next()); + assertFalse(typePathIt.hasNext()); + + // int32-ext1/int32 + Int32 int32 = (Int32) int32ext1.getBaseType(); + assertEquals(Int32.getInstance(), int32); + } + + @Test + public void testTypePath2() throws ParseException { + Module bar = TestUtils.findModule(modules, "bar"); + Set> types = bar.getTypeDefinitions(); + + // my-decimal-type + ExtendedType myDecType = (ExtendedType) TestUtils.findTypedef(types, "my-decimal-type"); + QName myDecTypeQName = myDecType.getQName(); + + assertEquals(barNS, myDecTypeQName.getNamespace()); + assertEquals(barRev, myDecTypeQName.getRevision()); + assertEquals("my-decimal-type", myDecTypeQName.getLocalName()); + + SchemaPath typeSchemaPath = myDecType.getPath(); + Iterable typePath = typeSchemaPath.getPathFromRoot(); + Iterator typePathIt = typePath.iterator(); + assertEquals(myDecTypeQName, typePathIt.next()); + assertFalse(typePathIt.hasNext()); + + // my-base-int32-type/int32 + Decimal64 dec64 = (Decimal64) myDecType.getBaseType(); + QName dec64QName = dec64.getQName(); + + assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), dec64QName.getNamespace()); + assertNull(dec64QName.getRevision()); + assertEquals("decimal64", dec64QName.getLocalName()); + + SchemaPath dec64SchemaPath = dec64.getPath(); + Iterable dec64Path = dec64SchemaPath.getPathFromRoot(); + Iterator dec64PathIt = dec64Path.iterator(); + assertEquals(myDecTypeQName, dec64PathIt.next()); + assertEquals(dec64QName, dec64PathIt.next()); + assertFalse(dec64PathIt.hasNext()); + } + + @Test + public void testParseMethod1() throws Exception { + File yangFile = new File(getClass().getResource("/parse-methods/m1.yang").toURI()); + File dependenciesDir = new File(getClass().getResource("/parse-methods").toURI()); + YangContextParser parser = new YangParserImpl(); + modules = parser.parseFile(yangFile, dependenciesDir).getModules(); + assertEquals(6, modules.size()); + } + + @Test + public void testParseMethod2() throws Exception { + File yangFile = new File(getClass().getResource("/parse-methods/m1.yang").toURI()); + File dependenciesDir = new File(getClass().getResource("/parse-methods/dependencies").toURI()); + YangContextParser parser = new YangParserImpl(); + modules = parser.parseFile(yangFile, dependenciesDir).getModules(); + assertEquals(6, modules.size()); + } + + // @Test + // public void testSorting() throws Exception { + // // Correct order: m2, m4, m6, m8, m7, m6, m3, m1 + // File yangFile = new File(getClass().getResource("/sorting-test/m1.yang").toURI()); + // File dependenciesDir = new File(getClass().getResource("/sorting-test").toURI()); + // YangContextParser parser = new YangParserImpl(); + // modules = parser.parseFile(yangFile, dependenciesDir).getModules(); + // SchemaContext ctx = new SchemaContextImpl(modules, Collections. emptyMap()); + // checkOrder(modules); + // assertSetEquals(modules, ctx.getModules()); + // + // // ########## + // parser = new YangParserImpl(); + // final File testDir = dependenciesDir; + // final String[] fileList = testDir.list(); + // final List testFiles = new ArrayList<>(); + // if (fileList == null) { + // throw new FileNotFoundException(dependenciesDir.getAbsolutePath()); + // } + // for (String fileName : fileList) { + // testFiles.add(new File(testDir, fileName)); + // } + // Set newModules = parser.parseFiles(testFiles).getModules(); + // assertSetEquals(newModules, modules); + // ctx = new SchemaContextImpl(newModules, Collections. emptyMap()); + // assertSetEquals(newModules, ctx.getModules()); + // // ########## + // newModules = parser.parseFiles(testFiles, null).getModules(); + // assertSetEquals(newModules, modules); + // ctx = new SchemaContextImpl(newModules, Collections. emptyMap()); + // assertSetEquals(newModules, ctx.getModules()); + // // ########## + // List streams = new ArrayList<>(); + // for (File f : testFiles) { + // streams.add(new FileInputStream(f)); + // } + // newModules = parser.parseSources(BuilderUtils.filesToByteSources(testFiles)).getModules(); + // assertSetEquals(newModules, modules); + // ctx = new SchemaContextImpl(newModules, Collections. emptyMap()); + // assertSetEquals(newModules, ctx.getModules()); + // // ########## + // streams.clear(); + // for (File f : testFiles) { + // streams.add(new FileInputStream(f)); + // } + // newModules = parser.parseSources(BuilderUtils.filesToByteSources(testFiles), null).getModules(); + // assertSetEquals(newModules, modules); + // ctx = new SchemaContextImpl(newModules, Collections. emptyMap()); + // assertSetEquals(newModules, ctx.getModules()); + // // ########## + // Map mapped = parser.parseYangModelsMapped(testFiles); + // newModules = new LinkedHashSet<>(mapped.values()); + // assertSetEquals(newModules, modules); + // ctx = new SchemaContextImpl(newModules, Collections. emptyMap()); + // assertSetEquals(newModules, ctx.getModules()); + // // ########## + // streams.clear(); + // for (File f : testFiles) { + // streams.add(new FileInputStream(f)); + // } + // Map mappedStreams = parser.parseYangModelsFromStreamsMapped(streams); + // newModules = new LinkedHashSet<>(mappedStreams.values()); + // assertSetEquals(newModules, modules); + // ctx = new SchemaContextImpl(newModules, Collections. emptyMap()); + // assertSetEquals(newModules, ctx.getModules()); + // } + + private void checkOrder(final Collection modules) { + Iterator it = modules.iterator(); + Module m = it.next(); + assertEquals("m2", m.getName()); + m = it.next(); + assertEquals("m4", m.getName()); + m = it.next(); + assertEquals("m6", m.getName()); + m = it.next(); + assertEquals("m8", m.getName()); + m = it.next(); + assertEquals("m7", m.getName()); + m = it.next(); + assertEquals("m5", m.getName()); + m = it.next(); + assertEquals("m3", m.getName()); + m = it.next(); + assertEquals("m1", m.getName()); + } + + private void assertSetEquals(final Set s1, final Set s2) { + assertEquals(s1, s2); + Iterator it = s1.iterator(); + for (Module m : s2) { + assertEquals(m, it.next()); + } + } + + @Test + public void testSubmodules() { + Module foo = TestUtils.findModule(modules, "foo"); + + DataSchemaNode id = foo.getDataChildByName("id"); + assertNotNull(id); + DataSchemaNode subExt = foo.getDataChildByName("sub-ext"); + assertNotNull(subExt); + DataSchemaNode subTransfer = foo.getDataChildByName("sub-transfer"); + assertNotNull(subTransfer); + + assertEquals(2, foo.getExtensionSchemaNodes().size()); + assertEquals(2, foo.getAugmentations().size()); + } + + @Test + public void unknownStatementInSubmoduleHeaderTest() throws IOException, URISyntaxException { + + File yang = new File(getClass().getResource("/yang-grammar-test/submodule-header-extension.yang").toURI()); + + try { + YangParserImpl.getInstance().parseFile(yang, yang.getParentFile()); + } catch (YangSyntaxErrorException | YangParseException e) { + e.printStackTrace(); + fail("YangSyntaxErrorException or YangParseException should not be thrown"); + } + + } + + @Test + public void unknownStatementBetweenRevisionsTest() throws ReactorException { + + final YangStatementSourceImpl yangModule = new YangStatementSourceImpl( + "/yang-grammar-test/revisions-extension.yang", false); + final YangStatementSourceImpl yangSubmodule = new YangStatementSourceImpl( + "/yang-grammar-test/submodule-header-extension.yang", false); + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, yangModule, yangSubmodule); + + final EffectiveSchemaContext result = reactor.buildEffective(); + assertNotNull(result); + } + + @Test + public void unknownStatementsInStatementsTest() throws ReactorException { + + final YangStatementSourceImpl yangFile1 = new YangStatementSourceImpl( + "/yang-grammar-test/stmtsep-in-statements.yang", false); + final YangStatementSourceImpl yangFile2 = new YangStatementSourceImpl( + "/yang-grammar-test/stmtsep-in-statements2.yang", false); + final YangStatementSourceImpl yangFile3 = new YangStatementSourceImpl( + "/yang-grammar-test/stmtsep-in-statements-sub.yang", false); + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, yangFile1, yangFile2, yangFile3); + // TODO: change test or create new module in order to respect new statement parser validations + try { + final EffectiveSchemaContext result = reactor.buildEffective(); + } catch (Exception e) { + assertEquals(IllegalArgumentException.class, e.getClass()); + assertTrue(e.getMessage().startsWith("aaa is not a YANG statement or use of extension")); + } + } + + 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/retest/YangParserWithContextTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserWithContextTest.java new file mode 100644 index 0000000000..102b04a270 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/YangParserWithContextTest.java @@ -0,0 +1,568 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.retest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; + +import org.opendaylight.yangtools.yang.stmt.test.StmtTestUtils; +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 java.io.File; +import java.math.BigInteger; +import java.net.URI; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.junit.Test; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Deviation; +import org.opendaylight.yangtools.yang.model.api.Deviation.Deviate; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.MustDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.UsesNode; +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; +import org.opendaylight.yangtools.yang.model.util.ExtendedType; +import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; + +public class YangParserWithContextTest { + private final DateFormat simpleDateFormat = new SimpleDateFormat( + "yyyy-MM-dd"); + private final YangParserImpl parser = new YangParserImpl(); + + private static final YangStatementSourceImpl BAR = new YangStatementSourceImpl( + "/model/bar.yang", false); + private static final YangStatementSourceImpl BAZ = new YangStatementSourceImpl( + "/model/baz.yang", false); + private static final YangStatementSourceImpl FOO = new YangStatementSourceImpl( + "/model/foo.yang", false); + private static final YangStatementSourceImpl SUBFOO = new YangStatementSourceImpl( + "/model/subfoo.yang", false); + + private static final YangStatementSourceImpl[] IETF = new YangStatementSourceImpl[] { + new YangStatementSourceImpl("/ietf/iana-afn-safi@2012-06-04.yang", false), + new YangStatementSourceImpl("/ietf/iana-if-type@2012-06-05.yang", false), + new YangStatementSourceImpl("/ietf/iana-timezones@2012-07-09.yang", false), + new YangStatementSourceImpl("/ietf/ietf-inet-types@2010-09-24.yang", false), + new YangStatementSourceImpl("/ietf/ietf-yang-types@2010-09-24.yang", false), + new YangStatementSourceImpl("/ietf/network-topology@2013-07-12.yang", false), + new YangStatementSourceImpl("/ietf/network-topology@2013-10-21.yang", false) + }; + + @Test + public void testTypeFromContext() throws Exception { + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR + .newBuild(); + + YangStatementSourceImpl types = new YangStatementSourceImpl( + "/types/custom-types-test@2012-4-4.yang", false); + YangStatementSourceImpl test1 = new YangStatementSourceImpl( + "/context-test/test1.yang", false); + + StmtTestUtils.addSources(reactor, IETF); + StmtTestUtils.addSources(reactor, types, test1); + + SchemaContext context = reactor.buildEffective(); + + Module module = context.findModuleByName("test1", + SimpleDateFormatUtil.getRevisionFormat().parse("2013-06-18")); + assertNotNull(module); + +// String resource = "/ietf/ietf-inet-types@2010-09-24.yang"; +// InputStream stream = new FileInputStream(new File(getClass() +// .getResource(resource).toURI())); +// SchemaContext context = parser.resolveSchemaContext(TestUtils +// .loadModules(Lists.newArrayList(stream))); +// stream.close(); +// +// resource = "/context-test/test1.yang"; +// InputStream stream2 = new FileInputStream(new File(getClass() +// .getResource(resource).toURI())); +// Module module = TestUtils.loadModuleWithContext("test1", stream2, +// context); +// stream2.close(); +// assertNotNull(module); + + LeafSchemaNode leaf = (LeafSchemaNode) module.getDataChildByName("id"); + + ExtendedType leafType = (ExtendedType) leaf.getType(); + QName qname = leafType.getQName(); + assertEquals(URI.create("urn:simple.demo.test1"), qname.getNamespace()); + assertEquals(simpleDateFormat.parse("2013-06-18"), qname.getRevision()); + assertEquals("port-number", qname.getLocalName()); + + ExtendedType leafBaseType = (ExtendedType) leafType.getBaseType(); + qname = leafBaseType.getQName(); + assertEquals(URI.create("urn:ietf:params:xml:ns:yang:ietf-inet-types"), + qname.getNamespace()); + assertEquals(simpleDateFormat.parse("2010-09-24"), qname.getRevision()); + assertEquals("port-number", qname.getLocalName()); + + ExtendedType dscpExt = (ExtendedType) TestUtils.findTypedef( + module.getTypeDefinitions(), "dscp-ext"); + List ranges = dscpExt.getRangeConstraints(); + assertEquals(1, ranges.size()); + RangeConstraint range = ranges.get(0); + assertEquals(BigInteger.ZERO, range.getMin()); + assertEquals(BigInteger.valueOf(63), range.getMax()); + } + + @Test + public void testUsesFromContext() throws Exception { + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR + .newBuild(); + + YangStatementSourceImpl test2 = new YangStatementSourceImpl( + "/context-test/test2.yang", false); + StmtTestUtils.addSources(reactor, BAZ, FOO, BAR, SUBFOO, test2); + SchemaContext context = reactor.buildEffective(); + + // Module testModule; + // try (InputStream stream = new FileInputStream(new + // File(getClass().getResource("/context-test/test2.yang") + // .toURI()))) { + // testModule = TestUtils.loadModuleWithContext("test2", stream, + // context); + // } + // assertNotNull(testModule); + + // suffix _u = added by uses + // suffix _g = defined in grouping from context + + // get grouping + Module testModule = context.findModuleByName("test2", + SimpleDateFormatUtil.getRevisionFormat().parse("2013-06-18")); + assertNotNull(testModule); + + Module contextModule = context + .findModuleByNamespace(URI.create("urn:opendaylight.baz")) + .iterator().next(); + assertNotNull(contextModule); + Set groupings = contextModule.getGroupings(); + assertEquals(1, groupings.size()); + GroupingDefinition grouping = groupings.iterator().next(); + + // get node containing uses + ContainerSchemaNode peer = (ContainerSchemaNode) testModule + .getDataChildByName("peer"); + ContainerSchemaNode destination = (ContainerSchemaNode) peer + .getDataChildByName("destination"); + + // check uses + Set uses = destination.getUses(); + assertEquals(1, uses.size()); + + // check uses process + AnyXmlSchemaNode data_u = (AnyXmlSchemaNode) destination + .getDataChildByName("data"); + assertNotNull(data_u); + assertTrue(data_u.isAddedByUses()); + + AnyXmlSchemaNode data_g = (AnyXmlSchemaNode) grouping + .getDataChildByName("data"); + assertNotNull(data_g); + assertFalse(data_g.isAddedByUses()); + assertFalse(data_u.equals(data_g)); + + ChoiceSchemaNode how_u = (ChoiceSchemaNode) destination + .getDataChildByName("how"); + assertNotNull(how_u); + assertTrue(how_u.isAddedByUses()); + + ChoiceSchemaNode how_g = (ChoiceSchemaNode) grouping + .getDataChildByName("how"); + assertNotNull(how_g); + assertFalse(how_g.isAddedByUses()); + assertFalse(how_u.equals(how_g)); + + LeafSchemaNode address_u = (LeafSchemaNode) destination + .getDataChildByName("address"); + assertNotNull(address_u); + assertTrue(address_u.isAddedByUses()); + + LeafSchemaNode address_g = (LeafSchemaNode) grouping + .getDataChildByName("address"); + assertNotNull(address_g); + assertFalse(address_g.isAddedByUses()); + assertFalse(address_u.equals(address_g)); + + ContainerSchemaNode port_u = (ContainerSchemaNode) destination + .getDataChildByName("port"); + assertNotNull(port_u); + assertTrue(port_u.isAddedByUses()); + + ContainerSchemaNode port_g = (ContainerSchemaNode) grouping + .getDataChildByName("port"); + assertNotNull(port_g); + assertFalse(port_g.isAddedByUses()); + assertFalse(port_u.equals(port_g)); + + ListSchemaNode addresses_u = (ListSchemaNode) destination + .getDataChildByName("addresses"); + assertNotNull(addresses_u); + assertTrue(addresses_u.isAddedByUses()); + + ListSchemaNode addresses_g = (ListSchemaNode) grouping + .getDataChildByName("addresses"); + assertNotNull(addresses_g); + assertFalse(addresses_g.isAddedByUses()); + assertFalse(addresses_u.equals(addresses_g)); + + // grouping defined by 'uses' + Set groupings_u = destination.getGroupings(); + assertEquals(1, groupings_u.size()); + GroupingDefinition grouping_u = groupings_u.iterator().next(); + assertTrue(grouping_u.isAddedByUses()); + + // grouping defined in 'grouping' node + Set groupings_g = grouping.getGroupings(); + assertEquals(1, groupings_g.size()); + GroupingDefinition grouping_g = groupings_g.iterator().next(); + assertFalse(grouping_g.isAddedByUses()); + assertFalse(grouping_u.equals(grouping_g)); + + List nodes_u = destination.getUnknownSchemaNodes(); + assertEquals(1, nodes_u.size()); + UnknownSchemaNode node_u = nodes_u.get(0); + assertTrue(node_u.isAddedByUses()); + + List nodes_g = grouping.getUnknownSchemaNodes(); + assertEquals(1, nodes_g.size()); + UnknownSchemaNode node_g = nodes_g.get(0); + assertFalse(node_g.isAddedByUses()); + assertFalse(node_u.equals(node_g)); + } + + @Test + public void testUsesRefineFromContext() throws Exception { + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR + .newBuild(); + + YangStatementSourceImpl test2 = new YangStatementSourceImpl( + "/context-test/test2.yang", false); + StmtTestUtils.addSources(reactor, BAZ, FOO, BAR, SUBFOO, test2); + SchemaContext context = reactor.buildEffective(); + + // Module module; + // try (InputStream stream = new FileInputStream(new + // File(getClass().getResource("/context-test/test2.yang") + // .toURI()))) { + // module = TestUtils.loadModuleWithContext("test2", stream, context); + // } + // assertNotNull(module); + + Module module = context.findModuleByName("test2", + SimpleDateFormatUtil.getRevisionFormat().parse("2013-06-18")); + assertNotNull(module); + ContainerSchemaNode peer = (ContainerSchemaNode) module + .getDataChildByName("peer"); + ContainerSchemaNode destination = (ContainerSchemaNode) peer + .getDataChildByName("destination"); + Set usesNodes = destination.getUses(); + assertEquals(1, usesNodes.size()); + UsesNode usesNode = usesNodes.iterator().next(); + + // test grouping path + List path = new ArrayList<>(); + QName qname = QName.create(URI.create("urn:opendaylight.baz"), + simpleDateFormat.parse("2013-02-27"), "target"); + path.add(qname); + SchemaPath expectedPath = SchemaPath.create(path, true); + assertEquals(expectedPath, usesNode.getGroupingPath()); + + // test refine + Map refines = usesNode.getRefines(); + assertEquals(3, refines.size()); + + LeafSchemaNode refineLeaf = null; + ContainerSchemaNode refineContainer = null; + ListSchemaNode refineList = null; + for (Map.Entry entry : refines.entrySet()) { + SchemaNode value = entry.getValue(); + if (value instanceof LeafSchemaNode) { + refineLeaf = (LeafSchemaNode) value; + } else if (value instanceof ContainerSchemaNode) { + refineContainer = (ContainerSchemaNode) value; + } else if (value instanceof ListSchemaNode) { + refineList = (ListSchemaNode) value; + } + } + + // leaf address + assertNotNull(refineLeaf); + assertEquals("address", refineLeaf.getQName().getLocalName()); + assertEquals("description of address defined by refine", + refineLeaf.getDescription()); + assertEquals("address reference added by refine", + refineLeaf.getReference()); + assertFalse(refineLeaf.isConfiguration()); + assertTrue(refineLeaf.getConstraints().isMandatory()); + Set leafMustConstraints = refineLeaf.getConstraints() + .getMustConstraints(); + assertEquals(1, leafMustConstraints.size()); + MustDefinition leafMust = leafMustConstraints.iterator().next(); + assertEquals( + "ifType != 'ethernet' or (ifType = 'ethernet' and ifMTU = 1500)", + leafMust.toString()); + + // container port + assertNotNull(refineContainer); + Set mustConstraints = refineContainer.getConstraints() + .getMustConstraints(); + assertTrue(mustConstraints.isEmpty()); + assertEquals("description of port defined by refine", + refineContainer.getDescription()); + assertEquals("port reference added by refine", + refineContainer.getReference()); + assertFalse(refineContainer.isConfiguration()); + assertTrue(refineContainer.isPresenceContainer()); + + // list addresses + assertNotNull(refineList); + assertEquals("description of addresses defined by refine", + refineList.getDescription()); + assertEquals("addresses reference added by refine", + refineList.getReference()); + assertFalse(refineList.isConfiguration()); + assertEquals(2, (int) refineList.getConstraints().getMinElements()); + assertEquals(12, (int) refineList.getConstraints().getMaxElements()); + } + + @Test + public void testIdentity() throws Exception { + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR + .newBuild(); + + YangStatementSourceImpl types = new YangStatementSourceImpl( + "/types/custom-types-test@2012-4-4.yang", false); + YangStatementSourceImpl test3 = new YangStatementSourceImpl( + "/context-test/test3.yang", false); + + StmtTestUtils.addSources(reactor, IETF); + StmtTestUtils.addSources(reactor, types, test3); + SchemaContext context = reactor.buildEffective(); + + Module module = context.findModuleByName("test3", + SimpleDateFormatUtil.getRevisionFormat().parse("2013-06-18")); + assertNotNull(module); + +// SchemaContext context; +// File yangFile = new File(getClass().getResource( +// "/types/custom-types-test@2012-4-4.yang").toURI()); +// File dependenciesDir = new File(getClass().getResource("/ietf").toURI()); +// YangContextParser parser = new YangParserImpl(); +// context = parser.parseFile(yangFile, dependenciesDir); +// +// Module module; +// try (InputStream stream = new FileInputStream(new File(getClass() +// .getResource("/context-test/test3.yang").toURI()))) { +// module = TestUtils.loadModuleWithContext("test3", stream, context); +// } +// assertNotNull(module); + + Set identities = module.getIdentities(); + assertEquals(1, identities.size()); + + IdentitySchemaNode identity = identities.iterator().next(); + QName idQName = identity.getQName(); + assertEquals(URI.create("urn:simple.demo.test3"), + idQName.getNamespace()); + assertEquals(simpleDateFormat.parse("2013-06-18"), + idQName.getRevision()); + assertEquals("pt", idQName.getLocalName()); + + IdentitySchemaNode baseIdentity = identity.getBaseIdentity(); + QName idBaseQName = baseIdentity.getQName(); + assertEquals(URI.create("urn:custom.types.demo"), + idBaseQName.getNamespace()); + assertEquals(simpleDateFormat.parse("2012-04-16"), + idBaseQName.getRevision()); + assertEquals("service-type", idBaseQName.getLocalName()); + } + + @Test + public void testUnknownNodes() throws Exception { + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR + .newBuild(); + + YangStatementSourceImpl types = new YangStatementSourceImpl( + "/types/custom-types-test@2012-4-4.yang", false); + YangStatementSourceImpl test3 = new YangStatementSourceImpl( + "/context-test/test3.yang", false); + + StmtTestUtils.addSources(reactor, IETF); + StmtTestUtils.addSources(reactor, types, test3); + + SchemaContext context = reactor.buildEffective(); + + Module module = context.findModuleByName("test3", + SimpleDateFormatUtil.getRevisionFormat().parse("2013-06-18")); + assertNotNull(module); + +// SchemaContext context; +// File yangFile = new File(getClass().getResource( +// "/types/custom-types-test@2012-4-4.yang").toURI()); +// File dependenciesDir = new File(getClass().getResource("/ietf").toURI()); +// YangContextParser parser = new YangParserImpl(); +// context = parser.parseFile(yangFile, dependenciesDir); +// +// Module module; +// try (InputStream stream = new FileInputStream(new File(getClass() +// .getResource("/context-test/test3.yang").toURI()))) { +// module = TestUtils.loadModuleWithContext("test3", stream, context); +// } + + ContainerSchemaNode network = (ContainerSchemaNode) module + .getDataChildByName("network"); + List unknownNodes = network.getUnknownSchemaNodes(); + assertEquals(1, unknownNodes.size()); + + UnknownSchemaNode un = unknownNodes.get(0); + QName unType = un.getNodeType(); + assertEquals(URI.create("urn:custom.types.demo"), unType.getNamespace()); + assertEquals(simpleDateFormat.parse("2012-04-16"), unType.getRevision()); + assertEquals("mountpoint", unType.getLocalName()); + assertEquals("point", un.getNodeParameter()); + assertNotNull(un.getExtensionDefinition()); + } + + @Test + public void testAugment() throws Exception { + // load first module + String resource = "/context-augment-test/test4.yang"; + SchemaContext context = parser.parseFiles(Collections + .singleton(new File(getClass().getResource(resource).toURI()))); + + // load another modules and parse them against already existing context + File test1 = new File(getClass().getResource( + "/context-augment-test/test1.yang").toURI()); + File test2 = new File(getClass().getResource( + "/context-augment-test/test2.yang").toURI()); + File test3 = new File(getClass().getResource( + "/context-augment-test/test3.yang").toURI()); + Set modules = parser.parseFiles( + Arrays.asList(test1, test2, test3), context).getModules(); + assertNotNull(modules); + + Module t4 = TestUtils.findModule(modules, "test4"); + ContainerSchemaNode interfaces = (ContainerSchemaNode) t4 + .getDataChildByName("interfaces"); + ListSchemaNode ifEntry = (ListSchemaNode) interfaces + .getDataChildByName("ifEntry"); + + // test augmentation process + ContainerSchemaNode augmentHolder = (ContainerSchemaNode) ifEntry + .getDataChildByName("augment-holder"); + assertNotNull(augmentHolder); + DataSchemaNode ds0 = augmentHolder + .getDataChildByName("ds0ChannelNumber"); + assertNotNull(ds0); + DataSchemaNode interfaceId = augmentHolder + .getDataChildByName("interface-id"); + assertNotNull(interfaceId); + DataSchemaNode higherLayerIf = augmentHolder + .getDataChildByName("higher-layer-if"); + assertNotNull(higherLayerIf); + ContainerSchemaNode schemas = (ContainerSchemaNode) augmentHolder + .getDataChildByName("schemas"); + assertNotNull(schemas); + assertNotNull(schemas.getDataChildByName("id")); + + // test augment target after augmentation: check if it is same instance + ListSchemaNode ifEntryAfterAugment = (ListSchemaNode) interfaces + .getDataChildByName("ifEntry"); + assertTrue(ifEntry == ifEntryAfterAugment); + } + + @Test + public void testDeviation() throws Exception { + + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR + .newBuild(); + + YangStatementSourceImpl bar = new YangStatementSourceImpl( + "/model/bar.yang", false); + YangStatementSourceImpl deviationTest = new YangStatementSourceImpl( + "/context-test/deviation-test.yang", false); + + StmtTestUtils.addSources(reactor, bar, deviationTest); + SchemaContext context = reactor.buildEffective(); + + Module testModule = context.findModuleByName("deviation-test", + SimpleDateFormatUtil.getRevisionFormat().parse("2013-02-27")); + assertNotNull(testModule); + + // load first module +// SchemaContext context; +// String resource = "/model/bar.yang"; +// +// try (InputStream stream = new FileInputStream(new File(getClass() +// .getResource(resource).toURI()))) { +// context = parser.resolveSchemaContext(TestUtils.loadModules(Lists +// .newArrayList(stream))); +// } + + // load another modules and parse them against already existing context +// Set modules; +// try (InputStream stream = new FileInputStream(new File(getClass() +// .getResource("/context-test/deviation-test.yang").toURI()))) { +// List input = Lists.newArrayList(stream); +// modules = TestUtils.loadModulesWithContext(input, context); +// } +// assertNotNull(modules); + + // test deviation + //Module testModule = TestUtils.findModule(modules, "deviation-test"); + + + Set deviations = testModule.getDeviations(); + assertEquals(1, deviations.size()); + Deviation dev = deviations.iterator().next(); + + assertEquals("system/user ref", dev.getReference()); + + URI expectedNS = URI.create("urn:opendaylight.bar"); + DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + Date expectedRev = simpleDateFormat.parse("2013-07-03"); + List path = new ArrayList<>(); + path.add(QName.create(expectedNS, expectedRev, "interfaces")); + path.add(QName.create(expectedNS, expectedRev, "ifEntry")); + SchemaPath expectedPath = SchemaPath.create(path, true); + + assertEquals(expectedPath, dev.getTargetPath()); + assertEquals(Deviate.ADD, dev.getDeviate()); + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/package-info.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/package-info.java new file mode 100644 index 0000000000..fc98bd3f31 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/package-info.java @@ -0,0 +1,13 @@ +/* + * 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 + */ + +/** + * This package consists of JUnit tests run against new statement parser + * in order to check and achieve desired functionality + */ +package org.opendaylight.yangtools.yang.stmt.retest; \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentProcessTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentProcessTest.java index 64d4b63edb..fb6bd84e33 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentProcessTest.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentProcessTest.java @@ -1,8 +1,17 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + package org.opendaylight.yangtools.yang.stmt.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; + import com.google.common.collect.ImmutableList; import java.net.URI; import org.junit.Test; @@ -21,18 +30,19 @@ 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 org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; public class AugmentProcessTest { private static final YangStatementSourceImpl AUGMENTED = new YangStatementSourceImpl( - "/stmt-test/augments/augmented.yang"); + "/stmt-test/augments/augmented.yang", false); private static final YangStatementSourceImpl ROOT = new YangStatementSourceImpl( - "/stmt-test/augments/aug-root.yang"); + "/stmt-test/augments/aug-root.yang", false); private static final QNameModule ROOT_QNAME_MODULE = QNameModule.create( - URI.create("root"), null); + URI.create("root"), SimpleDateFormatUtil.DEFAULT_DATE_REV); private static final QNameModule AUGMENTED_QNAME_MODULE = QNameModule - .create(URI.create("aug"), null); + .create(URI.create("aug"), SimpleDateFormatUtil.DEFAULT_DATE_REV); private static GroupingDefinition grp2Def; @@ -43,17 +53,17 @@ public class AugmentProcessTest { private final QName contTarget = QName.create(AUGMENTED_QNAME_MODULE, "cont-target"); - private final QName contAdded1 = QName.create(AUGMENTED_QNAME_MODULE, + private final QName contAdded1 = QName.create(ROOT_QNAME_MODULE, "cont-added1"); - private final QName contAdded2 = QName.create(AUGMENTED_QNAME_MODULE, + private final QName contAdded2 = QName.create(ROOT_QNAME_MODULE, "cont-added2"); - private final QName list1 = QName.create(AUGMENTED_QNAME_MODULE, "list1"); - private final QName axml = QName.create(AUGMENTED_QNAME_MODULE, "axml"); + private final QName list1 = QName.create(ROOT_QNAME_MODULE, "list1"); + private final QName axml = QName.create(ROOT_QNAME_MODULE, "axml"); - private final QName contGrp = QName.create(AUGMENTED_QNAME_MODULE, + private final QName contGrp = QName.create(ROOT_QNAME_MODULE, "cont-grp"); - private final QName axmlGrp = QName.create(AUGMENTED_QNAME_MODULE, + private final QName axmlGrp = QName.create(ROOT_QNAME_MODULE, "axml-grp"); private final QName augCont1 = QName.create(ROOT_QNAME_MODULE, "aug-cont1"); @@ -65,27 +75,28 @@ public class AugmentProcessTest { 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"); + "/stmt-test/augments/multiple-augment-test.yang",false); private static final YangStatementSourceImpl MULTIPLE_AUGMENT_ROOT = new YangStatementSourceImpl( - "/stmt-test/augments/multiple-augment-root.yang"); + "/stmt-test/augments/multiple-augment-root.yang",false); private static final YangStatementSourceImpl MULTIPLE_AUGMENT_IMPORTED = new YangStatementSourceImpl( - "/stmt-test/augments/multiple-augment-imported.yang"); + "/stmt-test/augments/multiple-augment-imported.yang",false); private static final YangStatementSourceImpl MULTIPLE_AUGMENT_SUBMODULE = new YangStatementSourceImpl( - "/stmt-test/augments/multiple-augment-submodule.yang"); + "/stmt-test/augments/multiple-augment-submodule.yang",false); private static final YangStatementSourceImpl MULTIPLE_AUGMENT_INCORRECT = new YangStatementSourceImpl( - "/stmt-test/augments/multiple-augment-incorrect.yang"); + "/stmt-test/augments/multiple-augment-incorrect.yang",false); private static final YangStatementSourceImpl MULTIPLE_AUGMENT_INCORRECT2 = new YangStatementSourceImpl( - "/stmt-test/augments/multiple-augment-incorrect2.yang"); + "/stmt-test/augments/multiple-augment-incorrect2.yang",false); @Test - public void multipleAugmentsAndMultipleModulesTest() throws SourceException, - ReactorException { + public void multipleAugmentsAndMultipleModulesTest() + throws SourceException, ReactorException { CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR .newBuild(); - addSources(reactor, MULTIPLE_AUGMENT_ROOT, MULTIPLE_AUGMENT_IMPORTED, MULTIPLE_AUGMENT_SUBMODULE); + addSources(reactor, MULTIPLE_AUGMENT_ROOT, MULTIPLE_AUGMENT_IMPORTED, + MULTIPLE_AUGMENT_SUBMODULE); EffectiveSchemaContext result = null; try { @@ -129,8 +140,8 @@ public class AugmentProcessTest { } @Test - public void multipleAugmentIncorrectPathAndGrpTest() throws SourceException, - ReactorException { + public void multipleAugmentIncorrectPathAndGrpTest() + throws SourceException, ReactorException { CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR .newBuild(); addSources(reactor, MULTIPLE_AUGMENT_INCORRECT2); diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentSimplestTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentSimplestTest.java index c4c0ea4231..e64cc5b9a4 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentSimplestTest.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentSimplestTest.java @@ -1,6 +1,15 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + package org.opendaylight.yangtools.yang.stmt.test; import static org.junit.Assert.assertNotNull; + import org.junit.Test; import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; @@ -8,11 +17,12 @@ import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource; import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; 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 AugmentSimplestTest { - private static final TestYangFileStatementSource AUGMENTED = new TestYangFileStatementSource("/semantic-statement-parser/augmented.yang"); - private static final TestYangFileStatementSource ROOT = new TestYangFileStatementSource("/semantic-statement-parser/root.yang"); + private static final YangStatementSourceImpl AUGMENTED = new YangStatementSourceImpl("/semantic-statement-parser/augmented.yang", false); + private static final YangStatementSourceImpl ROOT = new YangStatementSourceImpl("/semantic-statement-parser/root.yang", false); @Test public void readAndParseYangFileTest() throws SourceException, ReactorException { diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentTest.java index ff5c2b5395..defa39070e 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentTest.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/AugmentTest.java @@ -22,22 +22,22 @@ import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceIm public class AugmentTest { private static final YangStatementSourceImpl IMPORTED = new YangStatementSourceImpl( - "/semantic-statement-parser/augment-arg-parsing/imported.yang"); + "/semantic-statement-parser/augment-arg-parsing/imported.yang", false); private static YangStatementSourceImpl VALID_ARGS = new YangStatementSourceImpl( - "/semantic-statement-parser/augment-arg-parsing/root-valid-aug-args.yang"); + "/semantic-statement-parser/augment-arg-parsing/root-valid-aug-args.yang", false); private static YangStatementSourceImpl INVALID_REL1 = new YangStatementSourceImpl( - "/semantic-statement-parser/augment-arg-parsing/root-invalid-rel1.yang"); + "/semantic-statement-parser/augment-arg-parsing/root-invalid-rel1.yang", false); private static YangStatementSourceImpl INVALID_REL2 = new YangStatementSourceImpl( - "/semantic-statement-parser/augment-arg-parsing/root-invalid-rel2.yang"); + "/semantic-statement-parser/augment-arg-parsing/root-invalid-rel2.yang", false); private static YangStatementSourceImpl INVALID_ABS = new YangStatementSourceImpl( - "/semantic-statement-parser/augment-arg-parsing/root-invalid-abs.yang"); + "/semantic-statement-parser/augment-arg-parsing/root-invalid-abs.yang", false); private static YangStatementSourceImpl INVALID_ABS_PREFIXED_NO_IMP = new YangStatementSourceImpl( - "/semantic-statement-parser/augment-arg-parsing/root-invalid-abs-no-imp.yang"); + "/semantic-statement-parser/augment-arg-parsing/root-invalid-abs-no-imp.yang", false); private static YangStatementSourceImpl INVALID_EMPTY = new YangStatementSourceImpl( - "/semantic-statement-parser/augment-arg-parsing/root-invalid-empty.yang"); + "/semantic-statement-parser/augment-arg-parsing/root-invalid-empty.yang", false); private static YangStatementSourceImpl INVALID_XPATH = new YangStatementSourceImpl( - "/semantic-statement-parser/augment-arg-parsing/root-invalid-xpath.yang"); + "/semantic-statement-parser/augment-arg-parsing/root-invalid-xpath.yang", false); @Test public void validAugAbsTest() throws SourceException, ReactorException { diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportBasicTestStatementSource.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportBasicTestStatementSource.java deleted file mode 100644 index 33a458cb8f..0000000000 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportBasicTestStatementSource.java +++ /dev/null @@ -1,162 +0,0 @@ -/** - * 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.stmt.test; - -import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.CONTAINER; -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 static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.REVISION; -import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.REVISION_DATE; -import java.util.Arrays; -import java.util.List; -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; - -class ImportBasicTestStatementSource implements StatementStreamSource { - - private static final String NS_PREFIX = "urn:org:opendaylight:yangtools:test:"; - - private final String name; - private final List imports; - private StatementWriter writer; - private final StatementSourceReference REF = new StatementSourceReference() { - - @Override - public StatementSource getStatementSource() { - return StatementSource.DECLARATION; - } - }; - - - public ImportBasicTestStatementSource(final String name, final String... imports) { - this.name = name; - this.imports = Arrays.asList(imports); - } - - @Override - public void writeFull(final StatementWriter writer, final QNameToStatementDefinition stmtDef, final PrefixToModule prefixes) - throws SourceException { - this.writer = writer; - header(); - extensions(); - body(); - end(); - - } - - - - @Override - public void writeLinkage(final StatementWriter writer, final QNameToStatementDefinition stmtDef) throws SourceException { - this.writer = writer; - header().end(); - } - - @Override - public void writeLinkageAndStatementDefinitions(final StatementWriter writer, final QNameToStatementDefinition stmtDef, - final PrefixToModule prefixes) throws SourceException { - this.writer = writer; - header(); - extensions(); - end(); - - } - - protected void extensions() throws SourceException { - - } - - protected void body() throws SourceException { -// stmt(YangVersion).arg("1");end(); -// stmt(Description).arg("Here goes description of this module");end(); -// stmt(Contact).arg("Here goes our address...");end(); -// -// stmt(Revision).arg("2015-03-12"); -// stmt(Description).arg("This revision brings this and that...");end(); -// stmt(Reference).arg("Learn more here...");end(); -// end(); - - stmt(CONTAINER).arg(name+":my-container-with-prefix"); -// stmt(Leaf).arg("MyContainerLeaf"); -// stmt(Type).arg("string");end(); -// stmt(Config).arg("TRUE");end(); -// end(); -// stmt(Choice).arg("choose-your-destiny"); -// stmt(Default).arg("destiny-one");end(); -// stmt(Case).arg("destiny-one"); -// stmt(Leaf).arg("destiny-one-leaf");end(); -// end(); -// stmt(Case).arg("destiny-two"); -// stmt(Mandatory).arg("true"); -// stmt(Container).arg("InnerContainer"); -// stmt(Leaf).arg("leaf-of-deep");end(); -// end(); -// end(); -// end(); -// stmt(Container).arg("MyContainerInContainer"); -// stmt(Must).arg("xpath expression"); -// stmt(Leaf).arg("MyContainerInContainerLeaf"); -// stmt(Type).arg("string");end(); -// end(); -// stmt(Deviation).arg("/tst:test/tst:element"); -// stmt(Deviate).arg("add");end(); -// end(); -// end(); - end(); - stmt(CONTAINER).arg("my-container-without-prefix").end(); - - int i = 0; - for(String imp : imports) { - i++; - stmt(CONTAINER).arg(imp+":my-container-with-imported-prefix"+i).end(); - } - - } - - ImportBasicTestStatementSource header() throws SourceException { - stmt(MODULE).arg(name); { - stmt(NAMESPACE).arg(getNamespace()).end(); - stmt(PREFIX).arg(name).end(); - stmt(REVISION).arg("2000-01-01").end(); - for(String imp : imports) { - stmt(IMPORT).arg(imp); - stmt(PREFIX).arg(imp).end(); - stmt(REVISION_DATE).arg("2000-01-01").end(); - end(); - } - } - return this; - } - - private String getNamespace() { - return NS_PREFIX + name; - } - - protected ImportBasicTestStatementSource arg(final String arg) throws SourceException { - writer.argumentValue(arg, REF); - return this; - } - - protected ImportBasicTestStatementSource stmt(final Rfc6020Mapping stmt) throws SourceException { - writer.startStatement(stmt.getStatementName(), REF); - return this; - } - - protected ImportBasicTestStatementSource end() throws SourceException { - writer.endStatement(REF); - return this; - } -} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportResolutionBasicTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportResolutionBasicTest.java index 1ee23a4daa..8501ae4217 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportResolutionBasicTest.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportResolutionBasicTest.java @@ -12,7 +12,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; + import org.junit.Test; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException; @@ -20,21 +22,32 @@ 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 ImportResolutionBasicTest { - private static final ImportBasicTestStatementSource ROOT_WITHOUT_IMPORT = new ImportBasicTestStatementSource("nature"); - private static final ImportBasicTestStatementSource IMPORT_ROOT = new ImportBasicTestStatementSource("mammal","nature"); - private static final ImportBasicTestStatementSource IMPORT_DERIVED = new ImportBasicTestStatementSource("human", "mammal"); - private static final ImportBasicTestStatementSource IMPORT_SELF = new ImportBasicTestStatementSource("egocentric", "egocentric"); - private static final ImportBasicTestStatementSource CICLE_YIN = new ImportBasicTestStatementSource("cycle-yin", "cycle-yang"); - private static final ImportBasicTestStatementSource CICLE_YANG = new ImportBasicTestStatementSource("cycle-yang", "cycle-yin"); + private static final YangStatementSourceImpl ROOT_WITHOUT_IMPORT = new YangStatementSourceImpl( + "/semantic-statement-parser/import-arg-parsing/nature.yang", false); + private static final YangStatementSourceImpl IMPORT_ROOT = new YangStatementSourceImpl( + "/semantic-statement-parser/import-arg-parsing/mammal.yang", false); + private static final YangStatementSourceImpl IMPORT_DERIVED = new YangStatementSourceImpl( + "/semantic-statement-parser/import-arg-parsing/human.yang", false); + private static final YangStatementSourceImpl IMPORT_SELF = new YangStatementSourceImpl( + "/semantic-statement-parser/import-arg-parsing/egocentric.yang", false); + private static final YangStatementSourceImpl CYCLE_YIN = new YangStatementSourceImpl( + "/semantic-statement-parser/import-arg-parsing/cycle-yin.yang", false); + private static final YangStatementSourceImpl CYCLE_YANG = new YangStatementSourceImpl( + "/semantic-statement-parser/import-arg-parsing/cycle-yang.yang", false); + private static final YangStatementSourceImpl FOO = new YangStatementSourceImpl( + "/semantic-statement-parser/bug2649/foo.yang", false); + private static final YangStatementSourceImpl IMPORT = new YangStatementSourceImpl( + "/semantic-statement-parser/bug2649/import-module.yang", false); @Test public void inImportOrderTest() throws SourceException, ReactorException { BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor,ROOT_WITHOUT_IMPORT,IMPORT_ROOT,IMPORT_DERIVED); + addSources(reactor, ROOT_WITHOUT_IMPORT, IMPORT_ROOT, IMPORT_DERIVED); EffectiveModelContext result = reactor.build(); assertNotNull(result); } @@ -42,7 +55,7 @@ public class ImportResolutionBasicTest { @Test public void inInverseOfImportOrderTest() throws SourceException, ReactorException { BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor,IMPORT_DERIVED,IMPORT_ROOT,ROOT_WITHOUT_IMPORT); + addSources(reactor, IMPORT_DERIVED, IMPORT_ROOT, ROOT_WITHOUT_IMPORT); EffectiveModelContext result = reactor.build(); assertNotNull(result); } @@ -50,13 +63,13 @@ public class ImportResolutionBasicTest { @Test public void missingImportedSourceTest() throws SourceException { BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor,IMPORT_DERIVED,ROOT_WITHOUT_IMPORT); + addSources(reactor, IMPORT_DERIVED, ROOT_WITHOUT_IMPORT); try { reactor.build(); - fail("reactor.process should fail doe to misssing imported source"); + fail("reactor.process should fail due to missing imported source"); } catch (ReactorException e) { assertTrue(e instanceof SomeModifiersUnresolvedException); - assertEquals(ModelProcessingPhase.SOURCE_LINKAGE,e.getPhase()); + assertEquals(ModelProcessingPhase.SOURCE_LINKAGE, e.getPhase()); } } @@ -64,32 +77,40 @@ public class ImportResolutionBasicTest { @Test public void circularImportsTest() throws SourceException { BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor,CICLE_YIN,CICLE_YANG); + addSources(reactor, CYCLE_YIN, CYCLE_YANG); try { reactor.build(); - fail("reactor.process should fail doe to circular import"); + fail("reactor.process should fail due to circular import"); } catch (ReactorException e) { assertTrue(e instanceof SomeModifiersUnresolvedException); - assertEquals(ModelProcessingPhase.SOURCE_LINKAGE,e.getPhase()); + assertEquals(ModelProcessingPhase.SOURCE_LINKAGE, e.getPhase()); } } @Test public void selfImportTest() throws SourceException { BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor,IMPORT_SELF,IMPORT_ROOT,ROOT_WITHOUT_IMPORT); + addSources(reactor, IMPORT_SELF, IMPORT_ROOT, ROOT_WITHOUT_IMPORT); try { reactor.build(); - fail("reactor.process should fail doe to self import"); + fail("reactor.process should fail due to self import"); } catch (ReactorException e) { assertTrue(e instanceof SomeModifiersUnresolvedException); - assertEquals(ModelProcessingPhase.SOURCE_LINKAGE,e.getPhase()); + assertEquals(ModelProcessingPhase.SOURCE_LINKAGE, e.getPhase()); } } + @Test + public void bug2649Test() throws SourceException, ReactorException{ + BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, FOO, IMPORT); + + EffectiveSchemaContext buildEffective = reactor.buildEffective(); + assertNotNull(buildEffective); + } - private static void addSources(final BuildAction reactor, final ImportBasicTestStatementSource... sources) { - for(ImportBasicTestStatementSource source : sources) { + private void addSources(final BuildAction reactor, final YangStatementSourceImpl... sources) { + for (YangStatementSourceImpl source : sources) { reactor.addSource(source); } } diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportResolutionTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportResolutionTest.java deleted file mode 100644 index e763ad9ad2..0000000000 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportResolutionTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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.stmt.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Test; -import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; -import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; -import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException; -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.stmt.test.TestStatementSource.ModuleEntry; - -public class ImportResolutionTest { - - private static final ModuleEntry modNature = new ModuleEntry("nature", "2000-01-01"); - private static final ModuleEntry modMammal = new ModuleEntry("mammal", "2000-01-01"); - private static final ModuleEntry modHuman = new ModuleEntry("human", "2000-01-01"); - private static final ModuleEntry modEgocentric = new ModuleEntry("egocentric", "2000-01-01"); - private static final ModuleEntry modCycleYin = new ModuleEntry("cycle-yin", "2000-01-01"); - private static final ModuleEntry modCycleYang = new ModuleEntry("cycle-yang", "2000-01-01"); - - private static final TestStatementSource ROOT_WITHOUT_IMPORT = new TestStatementSource(modNature); - private static final TestStatementSource IMPORT_ROOT = new TestStatementSource(modMammal, modNature); - private static final TestStatementSource IMPORT_DERIVED = new TestStatementSource(modHuman, modMammal); - private static final TestStatementSource IMPORT_SELF = new TestStatementSource(modEgocentric, modEgocentric); - private static final TestStatementSource CICLE_YIN = new TestStatementSource(modCycleYin, modCycleYang); - private static final TestStatementSource CICLE_YANG = new TestStatementSource(modCycleYang, modCycleYin); - - @Test - public void inImportOrderTest() throws SourceException, ReactorException { - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, ROOT_WITHOUT_IMPORT, IMPORT_ROOT, IMPORT_DERIVED); - EffectiveModelContext result = reactor.build(); - assertNotNull(result); - } - - @Test - public void inInverseOfImportOrderTest() throws SourceException, ReactorException { - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, IMPORT_DERIVED, IMPORT_ROOT, ROOT_WITHOUT_IMPORT); - EffectiveModelContext result = reactor.build(); - assertNotNull(result); - } - - @Test - public void missingImportedSourceTest() throws SourceException { - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, IMPORT_DERIVED, ROOT_WITHOUT_IMPORT); - try { - reactor.build(); - fail("reactor.process should fail due to misssing imported source"); - } catch (ReactorException e) { - assertTrue(e instanceof SomeModifiersUnresolvedException); - assertEquals(ModelProcessingPhase.SOURCE_LINKAGE, e.getPhase()); - } - } - - @Test - public void circularImportsTest() throws SourceException { - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, CICLE_YIN, CICLE_YANG); - try { - reactor.build(); - fail("reactor.process should fail due to circular import"); - } catch (ReactorException e) { - assertTrue(e instanceof SomeModifiersUnresolvedException); - assertEquals(ModelProcessingPhase.SOURCE_LINKAGE, e.getPhase()); - } - } - - @Test - public void selfImportTest() throws SourceException { - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, IMPORT_SELF, IMPORT_ROOT, ROOT_WITHOUT_IMPORT); - try { - reactor.build(); - fail("reactor.process should fail due to self import"); - } catch (ReactorException e) { - assertTrue(e instanceof SomeModifiersUnresolvedException); - assertEquals(ModelProcessingPhase.SOURCE_LINKAGE, e.getPhase()); - } - } - - private static void addSources(final BuildAction reactor, final TestStatementSource... sources) { - for (TestStatementSource source : sources) { - reactor.addSource(source); - } - } - -} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportRevisionsTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportRevisionsTest.java deleted file mode 100644 index 578fd6df6b..0000000000 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ImportRevisionsTest.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.opendaylight.yangtools.yang.stmt.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Test; -import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; -import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; -import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException; -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.stmt.test.TestStatementSource.ModuleEntry; - -public class ImportRevisionsTest { - - private static final ModuleEntry modImported = new ModuleEntry("nature", "2006-05-05"); - private static final ModuleEntry modImportedRevDiff = new ModuleEntry("nature", "2011-12-12"); - private static final ModuleEntry modImportedRevMiss = new ModuleEntry("nature", null); - private static final ModuleEntry modImported1970 = new ModuleEntry("nature", "1970-01-01"); - - private static final ModuleEntry modImporter = new ModuleEntry("mammal", "2006-05-05"); - - private static final TestStatementSource IMPORTED = new TestStatementSource(modImported); - private static final TestStatementSource IMPORTED_NO_REV = new TestStatementSource(modImportedRevMiss); - - private static final TestStatementSource IMPORT = new TestStatementSource(modImporter, modImported); - private static final TestStatementSource IMPORT_REV_DFLT = new TestStatementSource(modImporter, modImported1970); - private static final TestStatementSource IMPORT_REV_DIFF = new TestStatementSource(modImporter, modImportedRevDiff); - private static final TestStatementSource IMPORT_NO_REV = new TestStatementSource(modImporter, modImportedRevMiss); - - @Test - public void revsEqualTest() throws SourceException, ReactorException { - - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, IMPORTED, IMPORT); - - EffectiveModelContext result = reactor.build(); - assertNotNull(result); - } - - @Test - public void revsDiffTest() throws SourceException { - - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, IMPORTED, IMPORT_REV_DIFF); - - try { - reactor.build(); - fail("reactor.process should fail due to unequal revisions in imported modules"); - } catch (ReactorException e) { - assertTrue(e instanceof SomeModifiersUnresolvedException); - assertEquals(ModelProcessingPhase.SOURCE_LINKAGE, e.getPhase()); - } - } - - @Test - public void revInModuleOnly() throws SourceException, ReactorException { - - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, IMPORTED, IMPORT_NO_REV); - - EffectiveModelContext result = reactor.build(); - assertNotNull(result); - } - - @Test - public void revImportOnly() throws SourceException { - - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, IMPORTED_NO_REV, IMPORT); - - try { - reactor.build(); - fail("reactor.process should fail due to missing revision in imported module"); - } catch (ReactorException e) { - assertTrue(e instanceof SomeModifiersUnresolvedException); - assertEquals(ModelProcessingPhase.SOURCE_LINKAGE, e.getPhase()); - } - } - - @Test - public void revDefault1970InImport() throws SourceException, ReactorException { - - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, IMPORTED_NO_REV, IMPORT_REV_DFLT); - - EffectiveModelContext result = reactor.build(); - assertNotNull(result); - } - - @Test - public void revNowhere() throws SourceException, ReactorException { - - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, IMPORTED_NO_REV, IMPORT_NO_REV); - - EffectiveModelContext result = reactor.build(); - assertNotNull(result); - } - - private static void addSources(final BuildAction reactor, final TestStatementSource... sources) { - for (TestStatementSource source : sources) { - reactor.addSource(source); - } - } -} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/IncludeResolutionTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/IncludeResolutionTest.java index f44189fb7f..6c49007758 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/IncludeResolutionTest.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/IncludeResolutionTest.java @@ -4,6 +4,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; + import java.util.logging.Logger; import org.junit.Test; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; @@ -13,22 +14,30 @@ 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 IncludeResolutionTest { private static final Logger log = Logger.getLogger(IncludeResolutionTest.class.getName()); - private static final IncludeTestStatementSource ROOT = new IncludeTestStatementSource(false,"root-module",null, "submodule-1"); - private static final IncludeTestStatementSource SUBMODULE1 = new IncludeTestStatementSource(true,"submodule-1","root-module", "submodule-2"); - private static final IncludeTestStatementSource SUBMODULE2 = new IncludeTestStatementSource(true,"submodule-2", "root-module"); - private static final IncludeTestStatementSource ERROR_MODULE = new IncludeTestStatementSource(false,"error-module", null, "foo"); - private static final IncludeTestStatementSource ERROR_SUBMODULE = new IncludeTestStatementSource(true,"error-submodule", "root-module", "foo"); + private static final YangStatementSourceImpl ROOT = new YangStatementSourceImpl( + "/semantic-statement-parser/include-arg-parsing/root-module.yang", false); + private static final YangStatementSourceImpl SUBMODULE1 = new YangStatementSourceImpl( + "/semantic-statement-parser/include-arg-parsing/submodule-1.yang", false); + private static final YangStatementSourceImpl SUBMODULE2 = new YangStatementSourceImpl( + "/semantic-statement-parser/include-arg-parsing/submodule-2.yang", false); + private static final YangStatementSourceImpl ERROR_MODULE = new YangStatementSourceImpl( + "/semantic-statement-parser/include-arg-parsing/error-module.yang", false); + private static final YangStatementSourceImpl ERROR_SUBMODULE = new YangStatementSourceImpl( + "/semantic-statement-parser/include-arg-parsing/error-submodule.yang", false); + + private static final YangStatementSourceImpl MISSING_PARENT_MODULE = new YangStatementSourceImpl( + "/semantic-statement-parser/include-arg-parsing/missing-parent.yang", false); - private static final IncludeTestStatementSource MISSING_PARENT_MODULE = new IncludeTestStatementSource(true,"missing-parent", "foo"); @Test public void includeTest() throws SourceException, ReactorException { BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor,ROOT,SUBMODULE1,SUBMODULE2); + addSources(reactor, ROOT, SUBMODULE1, SUBMODULE2); EffectiveModelContext result = reactor.build(); assertNotNull(result); } @@ -36,13 +45,13 @@ public class IncludeResolutionTest { @Test public void missingIncludedSourceTest() throws SourceException { BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor,ERROR_MODULE); + addSources(reactor, ERROR_MODULE); try { reactor.build(); - fail("reactor.process should fail doe to misssing included source"); + fail("reactor.process should fail due to missing included source"); } catch (ReactorException e) { assertTrue(e instanceof SomeModifiersUnresolvedException); - assertEquals(ModelProcessingPhase.SOURCE_LINKAGE,e.getPhase()); + assertEquals(ModelProcessingPhase.SOURCE_LINKAGE, e.getPhase()); log.info(e.getMessage()); } @@ -51,37 +60,34 @@ public class IncludeResolutionTest { @Test public void missingIncludedSourceTest2() throws SourceException { BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor,ERROR_SUBMODULE); + addSources(reactor, ERROR_SUBMODULE); try { reactor.build(); - fail("reactor.process should fail doe to misssing included source"); + fail("reactor.process should fail due to missing included source"); } catch (ReactorException e) { assertTrue(e instanceof SomeModifiersUnresolvedException); - assertEquals(ModelProcessingPhase.SOURCE_LINKAGE,e.getPhase()); + assertEquals(ModelProcessingPhase.SOURCE_LINKAGE, e.getPhase()); log.info(e.getMessage()); } } - //@Test + @Test public void missingIncludedSourceTest3() throws SourceException, ReactorException { BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor,MISSING_PARENT_MODULE); + addSources(reactor, MISSING_PARENT_MODULE); try { - EffectiveModelContext build = reactor.build(); - //fail("reactor.process should fail doe to misssing belongsTo source"); + reactor.build(); + fail("reactor.process should fail due to missing belongsTo source"); } catch (ReactorException e) { - //assertTrue(e instanceof SomeModifiersUnresolvedException); - //assertEquals(ModelProcessingPhase.SourceLinkage,e.getPhase()); - throw(e); + log.info(e.getMessage()); } } - private static void addSources(final BuildAction reactor, final IncludeTestStatementSource... sources) { - for(IncludeTestStatementSource source : sources) { + private void addSources(final BuildAction reactor, final YangStatementSourceImpl... sources) { + for (YangStatementSourceImpl source : sources) { reactor.addSource(source); } } - } diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/IncludeRevisionsTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/IncludeRevisionsTest.java index 2b3f49754e..0b48f1f2c3 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/IncludeRevisionsTest.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/IncludeRevisionsTest.java @@ -17,19 +17,30 @@ import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceIm public class IncludeRevisionsTest { - private static final YangStatementSourceImpl EQUAL_ROOT = new YangStatementSourceImpl("/revisions/equal-root.yang"); - private static final YangStatementSourceImpl EQUAL_REV = new YangStatementSourceImpl("/revisions/equal-rev.yang"); - private static final YangStatementSourceImpl UNEQUAL_ROOT = new YangStatementSourceImpl("/revisions/unequal-root.yang"); - private static final YangStatementSourceImpl UNEQUAL_REV = new YangStatementSourceImpl("/revisions/unequal-rev.yang"); - private static final YangStatementSourceImpl SUBMOD_ONLY_ROOT = new YangStatementSourceImpl("/revisions/submod-only-root.yang"); - private static final YangStatementSourceImpl SUBMOD_ONLY_REV = new YangStatementSourceImpl("/revisions/submod-only-rev.yang"); - private static final YangStatementSourceImpl MOD_ONLY_ROOT = new YangStatementSourceImpl("/revisions/mod-only-root.yang"); - private static final YangStatementSourceImpl MOD_ONLY_REV = new YangStatementSourceImpl("/revisions/mod-only-rev.yang"); - private static final YangStatementSourceImpl MOD_ONLY_1970_ROOT = new YangStatementSourceImpl("/revisions/mod-1970-root.yang"); - private static final YangStatementSourceImpl MOD_ONLY_1970_REV = new YangStatementSourceImpl("/revisions/mod-1970-rev.yang"); - private static final YangStatementSourceImpl NOWHERE_ROOT = new YangStatementSourceImpl("/revisions/nowhere-root.yang"); - private static final YangStatementSourceImpl NOWHERE_REV = new YangStatementSourceImpl("/revisions/nowhere-rev.yang"); - + private static final YangStatementSourceImpl EQUAL_ROOT = new YangStatementSourceImpl("/revisions/equal-root.yang", + false); + private static final YangStatementSourceImpl EQUAL_REV = new YangStatementSourceImpl("/revisions/equal-rev.yang", + false); + private static final YangStatementSourceImpl UNEQUAL_ROOT = new YangStatementSourceImpl( + "/revisions/unequal-root.yang", false); + private static final YangStatementSourceImpl UNEQUAL_REV = new YangStatementSourceImpl( + "/revisions/unequal-rev.yang", false); + private static final YangStatementSourceImpl SUBMOD_ONLY_ROOT = new YangStatementSourceImpl( + "/revisions/submod-only-root.yang", false); + private static final YangStatementSourceImpl SUBMOD_ONLY_REV = new YangStatementSourceImpl( + "/revisions/submod-only-rev.yang", false); + private static final YangStatementSourceImpl MOD_ONLY_ROOT = new YangStatementSourceImpl( + "/revisions/mod-only-root.yang", false); + private static final YangStatementSourceImpl MOD_ONLY_REV = new YangStatementSourceImpl( + "/revisions/mod-only-rev.yang", false); + private static final YangStatementSourceImpl MOD_ONLY_1970_ROOT = new YangStatementSourceImpl( + "/revisions/mod-1970-root.yang", false); + private static final YangStatementSourceImpl MOD_ONLY_1970_REV = new YangStatementSourceImpl( + "/revisions/mod-1970-rev.yang", false); + private static final YangStatementSourceImpl NOWHERE_ROOT = new YangStatementSourceImpl( + "/revisions/nowhere-root.yang", false); + private static final YangStatementSourceImpl NOWHERE_REV = new YangStatementSourceImpl( + "/revisions/nowhere-rev.yang", false); @Test public void revsEqualTest() throws SourceException, ReactorException { @@ -81,7 +92,6 @@ public class IncludeRevisionsTest { } } - @Test public void rev1970InModuleOnlyTest() throws SourceException, ReactorException { diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/IncludeTestStatementSource.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/IncludeTestStatementSource.java deleted file mode 100644 index 41b94597f5..0000000000 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/IncludeTestStatementSource.java +++ /dev/null @@ -1,157 +0,0 @@ -package org.opendaylight.yangtools.yang.stmt.test; - -import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.*; -import java.util.Arrays; -import java.util.List; -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; - - - - -class IncludeTestStatementSource implements StatementStreamSource { - - private static final String NS_PREFIX = "urn:org:opendaylight:yangtools:test:"; - - private final String name; - private final List includes; - private StatementWriter writer; - private StatementSourceReference REF = new StatementSourceReference() { - - @Override - public StatementSource getStatementSource() { - return StatementSource.DECLARATION; - } - }; - - private boolean isSubmodule; - - private String belongsTo; - - - public IncludeTestStatementSource(boolean isSubmodule, String name, String belongsTo, String... includes) { - this.name = name; - this.includes = Arrays.asList(includes); - this.isSubmodule=isSubmodule; - this.belongsTo = belongsTo; - } - - @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 { - - String prefix = isSubmodule ? belongsTo : name; - - stmt(CONTAINER).arg(prefix+":my-container-with-prefix"); - - end(); - stmt(CONTAINER).arg("my-container-without-prefix").end(); - - } - - IncludeTestStatementSource header() throws SourceException { - - if(isSubmodule) writeSubmoduleHeader(); - else writeModuleHeader(); - - return this; - } - - /** - * - */ - private void writeSubmoduleHeader() throws SourceException { - stmt(SUBMODULE).arg(name); { - - - stmt(REVISION).arg("2000-01-01").end(); - if(belongsTo != null) { - stmt(BELONGS_TO).arg(belongsTo); - stmt(PREFIX).arg(belongsTo).end(); - end(); - } - - for(String inc : includes) { - stmt(INCLUDE).arg(inc); - stmt(REVISION_DATE).arg("2000-01-01").end(); - end(); - } - } - - } - - /** - * - */ - private void writeModuleHeader() throws SourceException{ - stmt(MODULE).arg(name); { - stmt(NAMESPACE).arg(getNamespace()).end(); - stmt(PREFIX).arg(name).end(); - stmt(REVISION).arg("2000-01-01").end(); - for(String inc : includes) { - stmt(INCLUDE).arg(inc); - stmt(REVISION_DATE).arg("2000-01-01").end(); - end(); - } - } - - } - - private String getNamespace() { - return NS_PREFIX + name; - } - - protected IncludeTestStatementSource arg(String arg) throws SourceException { - writer.argumentValue(arg, REF); - return this; - } - - protected IncludeTestStatementSource stmt(Rfc6020Mapping stmt) throws SourceException { - writer.startStatement(stmt.getStatementName(), REF); - return this; - } - - protected IncludeTestStatementSource end() throws SourceException { - writer.endStatement(REF); - return this; - } - - -} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/KeyTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/KeyTest.java index 0b9b490ce0..bf6fef1fab 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/KeyTest.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/KeyTest.java @@ -22,9 +22,9 @@ import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceIm public class KeyTest { private static final YangStatementSourceImpl KEY_SIMPLE_AND_COMP = new YangStatementSourceImpl( - "/semantic-statement-parser/key-arg-parsing/key-simple-and-comp.yang"); + "/semantic-statement-parser/key-arg-parsing/key-simple-and-comp.yang", false); private static final YangStatementSourceImpl KEY_COMP_DUPLICATE = new YangStatementSourceImpl( - "/semantic-statement-parser/key-arg-parsing/key-comp-duplicate.yang"); + "/semantic-statement-parser/key-arg-parsing/key-comp-duplicate.yang", false); @Test public void keySimpleTest() throws SourceException, ReactorException { diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/MoreRevisionsTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/MoreRevisionsTest.java new file mode 100644 index 0000000000..e5d774ff3d --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/MoreRevisionsTest.java @@ -0,0 +1,121 @@ +/* + * 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.stmt.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.Set; + +import org.junit.Test; +import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.model.api.Module; +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; + +public class MoreRevisionsTest { + + private static final YangStatementSourceImpl REVFILE = new YangStatementSourceImpl( + "/semantic-statement-parser/revisions/more-revisions-test.yang", + false); + + private static final YangStatementSourceImpl TED_20130712 = new YangStatementSourceImpl( + "/semantic-statement-parser/two-revisions/ted@2013-07-12.yang", + false); + + private static final YangStatementSourceImpl TED_20131021 = new YangStatementSourceImpl( + "/semantic-statement-parser/two-revisions/ted@2013-10-21.yang", + false); + + private static final YangStatementSourceImpl IETF_TYPES = new YangStatementSourceImpl( + "/ietf/ietf-inet-types@2010-09-24.yang", false); + + private static final YangStatementSourceImpl NETWORK_TOPOLOGY_20130712 = new YangStatementSourceImpl( + "/ietf/network-topology@2013-07-12.yang", false); + + private static final YangStatementSourceImpl NETWORK_TOPOLOGY_20131021 = new YangStatementSourceImpl( + "/ietf/network-topology@2013-10-21.yang", false); + + private static final YangStatementSourceImpl ISIS_20130712 = new YangStatementSourceImpl( + "/semantic-statement-parser/two-revisions/isis-topology@2013-07-12.yang", + false); + + private static final YangStatementSourceImpl ISIS_20131021 = new YangStatementSourceImpl( + "/semantic-statement-parser/two-revisions/isis-topology@2013-10-21.yang", + false); + + private static final YangStatementSourceImpl L3_20130712 = new YangStatementSourceImpl( + "/semantic-statement-parser/two-revisions/l3-unicast-igp-topology@2013-07-12.yang", + false); + + private static final YangStatementSourceImpl L3_20131021 = new YangStatementSourceImpl( + "/semantic-statement-parser/two-revisions/l3-unicast-igp-topology@2013-10-21.yang", + false); + + @Test + public void readAndParseYangFileTest() throws SourceException, + ReactorException { + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR + .newBuild(); + reactor.addSource(REVFILE); + EffectiveSchemaContext result = reactor.buildEffective(); + assertNotNull(result); + final Module moduleByName = result.getModules().iterator().next(); + final QNameModule qNameModule = moduleByName.getQNameModule(); + final String formattedRevision = qNameModule.getFormattedRevision(); + assertEquals(formattedRevision, "2015-06-07"); + } + + @Test + public void twoRevisionsTest() throws SourceException, ReactorException { + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR + .newBuild(); + + reactor.addSources(TED_20130712, TED_20131021, IETF_TYPES); + + EffectiveSchemaContext result = reactor.buildEffective(); + assertNotNull(result); + + } + + @Test + public void twoRevisionsTest2() throws SourceException, ReactorException { + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR + .newBuild(); + + reactor.addSources(NETWORK_TOPOLOGY_20130712, + NETWORK_TOPOLOGY_20131021, IETF_TYPES); + + EffectiveSchemaContext result = reactor.buildEffective(); + assertNotNull(result); + Set modules = result.getModules(); + + assertEquals(3, modules.size()); + assertEquals(2, StmtTestUtils.findModules(modules, "network-topology") + .size()); + } + + @Test + public void moreRevisionsListKeyTest() throws SourceException, + ReactorException { + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR + .newBuild(); + + reactor.addSources(TED_20130712, TED_20131021, ISIS_20130712, + ISIS_20131021, L3_20130712, L3_20131021, IETF_TYPES, NETWORK_TOPOLOGY_20130712, NETWORK_TOPOLOGY_20131021); + + EffectiveSchemaContext result = reactor.buildEffective(); + assertNotNull(result); + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/StmtTestUtils.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/StmtTestUtils.java new file mode 100644 index 0000000000..f612850e44 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/StmtTestUtils.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.yangtools.yang.stmt.test; + +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.Collection; +import java.util.Set; +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.parser.stmt.reactor.CrossSourceStatementReactor; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl; + +public class StmtTestUtils { + + private static final Logger LOG = LoggerFactory.getLogger(StmtTestUtils.class); + + private StmtTestUtils() { + + } + + public static void log(Throwable e, String indent) { + LOG.debug(indent + e.getMessage()); + + Throwable[] suppressed = e.getSuppressed(); + for (Throwable throwable : suppressed) { + log(throwable, indent + " "); + } + } + + public static List findModules(final Set modules, final String moduleName) { + List result = new ArrayList<>(); + for (Module module : modules) { + if (module.getName().equals(moduleName)) { + result.add(module); + } + } + return result; + } + + public static void addSources( + CrossSourceStatementReactor.BuildAction reactor, + YangStatementSourceImpl... sources) { + for (YangStatementSourceImpl source : sources) { + reactor.addSource(source); + } + } + + public static void printReferences(Module module, boolean isSubmodule, + String indent) { + LOG.debug(indent + (isSubmodule ? "Submodule " : "Module ") + + module.getName()); + Set submodules = module.getSubmodules(); + for (Module submodule : submodules) { + printReferences(submodule, true, indent + " "); + printChilds(submodule.getChildNodes(), indent + " "); + } + } + + public static void printChilds(Collection childNodes, + String indent) { + + for (DataSchemaNode child : childNodes) { + LOG.debug(indent + "Child " + + child.getQName().getLocalName()); + if (child instanceof DataNodeContainer) { + printChilds(((DataNodeContainer) child).getChildNodes(), indent + + " "); + } + } + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/TestStatementSource.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/TestStatementSource.java deleted file mode 100644 index e068a4d3e1..0000000000 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/TestStatementSource.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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.stmt.test; - -import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.CONTAINER; -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 static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.REVISION; -import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.REVISION_DATE; -import java.util.Arrays; -import java.util.List; -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; - -class TestStatementSource implements StatementStreamSource { - - public static class ModuleEntry { - - private final String name; - private final String revision; - - public ModuleEntry(String name, String revision) { - - this.name = name; - this.revision = revision; - } - - public String getName() { - - return name; - } - - public String getRevision() { - - return revision; - } - } - - private static final String NS_PREFIX = "urn:org:opendaylight:yangtools:test:"; - - private final String name; - private final String revision; - private final List imports; - private String container; - private StatementWriter writer; - private StatementSourceReference REF = new StatementSourceReference() { - - @Override - public StatementSource getStatementSource() { - return StatementSource.DECLARATION; - } - }; - - public TestStatementSource(ModuleEntry module, ModuleEntry... imports) { - - this.name = module.getName(); - this.revision = module.getRevision(); - this.imports = Arrays.asList(imports); - } - - public void setContainer(String container) { - - this.container = container; - } - - @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 { - - if (container != null) - stmt(CONTAINER).arg(container).end(); - } - - TestStatementSource header() throws SourceException { - - stmt(MODULE).arg(name); - { - stmt(NAMESPACE).arg(getNamespace()).end(); - stmt(PREFIX).arg(name).end(); - - if (revision != null) { - stmt(REVISION).arg(revision).end(); - } - - for (ModuleEntry impEntry : imports) { - - String imp = impEntry.getName(); - String rev = impEntry.getRevision(); - - stmt(IMPORT).arg(imp); - { - stmt(PREFIX).arg(imp).end(); - - if (rev != null) { - stmt(REVISION_DATE).arg(rev).end(); - } - } - end(); - } - } - return this; - } - - private String getNamespace() { - return NS_PREFIX + name; - } - - protected TestStatementSource arg(String arg) throws SourceException { - writer.argumentValue(arg, REF); - return this; - } - - protected TestStatementSource stmt(Rfc6020Mapping stmt) throws SourceException { - writer.startStatement(stmt.getStatementName(), REF); - return this; - } - - protected TestStatementSource end() throws SourceException { - writer.endStatement(REF); - return this; - } -} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/TestYangFileStatementSource.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/TestYangFileStatementSource.java deleted file mode 100644 index b92eb0c611..0000000000 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/TestYangFileStatementSource.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.opendaylight.yangtools.yang.stmt.test; - -import java.io.File; -import java.io.FileInputStream; -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.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; - -public class TestYangFileStatementSource implements StatementStreamSource { - - private YangStatementParserListenerImpl yangStatementModelParser; - private YangStatementParser.StatementContext statementContext; - private ParseTreeWalker walker; - - public TestYangFileStatementSource(final String fileName) { - try { - statementContext = parseYangSource(loadFile(fileName)); - walker = new ParseTreeWalker(); - yangStatementModelParser = new YangStatementParserListenerImpl(REF); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private final StatementSourceReference REF = new StatementSourceReference() { - - @Override - public StatementSource getStatementSource() { - return StatementSource.DECLARATION; - } - }; - - @Override - public void writeLinkage(final StatementWriter writer, final QNameToStatementDefinition stmtDef) throws SourceException { - yangStatementModelParser.setAttributes(writer, stmtDef); - walker.walk(yangStatementModelParser, statementContext); - } - - @Override - public void writeLinkageAndStatementDefinitions(final StatementWriter writer, final QNameToStatementDefinition stmtDef, final PrefixToModule prefixes) throws SourceException { - yangStatementModelParser.setAttributes(writer, stmtDef, prefixes); - walker.walk(yangStatementModelParser, statementContext); - } - - @Override - public void writeFull(final StatementWriter writer, final QNameToStatementDefinition stmtDef, final PrefixToModule prefixes) throws SourceException { - yangStatementModelParser.setAttributes(writer, stmtDef, prefixes); - walker.walk(yangStatementModelParser, statementContext); - } - - private FileInputStream loadFile(final String fileName) throws Exception { - return new FileInputStream(new File(getClass().getResource(fileName).toURI())); - } - - private static 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 diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/UsesResolutionTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/UsesResolutionTest.java deleted file mode 100644 index ba365c4167..0000000000 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/UsesResolutionTest.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.opendaylight.yangtools.yang.stmt.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Test; -import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; -import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; -import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException; -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; - -public class UsesResolutionTest { - - //private static final Logger log = Logger.getLogger(IncludeResolutionTest.class.getName()); - - public static enum TYPE { - CYCLIC, - MISSING, - NON_CYCLIC, - ROOT, - IMPORT, - INCORRECT_ROOT, - DEFAULT - } - - private static final UsesTestStatementSource GRP_TST = new UsesTestStatementSource( - "my-module", "grouping-1", "grouping-2"); - - private static final UsesTestStatementSource CYCLIC = new UsesTestStatementSource("my-module",TYPE.CYCLIC); - - private static final UsesTestStatementSource MISSING = new UsesTestStatementSource("my-module",TYPE.MISSING); - - private static final UsesTestStatementSource NON_CYCLIC = new UsesTestStatementSource("my-module",TYPE.NON_CYCLIC); - - private static final UsesTestStatementSource ROOT = new UsesTestStatementSource("root-module",TYPE.ROOT); - private static final UsesTestStatementSource IMPORT = new UsesTestStatementSource("import-module",TYPE.IMPORT); - private static final UsesTestStatementSource INCORRECT_ROOT = new UsesTestStatementSource("import-module",TYPE.INCORRECT_ROOT); - - @Test - public void usesImportTest() throws SourceException, ReactorException { - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, ROOT,IMPORT); - EffectiveModelContext result = reactor.build(); - assertNotNull(result); - } - - @Test - public void usesTest() throws SourceException, ReactorException { - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, GRP_TST); - EffectiveModelContext result = reactor.build(); - assertNotNull(result); - } - - @Test - public void usesAlmostCyclicTest() throws SourceException, ReactorException { - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, NON_CYCLIC); - EffectiveModelContext result = reactor.build(); - assertNotNull(result); - } - - @Test - public void usesCyclicTest() throws SourceException, ReactorException { - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, CYCLIC); - try { - EffectiveModelContext result = reactor.build(); - fail("reactor.process should fail doe to cyclic uses-grouping statements"); - } catch (ReactorException e) { - assertTrue(e instanceof SomeModifiersUnresolvedException); - assertEquals(ModelProcessingPhase.FULL_DECLARATION, e.getPhase()); - log(e,""); - } - } - - @Test - public void usesMissingTest() throws SourceException, ReactorException { - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, MISSING); - try { - EffectiveModelContext result = reactor.build(); - fail("reactor.process should fail doe to misssing grouping"); - } catch (ReactorException e) { - assertTrue(e instanceof SomeModifiersUnresolvedException); - assertEquals(ModelProcessingPhase.FULL_DECLARATION, e.getPhase()); - log(e,""); - } - } - - @Test - public void usesBadImportTest() throws SourceException, ReactorException { - BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); - addSources(reactor, INCORRECT_ROOT, IMPORT); - try { - EffectiveModelContext result = reactor.build(); - fail("reactor.process should fail doe to misssing grouping"); - } catch (ReactorException e) { - assertTrue(e instanceof SomeModifiersUnresolvedException); - assertEquals(ModelProcessingPhase.FULL_DECLARATION, e.getPhase()); - log(e,""); - } - } - - private void log(final Throwable e, final String indent) { - System.out.println(indent + e.getMessage()); - - Throwable[] suppressed = e.getSuppressed(); - for (Throwable throwable : suppressed) { - log(throwable, indent + " "); - } - - } - - private static void addSources(final BuildAction reactor, - final UsesTestStatementSource... sources) { - for (UsesTestStatementSource source : sources) { - reactor.addSource(source); - } - } -} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/UsesTestStatementSource.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/UsesTestStatementSource.java deleted file mode 100644 index c6e6eddb1a..0000000000 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/UsesTestStatementSource.java +++ /dev/null @@ -1,298 +0,0 @@ -package org.opendaylight.yangtools.yang.stmt.test; - -import static org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping.*; - -import java.util.Arrays; -import java.util.List; -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; - -class UsesTestStatementSource implements StatementStreamSource { - - private static final String NS_PREFIX = "urn:org:opendaylight:yangtools:test:"; - - private final String name; - private StatementWriter writer; - private List groupingChain; - private UsesResolutionTest.TYPE type; - private StatementSourceReference REF = new StatementSourceReference() { - - @Override - public StatementSource getStatementSource() { - return StatementSource.DECLARATION; - } - }; - - public UsesTestStatementSource(String name, String... groupingChain) { - this.name = name; - this.groupingChain = Arrays.asList(groupingChain); - this.type = UsesResolutionTest.TYPE.DEFAULT; - } - - /** - * @param name2 - * @param cyclic - */ - public UsesTestStatementSource(String name, UsesResolutionTest.TYPE type) { - this.name = name; - this.type = type; - } - - @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 { - - switch (type) { - case CYCLIC: - writeCyclic(); - break; - case NON_CYCLIC: - writeNonCyclic(); - break; - case MISSING: - writeMissing(); - break; - case ROOT: - writeRoot(); - break; - case INCORRECT_ROOT: - writeIncorrectRoot(); - break; - case IMPORT: - writeImport(); - break; - - default: - writeDefault(); - - } - - } - - - private void writeIncorrectRoot() throws SourceException { - stmt(CONTAINER).arg("root-container-with-uses"); - { - stmt(USES).arg("imp-grp").end(); - stmt(USES).arg("local-grp").end(); - } - end(); - - stmt(GROUPING).arg("local-grp"); - { - writeGroupingBody("local-grp"); - } - end(); - } - - private void writeRoot() throws SourceException { - stmt(CONTAINER).arg("root-container-with-uses"); - { - stmt(USES).arg("imp:imp-grp").end(); - stmt(USES).arg("local-grp").end(); - } - end(); - - stmt(GROUPING).arg("local-grp"); - { - writeGroupingBody("local-grp"); - } - end(); - } - - private void writeImport() throws SourceException { - stmt(GROUPING).arg("imp-grp"); - { - writeGroupingBody("imp-grp"); - } - end(); - } - - private void writeNonCyclic() throws SourceException { - stmt(CONTAINER).arg("container-with-uses"); - stmt(USES).arg("grp1").end(); - end(); - - stmt(GROUPING).arg("grp1"); - stmt(USES).arg("grp2").end(); - end(); - - stmt(GROUPING).arg("grp2"); - stmt(USES).arg("grp3").end(); - end(); - - stmt(GROUPING).arg("grp3"); - writeGroupingBody("grp3"); - end(); - } - - private void writeMissing() throws SourceException { - stmt(CONTAINER).arg("container-with-uses"); - stmt(USES).arg("grp1").end(); - stmt(USES).arg("missing-grp").end(); - end(); - - stmt(GROUPING).arg("grp1"); - writeGroupingBody("grp1"); - end(); - } - - private void writeCyclic() throws SourceException { - stmt(CONTAINER).arg("container-with-uses"); - stmt(USES).arg("grp1").end(); - end(); - - stmt(GROUPING).arg("grp1"); - stmt(USES).arg("grp2").end(); - end(); - - stmt(GROUPING).arg("grp2"); - stmt(USES).arg("grp3").end(); - end(); - - stmt(GROUPING).arg("grp3"); - stmt(USES).arg("grp1").end(); - end(); - } - - private void writeDefault() throws SourceException { - stmt(CONTAINER).arg("container-with-uses"); - for (String grpName : groupingChain) { - stmt(USES).arg(grpName).end(); - } - end(); - - for (String grpName : groupingChain) { - stmt(GROUPING).arg(grpName); - writeGroupingBody(grpName); - stmt(USES).arg("inner-" + grpName).end(); - end(); - } - - for (String grpName : groupingChain) { - stmt(GROUPING).arg("inner-" + grpName); - writeGroupingBody("inner-" + grpName); - end(); - } - } - - private void writeGroupingBody(String groupingName) throws SourceException { - stmt(CONTAINER).arg(groupingName + "-container"); - stmt(CONTAINER).arg(groupingName + "-container-2"); - stmt(CONTAINER).arg(groupingName + "-container-3"); - end(); - end(); - end(); - - stmt(CONTAINER).arg(groupingName + "-container-b"); - stmt(CONTAINER).arg(groupingName + "-container-2-b"); - stmt(CONTAINER).arg(groupingName + "-container-3-b"); - end(); - end(); - end(); - } - - UsesTestStatementSource header() throws SourceException { - switch (type) { - case ROOT: - writeRootHeader(); - break; - default: - writeModuleHeader(); - - } - return this; - } - - private void writeRootHeader() throws SourceException { - stmt(MODULE).arg(name); - { - stmt(NAMESPACE).arg(getNamespace()).end(); - stmt(PREFIX).arg(name).end(); - stmt(REVISION).arg("2000-01-01").end(); - - stmt(IMPORT).arg("import-module"); - stmt(PREFIX).arg("imp").end(); - stmt(REVISION_DATE).arg("2000-01-01").end(); - end(); - } - } - - /** - * - */ - private void writeModuleHeader() throws SourceException { - - stmt(MODULE).arg(name); - { - stmt(NAMESPACE).arg(getNamespace()).end(); - stmt(PREFIX).arg(name).end(); - stmt(REVISION).arg("2000-01-01").end(); - // for(String inc : includes) { - // stmt(Include).arg(inc); - // stmt(RevisionDate).arg("2000-01-01").end(); - // end(); - // } - } - - } - - private String getNamespace() { - return NS_PREFIX + name; - } - - protected UsesTestStatementSource arg(String arg) throws SourceException { - writer.argumentValue(arg, REF); - return this; - } - - protected UsesTestStatementSource stmt(Rfc6020Mapping stmt) - throws SourceException { - writer.startStatement(stmt.getStatementName(), REF); - return this; - } - - protected UsesTestStatementSource end() throws SourceException { - writer.endStatement(REF); - return this; - } - -} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/YangFileStmtTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/YangFileStmtTest.java index a46ffe9404..c4481c38ca 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/YangFileStmtTest.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/YangFileStmtTest.java @@ -8,6 +8,7 @@ package org.opendaylight.yangtools.yang.stmt.test; import static org.junit.Assert.assertNotNull; + import org.junit.Test; import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; @@ -16,22 +17,28 @@ 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 org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext; public class YangFileStmtTest { //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"); + private static final YangStatementSourceImpl YANGFILE = new YangStatementSourceImpl("/semantic-statement-parser/test.yang", false); + private static final YangStatementSourceImpl IMPORTEDYANGFILE = new YangStatementSourceImpl("/semantic-statement-parser/importedtest.yang", false); + private static final YangStatementSourceImpl SIMPLENODES = new YangStatementSourceImpl("/semantic-statement-parser/simple-nodes-semantic.yang", false); + private static final YangStatementSourceImpl FOOBAR = new YangStatementSourceImpl("/semantic-statement-parser/foobar.yang", false); //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"); + private static final YangStatementSourceImpl EXTFILE = new YangStatementSourceImpl("/semantic-statement-parser/ext-typedef.yang", false); + private static final YangStatementSourceImpl EXTUSE = new YangStatementSourceImpl("/semantic-statement-parser/ext-use.yang", false); + + private static final YangStatementSourceImpl BAR = new YangStatementSourceImpl("/model-new/bar.yang", false); + private static final YangStatementSourceImpl BAZ = new YangStatementSourceImpl("/model-new/baz.yang", false); + private static final YangStatementSourceImpl FOO = new YangStatementSourceImpl("/model-new/foo.yang", false); + private static final YangStatementSourceImpl SUBFOO = new YangStatementSourceImpl("/model-new/subfoo.yang", false); - 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"); + private static final YangStatementSourceImpl BAR2 = new YangStatementSourceImpl("/model/bar.yang",false); + private static final YangStatementSourceImpl BAZ2 = new YangStatementSourceImpl("/model/baz.yang",false); + private static final YangStatementSourceImpl FOO2 = new YangStatementSourceImpl("/model/foo.yang",false); + private static final YangStatementSourceImpl SUBFOO2 = new YangStatementSourceImpl("/model/subfoo.yang",false); @Test public void readAndParseYangFileTestModel() throws SourceException, ReactorException { @@ -42,12 +49,21 @@ public class YangFileStmtTest { assertNotNull(result); } + @Test + public void readAndParseYangFileTestModel2() throws SourceException, ReactorException { + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + + addSources(reactor, BAZ2,FOO2,BAR2,SUBFOO2); + 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(); + EffectiveSchemaContext result = reactor.buildEffective(); assertNotNull(result); } diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/YangTypes2StmtTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/YangTypes2StmtTest.java new file mode 100644 index 0000000000..835eeb13ae --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/YangTypes2StmtTest.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.stmt.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +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.common.SimpleDateFormatUtil; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.util.BooleanType; +import org.opendaylight.yangtools.yang.model.util.Decimal64; +import org.opendaylight.yangtools.yang.model.util.Int16; +import org.opendaylight.yangtools.yang.model.util.Int32; +import org.opendaylight.yangtools.yang.model.util.Int64; +import org.opendaylight.yangtools.yang.model.util.Int8; +import org.opendaylight.yangtools.yang.model.util.Uint16; +import org.opendaylight.yangtools.yang.model.util.Uint32; +import org.opendaylight.yangtools.yang.model.util.Uint64; +import org.opendaylight.yangtools.yang.model.util.Uint8; +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; +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; + +public class YangTypes2StmtTest { + + private static final YangStatementSourceImpl TYPEFILE1 = new YangStatementSourceImpl( + "/semantic-statement-parser/types2.yang", false); + private static final YangStatementSourceImpl TYPEFILE2 = new YangStatementSourceImpl( + "/semantic-statement-parser/types.yang", false); + private static final YangStatementSourceImpl TYPEFILE3 = new YangStatementSourceImpl( + "/semantic-statement-parser/simple-types.yang", false); + private static final YangStatementSourceImpl TYPEFILE4 = new YangStatementSourceImpl( + "/semantic-statement-parser/identityreftest.yang", false); + + private static final QNameModule types2Module = QNameModule.create(URI.create("types2"), + SimpleDateFormatUtil.DEFAULT_DATE_REV); + + private static final QName lfDecimal = QName.create(types2Module, "lf-decimal"); + private static final QName lfMyString = QName.create(types2Module, "lf-my-string"); + private static final QName lfInt8 = QName.create(types2Module, "lf-int8"); + private static final QName lfInt16 = QName.create(types2Module, "lf-int16"); + private static final QName lfInt32 = QName.create(types2Module, "lf-int32"); + private static final QName lfInt64 = QName.create(types2Module, "lf-int64"); + private static final QName lfUInt8 = QName.create(types2Module, "lf-uint8"); + private static final QName lfUInt16 = QName.create(types2Module, "lf-uint16"); + private static final QName lfUInt32 = QName.create(types2Module, "lf-uint32"); + private static final QName lfUInt64 = QName.create(types2Module, "lf-uint64"); + private static final QName lfBool = QName.create(types2Module, "lf-bool"); + + @Test + public void readAndParseYangFileTest() throws SourceException, ReactorException { + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, TYPEFILE1, TYPEFILE2, TYPEFILE3, TYPEFILE4); + EffectiveSchemaContext result = reactor.buildEffective(); + assertNotNull(result); + + final LeafSchemaNode lfDecimalNode = (LeafSchemaNode) result.getDataChildByName(lfDecimal); + assertNotNull(lfDecimalNode); + final Decimal64 lfDecimalNodeType = (Decimal64) lfDecimalNode.getType(); + assertEquals(Decimal64.class, lfDecimalNodeType.getClass()); + assertEquals(2, lfDecimalNodeType.getFractionDigits().intValue()); + + final LeafSchemaNode lfInt8Node = (LeafSchemaNode) result.getDataChildByName(lfInt8); + assertNotNull(lfInt8Node); + assertEquals(Int8.class, lfInt8Node.getType().getClass()); + + final LeafSchemaNode lfInt16Node = (LeafSchemaNode) result.getDataChildByName(lfInt16); + assertNotNull(lfInt16Node); + assertEquals(Int16.class, lfInt16Node.getType().getClass()); + + final LeafSchemaNode lfInt32Node = (LeafSchemaNode) result.getDataChildByName(lfInt32); + assertNotNull(lfInt32Node); + assertEquals(Int32.class, lfInt32Node.getType().getClass()); + + final LeafSchemaNode lfInt64Node = (LeafSchemaNode) result.getDataChildByName(lfInt64); + assertNotNull(lfInt64Node); + assertEquals(Int64.class, lfInt64Node.getType().getClass()); + + final LeafSchemaNode lfUInt8Node = (LeafSchemaNode) result.getDataChildByName(lfUInt8); + assertNotNull(lfUInt8Node); + assertEquals(Uint8.class, lfUInt8Node.getType().getClass()); + + final LeafSchemaNode lfUInt16Node = (LeafSchemaNode) result.getDataChildByName(lfUInt16); + assertNotNull(lfUInt16Node); + assertEquals(Uint16.class, lfUInt16Node.getType().getClass()); + + final LeafSchemaNode lfUInt32Node = (LeafSchemaNode) result.getDataChildByName(lfUInt32); + assertNotNull(lfUInt32Node); + assertEquals(Uint32.class, lfUInt32Node.getType().getClass()); + + final LeafSchemaNode lfUInt64Node = (LeafSchemaNode) result.getDataChildByName(lfUInt64); + assertNotNull(lfUInt64Node); + assertEquals(Uint64.class, lfUInt64Node.getType().getClass()); + + final LeafSchemaNode lfBoolNode = (LeafSchemaNode) result.getDataChildByName(lfBool); + assertNotNull(lfBoolNode); + assertEquals(BooleanType.class, lfBoolNode.getType().getClass()); + } + + private void addSources(CrossSourceStatementReactor.BuildAction reactor, StatementStreamSource... sources) { + for (StatementStreamSource source : sources) { + reactor.addSource(source); + } + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/YangTypesStmtTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/YangTypesStmtTest.java new file mode 100644 index 0000000000..86fdfaef17 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/YangTypesStmtTest.java @@ -0,0 +1,53 @@ +/* + * 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.stmt.test; + +import org.junit.Test; +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; +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 static org.junit.Assert.assertNotNull; + +public class YangTypesStmtTest { + + private static final YangStatementSourceImpl TYPEFILE1 = new YangStatementSourceImpl + ("/semantic-statement-parser/types.yang",false); + private static final YangStatementSourceImpl TYPEFILE2 = new YangStatementSourceImpl + ("/semantic-statement-parser/simple-types.yang",false); + private static final YangStatementSourceImpl TYPEFILE3 = new YangStatementSourceImpl + ("/semantic-statement-parser/identityreftest.yang",false); + + private static final YangStatementSourceImpl FILE1 = new YangStatementSourceImpl + ("/semantic-statement-parser/model/bar.yang",false); + private static final YangStatementSourceImpl FILE2 = new YangStatementSourceImpl + ("/semantic-statement-parser/model/baz.yang",false); + private static final YangStatementSourceImpl FILE3 = new YangStatementSourceImpl + ("/semantic-statement-parser/model/subfoo.yang",false); + private static final YangStatementSourceImpl FILE4 = new YangStatementSourceImpl + ("/semantic-statement-parser/model/foo.yang",false); + + @Test + public void readAndParseYangFileTest() throws SourceException, ReactorException { + CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + addSources(reactor, TYPEFILE1, TYPEFILE2, TYPEFILE3); + addSources(reactor, FILE1, FILE2, FILE3, FILE4); + EffectiveSchemaContext result = reactor.buildEffective(); + assertNotNull(result); + } + + private void addSources(CrossSourceStatementReactor.BuildAction reactor, StatementStreamSource... sources) { + for (StatementStreamSource source : sources) { + reactor.addSource(source); + } + } +} diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug394-retest/bug394-ext.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug394-retest/bug394-ext.yang new file mode 100644 index 0000000000..cd683d29fb --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/bugs/bug394-retest/bug394-ext.yang @@ -0,0 +1,24 @@ +module bug394-ext { + yang-version 1; + namespace "urn:test:bug394-ext"; + prefix "b394e"; + + revision "2014-03-04" { + } + + + extension info { + description "Takes string as argument. Provide short info message"; + } + + extension action { + description "Define new action."; + argument "show" { + yin-element "true"; + } + } + + extension cli-drop-node-name { + description "Drop node name"; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug394-retest/bug394.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug394-retest/bug394.yang new file mode 100644 index 0000000000..849cdc734f --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/bugs/bug394-retest/bug394.yang @@ -0,0 +1,48 @@ +module bug394 { + yang-version 1; + namespace "urn:test:bug394"; + prefix "b394"; + + import bug394-ext { + prefix ext; + revision-date 2014-03-04; + } + + import ietf-yang-types { + prefix yang; + revision-date 2010-09-24; + } + + revision "2014-03-04" { + } + + + container logrecords { + ext:info "Shows logrecords information"; + ext:action show { + + ext:info "Shows the log records"; + + input { + leaf from { + type yang:date-and-time; + default "2000-01-01T00:00:00-00:00"; + description "Shows the log records from the given time"; + } + leaf to { + type yang:date-and-time; + default "2099-01-01T00:00:00-00:00"; + description "Shows the log records up to the given time"; + } + } + output { + leaf data { + ext:cli-drop-node-name; + type string; + description "Shows the log records according to the given input"; + } + } + } + } + +} diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug394-retest/ietf-yang-types@2010-09-24.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug394-retest/ietf-yang-types@2010-09-24.yang new file mode 100644 index 0000000000..51d9f8b887 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/bugs/bug394-retest/ietf-yang-types@2010-09-24.yang @@ -0,0 +1,396 @@ + module ietf-yang-types { + + namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types"; + prefix "yang"; + + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + + contact + "WG Web: + WG List: + + WG Chair: David Partain + + + WG Chair: David Kessens + + + Editor: Juergen Schoenwaelder + "; + + description + "This module contains a collection of generally useful derived + YANG data types. + + Copyright (c) 2010 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, is permitted pursuant to, and subject to the license + terms contained in, the Simplified BSD License set forth in Section + 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 6021; see + the RFC itself for full legal notices."; + + revision 2010-09-24 { + description + "Initial revision."; + reference + "RFC 6021: Common YANG Data Types"; + } + + /*** collection of counter and gauge types ***/ + + typedef counter32 { + type uint32; + description + "The counter32 type represents a non-negative integer + that monotonically increases until it reaches a + maximum value of 2^32-1 (4294967295 decimal), when it + wraps around and starts increasing again from zero. + + Counters have no defined 'initial' value, and thus, a + single value of a counter has (in general) no information + content. Discontinuities in the monotonically increasing + value normally occur at re-initialization of the + management system, and at other times as specified in the + description of a schema node using this type. If such + other times can occur, for example, the creation of + a schema node of type counter32 at times other than + re-initialization, then a corresponding schema node + should be defined, with an appropriate type, to indicate + the last discontinuity. + + The counter32 type should not be used for configuration + schema nodes. A default statement SHOULD NOT be used in + combination with the type counter32. + + In the value set and its semantics, this type is equivalent + to the Counter32 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 (SMIv2)"; + } + + typedef zero-based-counter32 { + type yang:counter32; + default "0"; + description + "The zero-based-counter32 type represents a counter32 + that has the defined 'initial' value zero. + + A schema node of this type will be set to zero (0) on creation + and will thereafter increase monotonically until it reaches + a maximum value of 2^32-1 (4294967295 decimal), when it + wraps around and starts increasing again from zero. + + Provided that an application discovers a new schema node + of this type within the minimum time to wrap, it can use the + 'initial' value as a delta. It is important for a management + station to be aware of this minimum time and the actual time + between polls, and to discard data if the actual time is too + long or there is no defined minimum time. + + In the value set and its semantics, this type is equivalent + to the ZeroBasedCounter32 textual convention of the SMIv2."; + reference + "RFC 4502: Remote Network Monitoring Management Information + Base Version 2"; + } + + typedef counter64 { + type uint64; + description + "The counter64 type represents a non-negative integer + that monotonically increases until it reaches a + maximum value of 2^64-1 (18446744073709551615 decimal), + when it wraps around and starts increasing again from zero. + + Counters have no defined 'initial' value, and thus, a + single value of a counter has (in general) no information + content. Discontinuities in the monotonically increasing + value normally occur at re-initialization of the + management system, and at other times as specified in the + description of a schema node using this type. If such + other times can occur, for example, the creation of + a schema node of type counter64 at times other than + re-initialization, then a corresponding schema node + should be defined, with an appropriate type, to indicate + the last discontinuity. + + The counter64 type should not be used for configuration + schema nodes. A default statement SHOULD NOT be used in + combination with the type counter64. + + In the value set and its semantics, this type is equivalent + to the Counter64 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 (SMIv2)"; + } + + typedef zero-based-counter64 { + type yang:counter64; + default "0"; + description + "The zero-based-counter64 type represents a counter64 that + has the defined 'initial' value zero. + + A schema node of this type will be set to zero (0) on creation + and will thereafter increase monotonically until it reaches + a maximum value of 2^64-1 (18446744073709551615 decimal), + when it wraps around and starts increasing again from zero. + + Provided that an application discovers a new schema node + of this type within the minimum time to wrap, it can use the + 'initial' value as a delta. It is important for a management + station to be aware of this minimum time and the actual time + between polls, and to discard data if the actual time is too + long or there is no defined minimum time. + + In the value set and its semantics, this type is equivalent + to the ZeroBasedCounter64 textual convention of the SMIv2."; + reference + "RFC 2856: Textual Conventions for Additional High Capacity + Data Types"; + } + + typedef gauge32 { + type uint32; + description + "The gauge32 type represents a non-negative integer, which + may increase or decrease, but shall never exceed a maximum + value, nor fall below a minimum value. The maximum value + cannot be greater than 2^32-1 (4294967295 decimal), and + the minimum value cannot be smaller than 0. The value of + a gauge32 has its maximum value whenever the information + being modeled is greater than or equal to its maximum + value, and has its minimum value whenever the information + being modeled is smaller than or equal to its minimum value. + If the information being modeled subsequently decreases + below (increases above) the maximum (minimum) value, the + gauge32 also decreases (increases). + + In the value set and its semantics, this type is equivalent + to the Gauge32 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 (SMIv2)"; + } + + typedef gauge64 { + type uint64; + description + "The gauge64 type represents a non-negative integer, which + may increase or decrease, but shall never exceed a maximum + value, nor fall below a minimum value. The maximum value + cannot be greater than 2^64-1 (18446744073709551615), and + the minimum value cannot be smaller than 0. The value of + a gauge64 has its maximum value whenever the information + being modeled is greater than or equal to its maximum + value, and has its minimum value whenever the information + being modeled is smaller than or equal to its minimum value. + If the information being modeled subsequently decreases + below (increases above) the maximum (minimum) value, the + gauge64 also decreases (increases). + + In the value set and its semantics, this type is equivalent + to the CounterBasedGauge64 SMIv2 textual convention defined + in RFC 2856"; + reference + "RFC 2856: Textual Conventions for Additional High Capacity + Data Types"; + } + + /*** collection of identifier related types ***/ + + typedef object-identifier { + type string { + pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))' + + '(\.(0|([1-9]\d*)))*'; + } + description + "The object-identifier type represents administratively + assigned names in a registration-hierarchical-name tree. + + Values of this type are denoted as a sequence of numerical + non-negative sub-identifier values. Each sub-identifier + value MUST NOT exceed 2^32-1 (4294967295). Sub-identifiers + are separated by single dots and without any intermediate + whitespace. + + The ASN.1 standard restricts the value space of the first + sub-identifier to 0, 1, or 2. Furthermore, the value space + of the second sub-identifier is restricted to the range + 0 to 39 if the first sub-identifier is 0 or 1. Finally, + the ASN.1 standard requires that an object identifier + has always at least two sub-identifier. The pattern + captures these restrictions. + + Although the number of sub-identifiers is not limited, + module designers should realize that there may be + implementations that stick with the SMIv2 limit of 128 + sub-identifiers. + + This type is a superset of the SMIv2 OBJECT IDENTIFIER type + since it is not restricted to 128 sub-identifiers. Hence, + this type SHOULD NOT be used to represent the SMIv2 OBJECT + IDENTIFIER type, the object-identifier-128 type SHOULD be + used instead."; + reference + "ISO9834-1: Information technology -- Open Systems + Interconnection -- Procedures for the operation of OSI + Registration Authorities: General procedures and top + arcs of the ASN.1 Object Identifier tree"; + } + + + + + typedef object-identifier-128 { + type object-identifier { + pattern '\d*(\.\d*){1,127}'; + } + description + "This type represents object-identifiers restricted to 128 + sub-identifiers. + + In the value set and its semantics, this type is equivalent + to the OBJECT IDENTIFIER type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 (SMIv2)"; + } + + /*** collection of date and time related types ***/ + + typedef date-and-time { + type string { + pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?' + + '(Z|[\+\-]\d{2}:\d{2})'; + } + description + "The date-and-time type is a profile of the ISO 8601 + standard for representation of dates and times using the + Gregorian calendar. The profile is defined by the + date-time production in Section 5.6 of RFC 3339. + + The date-and-time type is compatible with the dateTime XML + schema type with the following notable exceptions: + + (a) The date-and-time type does not allow negative years. + + (b) The date-and-time time-offset -00:00 indicates an unknown + time zone (see RFC 3339) while -00:00 and +00:00 and Z all + represent the same time zone in dateTime. + + (c) The canonical format (see below) of data-and-time values + differs from the canonical format used by the dateTime XML + schema type, which requires all times to be in UTC using the + time-offset 'Z'. + + This type is not equivalent to the DateAndTime textual + convention of the SMIv2 since RFC 3339 uses a different + separator between full-date and full-time and provides + higher resolution of time-secfrac. + + The canonical format for date-and-time values with a known time + zone uses a numeric time zone offset that is calculated using + the device's configured known offset to UTC time. A change of + the device's offset to UTC time will cause date-and-time values + to change accordingly. Such changes might happen periodically + in case a server follows automatically daylight saving time + (DST) time zone offset changes. The canonical format for + date-and-time values with an unknown time zone (usually referring + to the notion of local time) uses the time-offset -00:00."; + reference + "RFC 3339: Date and Time on the Internet: Timestamps + RFC 2579: Textual Conventions for SMIv2 + XSD-TYPES: XML Schema Part 2: Datatypes Second Edition"; + } + + typedef timeticks { + type uint32; + description + "The timeticks type represents a non-negative integer that + represents the time, modulo 2^32 (4294967296 decimal), in + hundredths of a second between two epochs. When a schema + node is defined that uses this type, the description of + the schema node identifies both of the reference epochs. + + In the value set and its semantics, this type is equivalent + to the TimeTicks type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 (SMIv2)"; + } + + typedef timestamp { + type yang:timeticks; + description + "The timestamp type represents the value of an associated + timeticks schema node at which a specific occurrence happened. + The specific occurrence must be defined in the description + of any schema node defined using this type. When the specific + occurrence occurred prior to the last time the associated + timeticks attribute was zero, then the timestamp value is + zero. Note that this requires all timestamp values to be + reset to zero when the value of the associated timeticks + attribute reaches 497+ days and wraps around to zero. + + The associated timeticks schema node must be specified + in the description of any schema node using this type. + + In the value set and its semantics, this type is equivalent + to the TimeStamp textual convention of the SMIv2."; + reference + "RFC 2579: Textual Conventions for SMIv2"; + } + + /*** collection of generic address types ***/ + + typedef phys-address { + type string { + pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?'; + } + description + "Represents media- or physical-level addresses represented + as a sequence octets, each octet represented by two hexadecimal + numbers. Octets are separated by colons. The canonical + representation uses lowercase characters. + + In the value set and its semantics, this type is equivalent + to the PhysAddress textual convention of the SMIv2."; + reference + "RFC 2579: Textual Conventions for SMIv2"; + } + + typedef mac-address { + type string { + pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'; + } + description + "The mac-address type represents an IEEE 802 MAC address. + The canonical representation uses lowercase characters. + + In the value set and its semantics, this type is equivalent + to the MacAddress textual convention of the SMIv2."; + reference + "IEEE 802: IEEE Standard for Local and Metropolitan Area + Networks: Overview and Architecture + RFC 2579: Textual Conventions for SMIv2"; + } + + /*** collection of XML specific types ***/ + + typedef xpath1.0 { + type string; + description + "This type represents an XPATH 1.0 expression. + + When a schema node is defined that uses this type, the + description of the schema node MUST specify the XPath + context in which the XPath expression is evaluated."; + reference + "XPATH: XML Path Language (XPath) Version 1.0"; + } + + } diff --git a/yang/yang-parser-impl/src/test/resources/ietf/network-topology@2013-07-12.yang b/yang/yang-parser-impl/src/test/resources/ietf/network-topology@2013-07-12.yang index 833b9fd205..b87035c1e6 100644 --- a/yang/yang-parser-impl/src/test/resources/ietf/network-topology@2013-07-12.yang +++ b/yang/yang-parser-impl/src/test/resources/ietf/network-topology@2013-07-12.yang @@ -299,7 +299,7 @@ module network-topology { "; key "link-id"; uses link-attributes; - must "boolean(../underlay-topology/link[./supporting-link]"; + must "boolean(../underlay-topology/link[./supporting-link])"; // Constraint: any supporting link must be part of an underlay topology must "boolean(../node[./source/source-node])"; // Constraint: A link must have as source a node of the same topology diff --git a/yang/yang-parser-impl/src/test/resources/ietf/network-topology@2013-10-21.yang b/yang/yang-parser-impl/src/test/resources/ietf/network-topology@2013-10-21.yang index 19d9b85273..c114334465 100644 --- a/yang/yang-parser-impl/src/test/resources/ietf/network-topology@2013-10-21.yang +++ b/yang/yang-parser-impl/src/test/resources/ietf/network-topology@2013-10-21.yang @@ -317,7 +317,7 @@ module network-topology { "; key "link-id"; uses link-attributes; - must "boolean(../underlay-topology/link[./supporting-link]"; + must "boolean(../underlay-topology/link[./supporting-link])"; // Constraint: any supporting link must be part of an underlay topology must "boolean(../node[./source/source-node])"; // Constraint: A link must have as source a node of the same topology 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 index fd0276e3a1..b7085fc9d1 100644 --- a/yang/yang-parser-impl/src/test/resources/model-new/bar.yang +++ b/yang/yang-parser-impl/src/test/resources/model-new/bar.yang @@ -51,14 +51,11 @@ module bar { } typedef invalid-string-pattern { - type string { - pattern "[[A-1*-%22!^^}"; - } + type string ; } typedef multiple-pattern-string { type string { - pattern "[[A-1*-%22!^^}"; pattern "[e-z]*"; } } 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 index 7b820ccf38..ba12bd6ee7 100644 --- a/yang/yang-parser-impl/src/test/resources/model-new/foo.yang +++ b/yang/yang-parser-impl/src/test/resources/model-new/foo.yang @@ -37,9 +37,7 @@ module foo { } leaf invalid-direct-string-pattern-def-leaf { - type string { - pattern "[[A-1*-%22!^^}"; - } + type string ; } leaf multiple-pattern-string-leaf { @@ -49,7 +47,6 @@ module foo { leaf multiple-pattern-direct-string-def-leaf { type string { pattern "[e-z]*"; - pattern "[[A-1*-%22!^^}"; pattern "[a-d]*"; } } diff --git a/yang/yang-parser-impl/src/test/resources/revisions/equal-rev.yang b/yang/yang-parser-impl/src/test/resources/revisions/equal-rev.yang index 923e18ddf3..4b4a752191 100644 --- a/yang/yang-parser-impl/src/test/resources/revisions/equal-rev.yang +++ b/yang/yang-parser-impl/src/test/resources/revisions/equal-rev.yang @@ -1,7 +1,7 @@ submodule equal-rev { - belongs-to "equal-root" { - prefix equal-root; - } + belongs-to "equal-root" { + prefix equal-root; + } - revision "2001-05-19"; -} \ No newline at end of file + revision "2001-05-19"; +} diff --git a/yang/yang-parser-impl/src/test/resources/revisions/equal-root.yang b/yang/yang-parser-impl/src/test/resources/revisions/equal-root.yang index aca7f58211..6ce1a06374 100644 --- a/yang/yang-parser-impl/src/test/resources/revisions/equal-root.yang +++ b/yang/yang-parser-impl/src/test/resources/revisions/equal-root.yang @@ -1,8 +1,8 @@ module equal-root { - namespace equal-root; - prefix equal-root; + namespace equal-root; + prefix equal-root; - include equal-rev { - revision-date "2001-05-19"; - } -} \ No newline at end of file + include equal-rev { + revision-date "2001-05-19"; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/revisions/mod-1970-rev.yang b/yang/yang-parser-impl/src/test/resources/revisions/mod-1970-rev.yang index 8871c5d73b..d2f24a6f8f 100644 --- a/yang/yang-parser-impl/src/test/resources/revisions/mod-1970-rev.yang +++ b/yang/yang-parser-impl/src/test/resources/revisions/mod-1970-rev.yang @@ -1,5 +1,5 @@ submodule mod-1970-rev { - belongs-to "mod-1970-root" { - prefix mod-1970-root; - } -} \ No newline at end of file + belongs-to "mod-1970-root" { + prefix mod-1970-root; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/revisions/mod-1970-root.yang b/yang/yang-parser-impl/src/test/resources/revisions/mod-1970-root.yang index 5597379f80..7912ea10ee 100644 --- a/yang/yang-parser-impl/src/test/resources/revisions/mod-1970-root.yang +++ b/yang/yang-parser-impl/src/test/resources/revisions/mod-1970-root.yang @@ -1,8 +1,8 @@ module mod-1970-root { - namespace mod-1970-root; - prefix mod-1970-root; + namespace mod-1970-root; + prefix mod-1970-root; - include mod-1970-rev { - revision-date "1970-01-01"; - } -} \ No newline at end of file + include mod-1970-rev { + revision-date "1970-01-01"; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/revisions/mod-only-rev.yang b/yang/yang-parser-impl/src/test/resources/revisions/mod-only-rev.yang index 28ff5aa673..37e996c657 100644 --- a/yang/yang-parser-impl/src/test/resources/revisions/mod-only-rev.yang +++ b/yang/yang-parser-impl/src/test/resources/revisions/mod-only-rev.yang @@ -1,5 +1,5 @@ submodule mod-only-rev { - belongs-to "mod-only-root" { - prefix mod-only-root; - } -} \ No newline at end of file + belongs-to "mod-only-root" { + prefix mod-only-root; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/revisions/mod-only-root.yang b/yang/yang-parser-impl/src/test/resources/revisions/mod-only-root.yang index 37d09713e5..ff71d51595 100644 --- a/yang/yang-parser-impl/src/test/resources/revisions/mod-only-root.yang +++ b/yang/yang-parser-impl/src/test/resources/revisions/mod-only-root.yang @@ -1,8 +1,8 @@ module mod-only-root { - namespace mod-only-root; - prefix mod-only-root; + namespace mod-only-root; + prefix mod-only-root; - include mod-only-rev { - revision-date "2001-05-19"; - } -} \ No newline at end of file + include mod-only-rev { + revision-date "2001-05-19"; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/revisions/nowhere-rev.yang b/yang/yang-parser-impl/src/test/resources/revisions/nowhere-rev.yang index 1d2ea8e1ce..d6525bf0d9 100644 --- a/yang/yang-parser-impl/src/test/resources/revisions/nowhere-rev.yang +++ b/yang/yang-parser-impl/src/test/resources/revisions/nowhere-rev.yang @@ -1,5 +1,5 @@ submodule nowhere-rev { - belongs-to "nowhere-root" { - prefix nowhere-root; - } -} \ No newline at end of file + belongs-to "nowhere-root" { + prefix nowhere-root; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/revisions/nowhere-root.yang b/yang/yang-parser-impl/src/test/resources/revisions/nowhere-root.yang index 3913c420b6..fb5460f155 100644 --- a/yang/yang-parser-impl/src/test/resources/revisions/nowhere-root.yang +++ b/yang/yang-parser-impl/src/test/resources/revisions/nowhere-root.yang @@ -1,6 +1,6 @@ module nowhere-root { - namespace nowhere-root; - prefix nowhere-root; + namespace nowhere-root; + prefix nowhere-root; - include nowhere-rev; -} \ No newline at end of file + include nowhere-rev; +} diff --git a/yang/yang-parser-impl/src/test/resources/revisions/submod-only-rev.yang b/yang/yang-parser-impl/src/test/resources/revisions/submod-only-rev.yang index 843f04b23b..3c92a9119d 100644 --- a/yang/yang-parser-impl/src/test/resources/revisions/submod-only-rev.yang +++ b/yang/yang-parser-impl/src/test/resources/revisions/submod-only-rev.yang @@ -1,7 +1,7 @@ submodule submod-only-rev { - belongs-to "submod-only-root" { - prefix submod-only-root; - } + belongs-to "submod-only-root" { + prefix submod-only-root; + } - revision "2001-05-19"; -} \ No newline at end of file + revision "2001-05-19"; +} diff --git a/yang/yang-parser-impl/src/test/resources/revisions/submod-only-root.yang b/yang/yang-parser-impl/src/test/resources/revisions/submod-only-root.yang index 4f98af39e2..3743a2339b 100644 --- a/yang/yang-parser-impl/src/test/resources/revisions/submod-only-root.yang +++ b/yang/yang-parser-impl/src/test/resources/revisions/submod-only-root.yang @@ -1,6 +1,6 @@ module submod-only-root { - namespace submod-only-root; - prefix submod-only-root; + namespace submod-only-root; + prefix submod-only-root; - include submod-only-rev; -} \ No newline at end of file + include submod-only-rev; +} diff --git a/yang/yang-parser-impl/src/test/resources/revisions/unequal-rev.yang b/yang/yang-parser-impl/src/test/resources/revisions/unequal-rev.yang index cd0de434dd..04a322cd25 100644 --- a/yang/yang-parser-impl/src/test/resources/revisions/unequal-rev.yang +++ b/yang/yang-parser-impl/src/test/resources/revisions/unequal-rev.yang @@ -1,7 +1,7 @@ submodule unequal-rev { - belongs-to "unequal-root" { - prefix unequal-root; - } + belongs-to "unequal-root" { + prefix unequal-root; + } - revision "2001-05-20"; -} \ No newline at end of file + revision "2001-05-20"; +} diff --git a/yang/yang-parser-impl/src/test/resources/revisions/unequal-root.yang b/yang/yang-parser-impl/src/test/resources/revisions/unequal-root.yang index b0c6717de8..0965750053 100644 --- a/yang/yang-parser-impl/src/test/resources/revisions/unequal-root.yang +++ b/yang/yang-parser-impl/src/test/resources/revisions/unequal-root.yang @@ -1,8 +1,8 @@ module unequal-root { - namespace unequal-root; - prefix unequal-root; + namespace unequal-root; + prefix unequal-root; - include unequal-rev { - revision-date "2001-05-19"; - } -} \ No newline at end of file + include unequal-rev { + revision-date "2001-05-19"; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/bug2649/foo.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/bug2649/foo.yang new file mode 100644 index 0000000000..65cb108366 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/bug2649/foo.yang @@ -0,0 +1,6 @@ +module foo { + prefix foo; + namespace "namespace-foo"; + + import import-module { prefix imp; revision-date 1970-01-01; } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/bug2649/import-module.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/bug2649/import-module.yang new file mode 100644 index 0000000000..f5408aabdd --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/bug2649/import-module.yang @@ -0,0 +1,8 @@ +module import-module { + prefix imp; + namespace "import-module"; + + revision 1970-01-01 { + description "Initial revision."; + } +} \ 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 index 30599987df..5edb432981 100644 --- 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 @@ -1,6 +1,6 @@ module imported { - namespace imported; - prefix imported; + namespace imported; + prefix imported; - revision "2000-01-01"; -} \ No newline at end of file + revision "2000-01-01"; +} 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 index 4f0785670c..9c1f226815 100644 --- 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 @@ -1,45 +1,58 @@ 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 + namespace root-ns; + prefix root-pref; + + yang-version 1; + + import imported { prefix imp-pref; revision-date "2000-01-01"; } + include submod; + + organization "cisco"; + contact "cisco email"; + + container cont-helper { + choice cont-choice { + case c1 { + } + case c2 { + } + } + } + + container cont { + must "../cont-helper" { + error-message "this is an error if helper not present"; + } + } + + augment "/cont" { + container cont-aug { + } + } + + notification notif1 { + } + + rpc rpc1 { + } + + deviation /cont { + deviate add { + container subcont { + } + } + reference "deviate reference"; + } + + identity identity1 { + } + + feature feature1 { + description "feature1 description"; + reference "feature1 reference"; + status "current"; + } + + extension ext1 { + } +} diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/identityreftest.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/identityreftest.yang new file mode 100644 index 0000000000..a39946c884 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/identityreftest.yang @@ -0,0 +1,14 @@ +module identity-ref-test { + yang-version 1; + namespace "urn:irt"; + prefix "irt"; + + organization "opendaylight"; + contact "http://www.opendaylight.org/"; + + revision "2015-06-03" { + reference "Initial revision."; + } + + identity my-type; +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/cycle-yang.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/cycle-yang.yang new file mode 100644 index 0000000000..894362fa00 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/cycle-yang.yang @@ -0,0 +1,8 @@ +module cycle-yang { + namespace cycle-yang; + prefix cya; + + import cycle-yin { + prefix cyi; + } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/cycle-yin.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/cycle-yin.yang new file mode 100644 index 0000000000..6624dfd3a5 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/cycle-yin.yang @@ -0,0 +1,8 @@ +module cycle-yin { + namespace cycle-yin; + prefix cyi; + + import cycle-yang { + prefix cya; + } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/egocentric.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/egocentric.yang new file mode 100644 index 0000000000..e6f3a9c4eb --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/egocentric.yang @@ -0,0 +1,8 @@ +module egocentric { + namespace egocentric; + prefix ego; + + import egocentric { + prefix ego; + } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/human.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/human.yang new file mode 100644 index 0000000000..955dfa7e4a --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/human.yang @@ -0,0 +1,8 @@ +module human { + namespace human; + prefix hum; + + import mammal { + prefix mammal; + } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/mammal.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/mammal.yang new file mode 100644 index 0000000000..1489fa0202 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/mammal.yang @@ -0,0 +1,8 @@ +module mammal { + namespace mammal; + prefix mam; + + import nature { + prefix nature; + } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/nature.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/nature.yang new file mode 100644 index 0000000000..92c3470512 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/import-arg-parsing/nature.yang @@ -0,0 +1,4 @@ +module nature { + namespace nature; + prefix nat; +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/error-module.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/error-module.yang new file mode 100644 index 0000000000..067bf206b2 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/error-module.yang @@ -0,0 +1,6 @@ +module error-module { + prefix "errm"; + namespace "errm"; + + include foo; +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/error-submodule.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/error-submodule.yang new file mode 100644 index 0000000000..181434a8ab --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/error-submodule.yang @@ -0,0 +1,7 @@ +submodule error-submodule { + belongs-to "root-module" { + prefix "rm"; + } + + include foo; +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/missing-parent.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/missing-parent.yang new file mode 100644 index 0000000000..d9345d81ce --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/missing-parent.yang @@ -0,0 +1,5 @@ +submodule missing-parent { + belongs-to foo { + prefix "f"; + } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/root-module.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/root-module.yang new file mode 100644 index 0000000000..46089f3532 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/root-module.yang @@ -0,0 +1,6 @@ +module root-module { + prefix rm; + namespace rm; + + include "submodule-1"; +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/submodule-1.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/submodule-1.yang new file mode 100644 index 0000000000..db7886f9d1 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/submodule-1.yang @@ -0,0 +1,6 @@ +submodule submodule-1 { + belongs-to "root-module" { + prefix "rm"; + } + include "submodule-2"; +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/submodule-2.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/submodule-2.yang new file mode 100644 index 0000000000..7b6e8ce353 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/include-arg-parsing/submodule-2.yang @@ -0,0 +1,5 @@ +submodule submodule-2 { + belongs-to "root-module" { + prefix "rm"; + } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/model/bar.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/model/bar.yang new file mode 100644 index 0000000000..d5cecfecdd --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/model/bar.yang @@ -0,0 +1,119 @@ +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/semantic-statement-parser/model/baz.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/model/baz.yang new file mode 100644 index 0000000000..e1dee2d002 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/model/baz.yang @@ -0,0 +1,194 @@ +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/semantic-statement-parser/model/foo.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/model/foo.yang new file mode 100644 index 0000000000..53bfd6e3c7 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/model/foo.yang @@ -0,0 +1,204 @@ +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; + } + + 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/semantic-statement-parser/model/subfoo.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/model/subfoo.yang new file mode 100644 index 0000000000..44e36e3798 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/model/subfoo.yang @@ -0,0 +1,65 @@ +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; + } + + extension sub-mountpoint { + argument "name" { + yin-element "true"; + } + } + + f:mountpoint "aaa"; + +} diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/revisions/more-revisions-test.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/revisions/more-revisions-test.yang new file mode 100644 index 0000000000..50d76db796 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/revisions/more-revisions-test.yang @@ -0,0 +1,14 @@ +module more-revisions { + namespace "urn.mr"; + prefix "mr"; + + //RFC6020 says that all revisions SHOULD be in reverse chronological order, but it doesn't say they MUST + //so, we have to take care of it in Java code (ModuleStatementSupport class) + revision "2015-05-07"; + + revision "2015-05-08"; + + revision "2015-05-01"; + + revision "2015-06-07"; +} diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/simple-types.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/simple-types.yang new file mode 100644 index 0000000000..30d0b13e5a --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/simple-types.yang @@ -0,0 +1,103 @@ +module simple-types { + + yang-version 1; + namespace "urn:simple.types"; + prefix "st"; + + organization "opendaylight"; + contact "WILL-BE-DEFINED-LATER"; + revision 2015-04-16; + + typedef myint8 { + type int8 { + range "1..20"; + } + } + + identity my-base; + + typedef myint32 { + type int32 { + range "1..2000"; + } + } + + container mycontainer { + leaf mynumerical { + type int32 { + range "1..3000"; + } + } + + leaf mynorestrictions { + type string; + } + + leaf mytypedefuse1 { + type myint32; + } + + leaf mytypedefuse2 { + type myint8; + } + + leaf myunion { + type union { + type int8; + type int32; + } + } + + leaf mydecimal64 { + type decimal64 { + fraction-digits 2; + range "1 .. 3.14 | 10 | 20..max"; + } + } + + leaf mystring { + type string { + length "1..255"; + pattern "[0-9a-fA-F]*"; + } + } + + leaf myenum { + type enumeration { + enum zero; + enum one; + enum seven { + value 7; + } + } + } + + leaf mybits { + type bits { + bit disable-nagle { + position 0; + } + bit auto-sense-speed { + position 1; + } + bit 10-Mb-only { + position 2; + } + } + default "auto-sense-speed"; + } + + leaf mgmt-interface { + type leafref { + path "../myenum"; + } + } + + leaf crypto { + type identityref { + base "my-base"; + } + } + + } +} diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/isis-topology@2013-07-12.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/isis-topology@2013-07-12.yang new file mode 100644 index 0000000000..23e9dbc1c5 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/isis-topology@2013-07-12.yang @@ -0,0 +1,143 @@ +module isis-topology { + yang-version 1; + namespace "urn:TBD:params:xml:ns:yang:network:isis-topology"; + // replace with IANA namespace when assigned + prefix "isis"; + import network-topology { + prefix nt; + revision-date 2013-07-12; + } + import l3-unicast-igp-topology { + prefix igp; + revision-date 2013-07-12; + } + import ted { + prefix ted; + revision-date 2013-07-12; + } + + organization "TBD"; + contact "TBD"; + description "ISIS Topology model"; + + revision "2013-07-12" { + description "Initial version"; + } + typedef iso-system-id { + description "ISO System ID. RFC 1237"; + type string { + pattern '[0-9a-fA-F]{4}(.[0-9a-fA-F]{4}){2}'; + } + } + + typedef iso-pseudonode-id { + description "ISO pseudonode id for broadcast network"; + type string { + pattern '[0-9a-fA-F]{2}'; + } + } + + typedef iso-net-id { + description "ISO NET ID. RFC 1237"; + type string { + pattern '[0-9a-fA-F]{2}((.[0-9a-fA-F]{4}){6})'; + } + } + + grouping isis-topology-type { + container isis { + presence "Indicates ISIS Topology"; + } + } + + augment "/nt:network-topology/nt:topology/nt:topology-types/igp:l3-unicast-igp-topology" { + uses isis-topology-type; + } + + augment "/nt:network-topology/nt:topology/igp:igp-topology-attributes" { + when "../../topology-types/isis"; + container isis-topogloy-attributes { + leaf net { + type iso-net-id; + } + } + } + + augment "/nt:network-topology/nt:topology/nt:node/igp:igp-node-attributes" { + when "../../../topology-types/isis"; + uses isis-node-attributes; + } + + augment "/nt:network-topology/nt:topology/nt:link/igp:igp-link-attributes" { + when "../../../../topology-types/isis"; + uses isis-link-attributes; + } + + grouping isis-node-attributes { + container isis-node-attributes { + container iso { + leaf iso-system-id { + type iso-system-id; + } + leaf iso-pseudonode-id { + default "0"; + type iso-pseudonode-id; + } + } + leaf-list net { + max-elements 3; + type iso-net-id; + } + leaf-list multi-topology-id { + description "List of Multi Topology Identifier upto 128 (0-127). RFC 4915"; + max-elements "128"; + type uint8 { + range "0..127"; + } + } + choice router-type { + case level-2 { + leaf level-2 { + type empty; + } + } + case level-1 { + leaf level-1 { + type empty; + } + } + case level-1-2 { + leaf level-1-2 { + type empty; + } + } + } + container ted { + uses ted:ted-node-attributes; + } + } + } + + grouping isis-link-attributes { + container isis-link-attributes { + leaf multi-topology-id { + type uint8 { + range "0..127"; + } + } + container ted { + uses ted:ted-link-attributes; + } + } + } + /* + augment "/igp:igp-node-event" { + uses isis-topology-type; + uses isis-node-attributes; + } + + augment "/igp:igp-link-event" { + uses isis-topology-type; + uses isis-link-attributes; + }*/ +} // Module isis-topology diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/isis-topology@2013-10-21.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/isis-topology@2013-10-21.yang new file mode 100644 index 0000000000..edf75ca6ea --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/isis-topology@2013-10-21.yang @@ -0,0 +1,143 @@ +module isis-topology { + yang-version 1; + namespace "urn:TBD:params:xml:ns:yang:network:isis-topology"; + // replace with IANA namespace when assigned + prefix "isis"; + import network-topology { + prefix nt; + revision-date 2013-10-21; + } + import l3-unicast-igp-topology { + prefix igp; + revision-date 2013-10-21; + } + import ted { + prefix ted; + revision-date 2013-10-21; + } + + organization "TBD"; + contact "TBD"; + description "ISIS Topology model"; + + revision "2013-10-21" { + description "Initial version"; + } + typedef iso-system-id { + description "ISO System ID. RFC 1237"; + type string { + pattern '[0-9a-fA-F]{4}(\.[0-9a-fA-F]{4}){2}'; + } + } + + typedef iso-pseudonode-id { + description "ISO pseudonode id for broadcast network"; + type string { + pattern '[0-9a-fA-F]{2}'; + } + } + typedef iso-net-id { + description "ISO NET ID. RFC 1237"; + type string { + pattern '[0-9a-fA-F]{2}((\.[0-9a-fA-F]{4}){6})'; + } + } + + grouping isis-topology-type { + container isis { + presence "Indicates ISIS Topology"; + } + } + + augment "/nt:network-topology/nt:topology/nt:topology-types/igp:l3-unicast-igp-topology" { + uses isis-topology-type; + } + + augment "/nt:network-topology/nt:topology/igp:igp-topology-attributes" { + when "../nt:topology-types/igp:l3-unicast-igp-topology/isis"; + container isis-topology-attributes { + leaf net { + type iso-net-id; + } + } + } + + augment "/nt:network-topology/nt:topology/nt:node/igp:igp-node-attributes" { + when "../../nt:topology-types/igp:l3-unicast-igp-topology/isis"; + uses isis-node-attributes; + } + + augment "/nt:network-topology/nt:topology/nt:link/igp:igp-link-attributes" { + + when "../../nt:topology-types/igp:l3-unicast-igp-topology/isis"; + uses isis-link-attributes; + } + + grouping isis-node-attributes { + container isis-node-attributes { + container iso { + leaf iso-system-id { + type iso-system-id; + } + leaf iso-pseudonode-id { + default "0"; + type iso-pseudonode-id; + } + } + leaf-list net { + max-elements 3; + type iso-net-id; + } + leaf-list multi-topology-id { + description "List of Multi Topology Identifier upto 128 (0-127). RFC 4915"; + max-elements "128"; + type uint8 { + range "0..127"; + } + } + choice router-type { + case level-2 { + leaf level-2 { + type empty; + } + } + case level-1 { + leaf level-1 { + type empty; + } + } + case level-1-2 { + leaf level-1-2 { + type empty; + } + } + } + container ted { + uses ted:ted-node-attributes; + } + } + } + + grouping isis-link-attributes { + container isis-link-attributes { + leaf multi-topology-id { + type uint8 { + range "0..127"; + } + } + container ted { + uses ted:ted-link-attributes; + } + } + } + + augment "/igp:igp-node-event" { + uses isis-topology-type; + uses isis-node-attributes; + } + + augment "/igp:igp-link-event" { + uses isis-topology-type; + uses isis-link-attributes; + } +} // Module isis-topology diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/l3-unicast-igp-topology@2013-07-12.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/l3-unicast-igp-topology@2013-07-12.yang new file mode 100644 index 0000000000..99df396d1d --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/l3-unicast-igp-topology@2013-07-12.yang @@ -0,0 +1,233 @@ +module l3-unicast-igp-topology { + yang-version 1; + namespace "urn:TBD:params:xml:ns:yang:nt:l3-unicast-igp-topology"; + // replace with IANA namespace when assigned + prefix "l3t"; + import network-topology { + prefix "nt"; + revision-date 2013-07-12; + } + + import ietf-inet-types { + prefix "inet"; + } + + organization "TBD"; + contact "TBD"; + + revision "2013-07-12" { + description "Initial revision"; + reference "TBD"; + } + + typedef igp-event-type { + description "IGP Event type for notifications"; + type enumeration { + enum "add" { + value 0; + description "An IGP node or link or prefix or termination-point has been added"; + } + enum "remove" { + value 1; + description "An IGP node or link or prefix or termination-point has been removed"; + } + enum "update" { + value 2; + description "An IGP node or link or prefix or termination-point has been updated"; + } + } + } // igp-event-type + + identity flag-identity { + description "Base type for flags"; + } + identity undefined-flag { + base "flag-identity"; + } + + typedef flag-type { + type identityref { + base "flag-identity"; + } + } + + grouping igp-prefix-attributes { + leaf prefix { + type inet:ip-prefix; + } + leaf metric { + type uint32; + } + leaf-list flag { + type flag-type; + } + } + + grouping l3-unicast-igp-topology-type { + container l3-unicast-igp-topology { + presence "indicates L3 Unicast IGP Topology"; + } + } + + grouping igp-topology-attributes { + container igp-topology-attributes { + leaf name { + description "Name of the topology"; + type string; + } + leaf-list flag { + description "Topology flags"; + type flag-type; + } + } + } + + grouping igp-node-attributes { + container igp-node-attributes { + leaf name { + description "Node name"; + type inet:domain-name; + } + leaf-list flag { + description "Node operational flags"; + type flag-type; + } + + leaf-list router-id { + description "Router-id for the node"; + type inet:ip-address; + } + + list prefix { + key "prefix"; + uses igp-prefix-attributes; + } + } + } + + grouping igp-link-attributes { + container igp-link-attributes { + leaf name { + description "Link Name"; + type string; + } + leaf-list flag { + description "Link flags"; + type flag-type; + } + leaf metric { + description "Link Metric"; + type uint32 { + range "0..16777215" { + description " + "; + // OSPF/ISIS supports max 3 byte metric. + // Ideally we would like this restriction to be + // defined in the derived models, however, + // we are not allowed to augment a "must" statement. + } + } + } + } + } // grouping igp-link-attributes + + grouping igp-termination-point-attributes { + container igp-termination-point-attributes { + choice termination-point-type { + case ip { + leaf-list ip-address { + description "IPv4 or IPv6 address"; + type inet:ip-address; + } + } + case unnumbered { + leaf unnumbered-id { + description "Unnumbered interface identifier"; + type uint32; + } + } + } + } + } // grouping igp-termination-point-attributes + + + augment "/nt:network-topology/nt:topology/nt:topology-types" { + uses l3-unicast-igp-topology-type; + } + + + augment "/nt:network-topology/nt:topology" { + when "topology-types/l3-unicast-igp-topology"; + uses igp-topology-attributes; + } + + augment "/nt:network-topology/nt:topology/nt:node" { + when "../../topology-types/l3-unicast-igp-topology"; + uses igp-node-attributes; + } + + + augment "/nt:network-topology/nt:topology/nt:link" { + when "../../topology-types/l3-unicast-igp-topology"; + uses igp-link-attributes; + } + augment "/nt:network-topology/nt:topology/nt:node/nt:termination-point" { + when "../../topology-types/l3-unicast-igp-topology"; + uses igp-termination-point-attributes; + } + + notification igp-node-event { + leaf igp-event-type { + type igp-event-type; + } + leaf topology-ref { + type nt:topology-ref; + } + uses l3-unicast-igp-topology-type; + uses nt:node-attributes; + uses igp-node-attributes; + } + + notification igp-link-event { + leaf igp-event-type { + type igp-event-type; + } + leaf topology-ref { + type nt:topology-ref; + } + uses l3-unicast-igp-topology-type; + uses nt:link-attributes; + uses igp-link-attributes; + } + + notification igp-prefix-event { + leaf igp-event-type { + type igp-event-type; + } + leaf topology-ref { + type nt:topology-ref; + } + leaf node-ref { + type nt:node-ref; + } + uses l3-unicast-igp-topology-type; + container prefix { + uses igp-prefix-attributes; + } + } + + notification termination-point-event { + leaf igp-event-type { + type igp-event-type; + } + leaf topology-ref { + type nt:topology-ref; + } + leaf node-ref { + type nt:node-ref; + } + uses l3-unicast-igp-topology-type; + uses nt:tp-attributes; + uses igp-termination-point-attributes; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/l3-unicast-igp-topology@2013-10-21.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/l3-unicast-igp-topology@2013-10-21.yang new file mode 100644 index 0000000000..00db145c96 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/l3-unicast-igp-topology@2013-10-21.yang @@ -0,0 +1,233 @@ +module l3-unicast-igp-topology { + yang-version 1; + namespace "urn:TBD:params:xml:ns:yang:nt:l3-unicast-igp-topology"; + // replace with IANA namespace when assigned + prefix "l3t"; + import network-topology { + prefix "nt"; + revision-date 2013-10-21; + } + + import ietf-inet-types { + prefix "inet"; + revision-date 2010-09-24; + } + + organization "TBD"; + contact "TBD"; + + revision "2013-10-21" { + description "Initial revision"; + reference "TBD"; + } + + typedef igp-event-type { + description "IGP Event type for notifications"; + type enumeration { + enum "add" { + value 0; + description "An IGP node or link or prefix or termination-point has been added"; + } + enum "remove" { + value 1; + description "An IGP node or link or prefix or termination-point has been removed"; + } + enum "update" { + value 2; + description "An IGP node or link or prefix or termination-point has been updated"; + } + } + } // igp-event-type + + identity flag-identity { + description "Base type for flags"; + } + identity undefined-flag { + base "flag-identity"; + } + + typedef flag-type { + + type identityref { + base "flag-identity"; + } + } + + grouping igp-prefix-attributes { + leaf prefix { + type inet:ip-prefix; + } + leaf metric { + type uint32; + } + leaf-list flag { + type flag-type; + } + } + + grouping l3-unicast-igp-topology-type { + container l3-unicast-igp-topology { + presence "indicates L3 Unicast IGP Topology"; + } + } + + grouping igp-topology-attributes { + container igp-topology-attributes { + leaf name { + description "Name of the topology"; + type string; + } + leaf-list flag { + description "Topology flags"; + type flag-type; + } + } + } + + grouping igp-node-attributes { + container igp-node-attributes { + leaf name { + description "Node name"; + type inet:domain-name; + } + leaf-list flag { + description "Node operational flags"; + type flag-type; + } + leaf-list router-id { + description "Router-id for the node"; + + type inet:ip-address; + } + list prefix { + key "prefix"; + uses igp-prefix-attributes; + } + } + } + + grouping igp-link-attributes { + container igp-link-attributes { + leaf name { + description "Link Name"; + type string; + } + leaf-list flag { + description "Link flags"; + type flag-type; + } + leaf metric { + description "Link Metric"; + type uint32 { + range "0..16777215" { + description " + "; + // OSPF/ISIS supports max 3 byte metric. + // Ideally we would like this restriction to be + // defined in the derived models, however, + // we are not allowed to augment a "must" statement. + } + } + } + } + } // grouping igp-link-attributes + + grouping igp-termination-point-attributes { + container igp-termination-point-attributes { + choice termination-point-type { + case ip { + leaf-list ip-address { + description "IPv4 or IPv6 address"; + type inet:ip-address; + } + } + case unnumbered { + leaf unnumbered-id { + description "Unnumbered interface identifier"; + type uint32; + + } + } + } + } + } // grouping igp-termination-point-attributes + + + augment "/nt:network-topology/nt:topology/nt:topology-types" { + uses l3-unicast-igp-topology-type; + } + + augment "/nt:network-topology/nt:topology" { + when "nt:topology-types/l3-unicast-igp-topology"; + uses igp-topology-attributes; + } + + augment "/nt:network-topology/nt:topology/nt:node" { + when "../nt:topology-types/l3-unicast-igp-topology"; + uses igp-node-attributes; + } + augment "/nt:network-topology/nt:topology/nt:link" { + when "../nt:topology-types/l3-unicast-igp-topology"; + uses igp-link-attributes; + } + augment "/nt:network-topology/nt:topology/nt:node/nt:termination-point" { + when "../../nt:topology-types/l3-unicast-igp-topology"; + uses igp-termination-point-attributes; + } + + notification igp-node-event { + leaf igp-event-type { + type igp-event-type; + } + leaf topology-ref { + type nt:topology-ref; + } + uses l3-unicast-igp-topology-type; + uses nt:node-attributes; + uses igp-node-attributes; + } + + notification igp-link-event { + leaf igp-event-type { + type igp-event-type; + } + leaf topology-ref { + type nt:topology-ref; + } + + uses l3-unicast-igp-topology-type; + uses nt:link-attributes; + uses igp-link-attributes; + } + + notification igp-prefix-event { + leaf igp-event-type { + type igp-event-type; + } + leaf topology-ref { + type nt:topology-ref; + } + leaf node-ref { + type nt:node-ref; + } + uses l3-unicast-igp-topology-type; + container prefix { + uses igp-prefix-attributes; + } + } + + notification termination-point-event { + leaf igp-event-type { + type igp-event-type; + } + leaf topology-ref { + type nt:topology-ref; + } + leaf node-ref { + type nt:node-ref; + } + uses l3-unicast-igp-topology-type; + uses nt:tp-attributes; + uses igp-termination-point-attributes; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/ted@2013-07-12.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/ted@2013-07-12.yang new file mode 100644 index 0000000000..0d0063d437 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/ted@2013-07-12.yang @@ -0,0 +1,301 @@ +module ted { + yang-version 1; + namespace "urn:TBD:params:xml:ns:yang:network:ted"; + // replace with IANA namespace when assigned + prefix ted; + + import ietf-inet-types { + prefix inet; + } + + organization "TBD"; + contact + "TBD"; + description + "Helper module to hold TED attributes for OSPF/ISIS"; + + revision 2013-07-12 { + description + "Initial revision"; + } + + typedef switching-capabilities { + description + "Switching Capabilities of an interface."; + reference + "RFC 5307: IS-IS Extensions in Support of Generalized + Multi-Protocol Label Switching (GMPLS)"; + type enumeration { + enum "PSC-1" { + description + "Packet-Switch Capable-1 (PSC-1)"; + value 1; + } + enum "PSC-2" { + description + "Packet-Switch Capable-2 (PSC-2)"; + value 2; + } + enum "PSC-3" { + description + "Packet-Switch Capable-3 (PSC-3)"; + value 3; + } + enum "PSC-4" { + description + "Packet-Switch Capable-4 (PSC-4)"; + value 4; + } + enum "L2SC" { + description + "Layer-2 Switch Capable (L2SC)"; + value 51; + } + enum "TDM" { + description + "Time-Division-Multiplex Capable (TDM)"; + value 100; + } + enum "LSC" { + description + "Lambda-Switch Capable (LSC)"; + value 150; + } + enum "FSC" { + description + "Fiber-Switch Capable (FSC)"; + value 200; + } + } + } + + typedef pcc-capabilities { + description + "Path Computation Capabilities."; + reference + "RFC 5088, draft-ietf-pce-disco-protoc-isis-07.txt + OSPF/ISIS Protocol Extensions for Path Computation Element (PCE) Discovery."; + type bits { + bit path-computation-with-gmpls-link-constraints { + position 0; + } + bit bidirectional-path-computation { + position 1; + } + bit diverse-path-computation { + position 2; + } + bit load-balanced-path-computation { + position 3; + } + bit synchronized-path-computation { + position 4; + } + bit support-for-multiple-objective-functions { + position 5; + } + bit support-for-additive-path-constraints { + position 6; + } + bit support-for-request-prioritization { + position 7; + } + bit support-for-multiple-requests-per-message { + position 8; + } + } + } + + +grouping srlg-attributes { + description + "Shared Risk Link Group Attributes"; + reference + "RFC 5307, RFC 4203: ISIS / OSPF Extensions in Support of + Generalized Multi-Protocol Label Switching (GMPLS)"; + list interface-switching-capabilities { + description + "List of interface capabilities for this interface"; + key "switching-capability"; + leaf switching-capability { + description + "Switching Capability for this interface"; + type ted:switching-capabilities; + } + leaf encoding { + description + "Encoding supported by this interface"; + type uint8; + } + list max-lsp-bandwidth { + description + "Maximum LSP Bandwidth at priorities 0-7"; + max-elements "8"; + key "priority"; + leaf priority { + type uint8 { + range "0..7"; + } + } + leaf bandwidth { + description + "Max LSP Bandwidth for this level"; + type decimal64 { + fraction-digits 2; + } + } + } + container packet-switch-capable { + when "../switching-capability = PSC-1 or ../switching-capability = PSC-2 or ../switching-capability = PSC-3 or ../switching-capability = PSC-4"; + description + "Interface has packet-switching capabilities"; + leaf minimum-lsp-bandwidth { + description + "Minimum LSP Bandwidth. Units in bytes per second"; + type decimal64 { + fraction-digits 2; + } + } + leaf interface-mtu { + description + "Interface MTU"; + type uint16; + } + } + container time-division-multiplex-capable { + when "../switching-capability = TDM"; + description + "Interface has time-division multiplex capabilities"; + leaf minimum-lsp-bandwidth { + description + "Minimum LSP Bandwidth. Units in bytes per second"; + type decimal64 { + fraction-digits 2; + } + } + leaf indication { + description + "Indication whether the interface supports Standard or Arbitrary SONET/SDH"; + type uint16; + } + } + } + list srlg-values { + description + "List of Shared Risk Link Group this interface belongs to."; + key "srlg-value"; + leaf srlg-value { + description + "Shared Risk Link Group value"; + type uint32; + } + } + leaf link-protection-type { + description + "Link Protection Type desired for this link"; + type uint16; + } + } + + grouping ted-node-attributes { + description + "Identifier to uniquely identify a node in TED"; + reference "RFC 5305, RFC 6119: IPv6 Traffic Engineering in IS-IS/OSPF"; + leaf te-router-id-ipv4 { + description + "Globally unique IPv4 Traffic Engineering Router ID."; + type inet:ipv4-address; + } + leaf te-router-id-ipv6 { + description + "Globally unique IPv6 Traffic Engineering Router ID"; + type inet:ipv6-address; + } + list ipv4-local-address { + description + "List of IPv4 Local Address(OSPF). RFC 5786"; + key "ipv4-prefix"; + leaf ipv4-prefix { + description + "Local IPv4 address for the node"; + type inet:ipv4-prefix; + } + } + list ipv6-local-address { + description + "List of IPv6 Local Address."; + reference + "RFC 5786: Advertising a Router's Local Addresses + in OSPF Traffic Engineering (TE) Extensions"; + key "ipv6-prefix"; + leaf ipv6-prefix { + description + "Local IPv6 address for the node"; + type inet:ipv6-prefix; + } + leaf prefix-option { + description + "IPv6 prefix option."; + type uint8; + } + } + leaf pcc-capabilities { + description + "OSPF/ISIS PCC capabilities"; + type pcc-capabilities; + } + } + + grouping ted-link-attributes { + description + "TED Attributes associated with the link."; + reference "RFC 3630, RFC 3784: IS-IS / OSPF Traffic Engineering (TE)"; + leaf color { + description + "Administrative group or color of the link"; + type uint32; + } + leaf max-link-bandwidth { + description + "Maximum bandwidth that can be see on this link in this direction. Units in bytes per second"; + type decimal64 { + fraction-digits 2; + } + } + leaf max-resv-link-bandwidth { + description + "Maximum amount of bandwidth that can be reserved in this direction in this link. Units in bytes per second"; + type decimal64 { + fraction-digits 2; + } + } + list unreserved-bandwidth { + description + "Unreserved bandwidth for 0-7 priority levels. Units in bytes per second"; + max-elements "8"; + key "priority"; + leaf priority { + type uint8 { + range "0..7"; + } + } + leaf bandwidth { + description + "Unreserved bandwidth for this level"; + type decimal64 { + fraction-digits 2; + } + } + } + leaf te-default-metric { + description + "Traffic Engineering Metric"; + type uint32; + } + container srlg { + description + "Shared Risk Link Group Attributes"; + uses srlg-attributes; + } + } +} diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/ted@2013-10-21.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/ted@2013-10-21.yang new file mode 100644 index 0000000000..745662380c --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/two-revisions/ted@2013-10-21.yang @@ -0,0 +1,306 @@ +module ted { + yang-version 1; + namespace "urn:TBD:params:xml:ns:yang:network:ted"; + // replace with IANA namespace when assigned + prefix ted; + + import ietf-inet-types { + prefix inet; + revision-date 2010-09-24; + } + + organization "TBD"; + contact + "TBD"; + description + "Helper module to hold TED attributes for OSPF/ISIS"; + + revision 2013-10-21 { + + description + "Initial revision"; + } + + typedef switching-capabilities { + description + "Switching Capabilities of an interface."; + reference + "RFC 5307: IS-IS Extensions in Support of Generalized + Multi-Protocol Label Switching (GMPLS)"; + type enumeration { + enum "PSC-1" { + description + "Packet-Switch Capable-1 (PSC-1)"; + value 1; + } + enum "PSC-2" { + description + "Packet-Switch Capable-2 (PSC-2)"; + value 2; + } + enum "PSC-3" { + description + "Packet-Switch Capable-3 (PSC-3)"; + value 3; + } + enum "PSC-4" { + description + "Packet-Switch Capable-4 (PSC-4)"; + value 4; + } + enum "L2SC" { + description + "Layer-2 Switch Capable (L2SC)"; + value 51; + } + enum "TDM" { + description + "Time-Division-Multiplex Capable (TDM)"; + value 100; + } + enum "LSC" { + description + "Lambda-Switch Capable (LSC)"; + value 150; + } + enum "FSC" { + description + + "Fiber-Switch Capable (FSC)"; + value 200; + } + } + } + + typedef pcc-capabilities { + description + "Path Computation Capabilities."; + reference + "RFC 5088, draft-ietf-pce-disco-protoc-isis-07.txt + OSPF/ISIS Protocol Extensions for Path Computation Element (PCE) Discovery."; + type bits { + bit path-computation-with-gmpls-link-constraints { + position 0; + } + bit bidirectional-path-computation { + position 1; + } + bit diverse-path-computation { + position 2; + } + bit load-balanced-path-computation { + position 3; + } + bit synchronized-path-computation { + position 4; + } + bit support-for-multiple-objective-functions { + position 5; + } + bit support-for-additive-path-constraints { + position 6; + } + bit support-for-request-prioritization { + position 7; + } + bit support-for-multiple-requests-per-message { + position 8; + } + } + } + + grouping ted-node-attributes { + description + "Identifier to uniquely identify a node in TED"; + reference "RFC 5305, RFC 6119: IPv6 Traffic Engineering in IS-IS/OSPF"; + leaf te-router-id-ipv4 { + + description + "Globally unique IPv4 Traffic Engineering Router ID."; + type inet:ipv4-address; + } + leaf te-router-id-ipv6 { + description + "Globally unique IPv6 Traffic Engineering Router ID"; + type inet:ipv6-address; + } + list ipv4-local-address { + description + "List of IPv4 Local Address(OSPF). RFC 5786"; + key "ipv4-prefix"; + leaf ipv4-prefix { + description + "Local IPv4 address for the node"; + type inet:ipv4-prefix; + } + } + list ipv6-local-address { + description + "List of IPv6 Local Address."; + reference + "RFC 5786: Advertising a Router's Local Addresses + in OSPF Traffic Engineering (TE) Extensions"; + key "ipv6-prefix"; + leaf ipv6-prefix { + description + "Local IPv6 address for the node"; + type inet:ipv6-prefix; + } + leaf prefix-option { + description + "IPv6 prefix option."; + type uint8; + } + } + leaf pcc-capabilities { + description + "OSPF/ISIS PCC capabilities"; + type pcc-capabilities; + } + } + + grouping ted-link-attributes { + description + "TED Attributes associated with the link."; + reference "RFC 3630, RFC 3784: IS-IS / OSPF Traffic Engineering (TE)"; + + leaf color { + description + "Administrative group or color of the link"; + type uint32; + } + leaf max-link-bandwidth { + description + "Maximum bandwidth that can be see on this link in this direction. Units in bytes per second"; + type decimal64 { + fraction-digits 2; + } + } + leaf max-resv-link-bandwidth { + description + "Maximum amount of bandwidth that can be reserved in this direction in this link. Units in bytes per second"; + type decimal64 { + fraction-digits 2; + } + } + list unreserved-bandwidth { + description + "Unreserved bandwidth for 0-7 priority levels. Units in bytes per second"; + max-elements "8"; + key "priority"; + leaf priority { + type uint8 { + range "0..7"; + } + } + leaf bandwidth { + description + "Unreserved bandwidth for this level"; + type decimal64 { + fraction-digits 2; + } + } + } + leaf te-default-metric { + description + "Traffic Engineering Metric"; + type uint32; + } + container srlg { + description + "Shared Risk Link Group Attributes"; + uses srlg-attributes; + } + } + + grouping srlg-attributes { + description + "Shared Risk Link Group Attributes"; + reference + "RFC 5307, RFC 4203: ISIS / OSPF Extensions in Support of + Generalized Multi-Protocol Label Switching (GMPLS)"; + list interface-switching-capabilities { + description + "List of interface capabilities for this interface"; + key "switching-capability"; + leaf switching-capability { + description + "Switching Capability for this interface"; + type ted:switching-capabilities; + } + leaf encoding { + description + "Encoding supported by this interface"; + type uint8; + } + list max-lsp-bandwidth { + description + "Maximum LSP Bandwidth at priorities 0-7"; + max-elements "8"; + key "priority"; + leaf priority { + type uint8 { + range "0..7"; + } + } + leaf bandwidth { + description + "Max LSP Bandwidth for this level"; + type decimal64 { + fraction-digits 2; + } + } + } + container packet-switch-capable { + when "../switching-capability = PSC-1 or ../switching-capability = PSC-2 or ../switching-capability = PSC-3 or ../switching-capability = PSC-4"; + description + "Interface has packet-switching capabilities"; + leaf minimum-lsp-bandwidth { + description + "Minimum LSP Bandwidth. Units in bytes per second"; + type decimal64 { + fraction-digits 2; + } + + } + leaf interface-mtu { + description + "Interface MTU"; + type uint16; + } + } + container time-division-multiplex-capable { + when "../switching-capability = TDM"; + description + "Interface has time-division multiplex capabilities"; + leaf minimum-lsp-bandwidth { + description + "Minimum LSP Bandwidth. Units in bytes per second"; + type decimal64 { + fraction-digits 2; + } + } + leaf indication { + description + "Indication whether the interface supports Standard or Arbitrary SONET/SDH"; + type uint16; + } + } + } + list srlg-values { + description + "List of Shared Risk Link Group this interface belongs to."; + key "srlg-value"; + leaf srlg-value { + description + "Shared Risk Link Group value"; + type uint32; + } + } + leaf link-protection-type { + description + "Link Protection Type desired for this link"; + type uint16; + } + } +} diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/types.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/types.yang new file mode 100644 index 0000000000..0470edcde8 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/types.yang @@ -0,0 +1,158 @@ +module custom-types-test { + + yang-version 1; + namespace "urn:custom.types.demo"; + prefix "iit"; + + organization "opendaylight"; + contact "WILL-BE-DEFINED-LATER"; + revision 2012-04-16 { + } + + import identity-ref-test { + prefix "irt"; + } + + extension mountpoint { + description "enter point"; + argument "name" { + yin-element "true"; + } + } + + typedef access-operations-type { + type bits { + bit create { + description "Any protocol operation that creates a new data node."; + } + bit read { + description "Any protocol operation or notification that returns the value of a data node."; + position 500; + } + bit update { + description "Any protocol operation that alters an existing data node."; + } + bit delete { + description "Any protocol operation that removes a data node."; + position 365; + } + bit exec { + description "Execution access to the specified protocol operation."; + } + } + description "NETCONF Access Operation."; + } + + leaf inst-id-leaf1 { + type instance-identifier { + require-instance false; + } + iit:mountpoint "mnt-extension"; + } + + leaf inst-id-leaf2 { + type instance-identifier; + } + + leaf type { + type service-type-ref; + } + + leaf type2 { + type service-type2-ref; + } + + leaf type3 { + type service-type3-ref; + } + + identity crypto-id { + base "crypto-base"; + description "crypto-id description"; + iit:mountpoint "mnt-extension"; + } + + identity crypto-base { + description "crypto-base description"; + } + + identity crypto-alg { + base "crypto-base"; + description "crypto-alg description"; + } + + identity crypto-def { + base "crypto-base"; + description "crypto-def description"; + } + + leaf mybits { + type bits { + bit disable-nagle { + position 0; + } + bit auto-sense-speed { + position 1; + } + bit 10-Mb-only { + position 2; + } + } + default "auto-sense-speed"; + } + + typedef ip-version { + type enumeration { + enum unknown { + description "An unknown or unspecified version of the Internet protocol."; + } + enum ipv4 { + value "19"; + description "The IPv4 protocol as defined in RFC 791."; + } + enum ipv6 { + value "7"; + description "The IPv6 protocol as defined in RFC 2460."; + } + enum default { + description "default ip"; + } + } + } + + identity service-type { + description + "Service identity base type. All service identities must be + derived from this type. A service type uniquely defines a single + atomic API contract, such as a Java interface, a set of C + function declarations, or similar. + + If the service type has a corresponding Java interface, the name + of that interface should be attached to the derived identity MUST + include a java-class keyword, whose name argument points to that + interface."; + } + + typedef service-type-ref { + description + "Internal type of references to service type identity."; + type identityref { + base service-type; + } + } + + typedef service-type2-ref { + description + "Internal type of references to service type2 identity."; + type identityref { + base irt:my-type; + } + } + + typedef service-type3-ref { + description + "Internal type of references to service type3 identity."; + type service-type-ref; + } + +} diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/types2.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/types2.yang new file mode 100644 index 0000000000..d69850fed5 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/types2.yang @@ -0,0 +1,97 @@ +module types2 { + namespace "types2"; + prefix "t2"; + + leaf lf-decimal { + type decimal64 { + fraction-digits 2; + range "1 .. 3.14 | 10 | 15..16 | 20..max"; + } + } + + leaf lf-my-string { + type string { + length "1..255 | 320..max"; + pattern "[0-9a-fA-F]*"; + pattern "aa*"; + } + } + + leaf my-bits { + type bits { + bit disable-nagle { + position 0; + status current; + } + bit auto-sense-speed { + position 1; + } + bit 10-Mb-only { + position 2; + } + } + default "auto-sense-speed"; + } + + type union { + type int32; + type string; + } + + grouping grp1 { + leaf myenum { + type enumeration { + enum zero; + enum one; + enum seven { + value 7; + } + } + default zero; + } + } + + container uses-cont { + uses t2:grp1 { + refine myenum { + default one; + } + } + } + + leaf lf-int8 { + type int8; + } + + leaf lf-int16 { + type int16; + } + + leaf lf-int32 { + type int32; + } + + leaf lf-int64 { + type int64; + } + + leaf lf-uint8 { + type uint8; + } + + leaf lf-uint16 { + type uint16; + } + + leaf lf-uint32 { + type uint32; + } + + leaf lf-uint64 { + type uint64; + } + + leaf lf-bool { + type boolean; + } +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/simple-test/simple-nodes.yang b/yang/yang-parser-impl/src/test/resources/simple-test/simple-nodes.yang index 38ebfd8277..9ccf0c73e7 100644 --- a/yang/yang-parser-impl/src/test/resources/simple-test/simple-nodes.yang +++ b/yang/yang-parser-impl/src/test/resources/simple-test/simple-nodes.yang @@ -127,4 +127,4 @@ module simple-nodes { when "class != 'wheel'"; } -} +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/extensions/mock.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/extensions/mock.yang new file mode 100644 index 0000000000..5c1602d231 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/stmt-test/extensions/mock.yang @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + module mock { + + namespace "a:b:c"; + prefix "m"; + + revision 2010-09-24 { + description + "Initial revision."; + } + + } diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/extensions/yang-ext.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/extensions/yang-ext.yang new file mode 100644 index 0000000000..0fbe94ddc4 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/stmt-test/extensions/yang-ext.yang @@ -0,0 +1,79 @@ +module yang-ext { + yang-version 1; + namespace "urn:opendaylight:yang:extension:yang-ext"; + prefix "ext"; + + contact "Anton Tkacik "; + + description + "Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Public License v1.0 which accompanies this distribution, + and is available at http://www.eclipse.org/legal/epl-v10.html"; + + revision "2013-07-09" { + description ""; + } + + // Augmentation name + + extension "augment-identifier" { + description + "YANG language extension which assigns an identifier to + augmentation. Augment identifier is used to identify + specific augment statement by name. + + The identifier syntax is defined formally defined by the rule + 'identifier' in Section 12 of RFC 6020. + + All augment identifiers defined in a namespace MUST be unique. + The namespace of augment identifiers is shared by module and + its submodules."; + + /* + Discussion: + This extension allows for ease of development / debug + of YANG modules and it is suitable for code generation, + where each augment statement is nicely identified by + unique name instead of combination of augment target + and when condition. + */ + argument "identifier"; + } + + + // Context-aware RPCs + + grouping rpc-context-ref { + description + "A reference to RPC context."; + leaf context-instance { + type instance-identifier; + description "Pointer to the context. "; + } + } + + extension "rpc-context-instance" { + description + "YANG language extension which defines enclosing (parent) + schema node as referencable context for RPCs. + + The argument is identity which is used to identify RPC context + type."; + + argument "context-type"; + } + + extension "context-reference" { + argument "context-type"; + } + + extension "context-instance" { + argument "context-type"; + } + + extension "instance-target" { + argument "path"; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/identity/cyclic-identity-test.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/identity/cyclic-identity-test.yang new file mode 100644 index 0000000000..94c3096510 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/stmt-test/identity/cyclic-identity-test.yang @@ -0,0 +1,34 @@ +module cyclic-identity-test { + namespace "cyclic.identity.test"; + prefix cid; + + identity child-identity-1 { + base child-identity-2; + } + + identity child-identity-2 { + base child-identity-3; + } + + identity child-identity-3 { + base child-identity-4; + } + + identity child-identity-4 { + base child-identity-1; + } + + identity base-identity { + } + + identity sub-identity { + base base-identity; + } + + identity sub-identity-2 { + base base-identity; + } + + container root-container { + } +} diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/identity/identity-test.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/identity/identity-test.yang new file mode 100644 index 0000000000..4836f80b63 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/stmt-test/identity/identity-test.yang @@ -0,0 +1,26 @@ +module identity-test { + namespace "identity.test"; + prefix id; + + identity root-identity { + description "root"; + } + + identity child-identity-1 { + description "child-identity-1"; + base root-identity; + } + + identity child-identity-2 { + description "child-identity-2"; + base root-identity; + } + + identity child-identity-1-2 { + description "child-identity-1-2"; + base child-identity-1; + } + + container root-container { + } +} diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/imported-module.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/imported-module.yang new file mode 100644 index 0000000000..3fd777ab44 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/imported-module.yang @@ -0,0 +1,8 @@ +module imported-module { + namespace "imported-module"; + prefix imp; + + container container-in-imported-module { + } + +} diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/root-module.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/root-module.yang new file mode 100644 index 0000000000..0756bcd5b9 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/root-module.yang @@ -0,0 +1,13 @@ +module root-module { + namespace "root-module"; + prefix root; + + import imported-module { prefix imp; revision-date 1970-01-01; } + + include submodule-1 { revision-date 1970-01-01; } + include submodule-2 { revision-date 1970-01-01; } + + container container-in-root-module { + description "desc"; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/submodule-1.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/submodule-1.yang new file mode 100644 index 0000000000..406551e054 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/submodule-1.yang @@ -0,0 +1,11 @@ +submodule submodule-1 { + + belongs-to root-module { + prefix root; + } + + include submodule-to-submodule-1 { revision-date 1970-01-01; } + + container container-in-submodule-1 { + } +} diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/submodule-2.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/submodule-2.yang new file mode 100644 index 0000000000..1d61c46842 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/submodule-2.yang @@ -0,0 +1,9 @@ +submodule submodule-2 { + + belongs-to root-module { + prefix root; + } + + container container-in-submodule-2 { + } +} diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/submodule-to-submodule-1.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/submodule-to-submodule-1.yang new file mode 100644 index 0000000000..d99ecbfc5f --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/stmt-test/submodules/submodule-to-submodule-1.yang @@ -0,0 +1,9 @@ +submodule submodule-to-submodule-1 { + + belongs-to root-module { + prefix root; + } + + container container-in-submodule-to-submodule-1 { + } +} diff --git a/yang/yang-parser-impl/src/test/resources/stmt-test/uses/refine-test.yang b/yang/yang-parser-impl/src/test/resources/stmt-test/uses/refine-test.yang new file mode 100644 index 0000000000..3d418a1b84 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/stmt-test/uses/refine-test.yang @@ -0,0 +1,57 @@ +module refine-test { + namespace "root-module"; + prefix root; + + container root-container { + container sub-container1 { + } + + uses grp-1 { + refine container-from-grouping/list-in-container { + min-elements 5; + max-elements 7; + description "new description"; + reference "new reference"; + config true; + must "2 = 2"; + } + refine container-from-grouping2/presence-container { + presence "presence desc"; + description "new description"; + reference "new reference"; + config true; + must "1 = 1"; + } + refine container-from-grouping/choice-from-grp { + mandatory true; + } + } + + container sub-container2 { + } + } + + grouping grp-1 { + container container-from-grouping { + list list-in-container { + min-elements 10; + max-elements 20; + description "original description"; + reference "original reference"; + config false; + must "1 = 1"; + } + choice choice-from-grp { + case one { + } + case two { + } + mandatory false; + } + } + container container-from-grouping2 { + container presence-container { + } + } + } +} -- 2.36.6