/* * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public 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; import static org.junit.Assert.assertEquals; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.text.DateFormat; import java.text.ParseException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Set; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; import org.opendaylight.yangtools.yang.common.YangConstants; 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.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException; import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; import org.opendaylight.yangtools.yang.parser.rfc6020.repo.YangStatementStreamSource; 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.YinStatementSourceImpl; import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class TestUtils { private static final Logger LOG = LoggerFactory.getLogger(TestUtils.class); private TestUtils() { } public static Set<Module> loadModules(final URI resourceDirectory) throws SourceException, ReactorException, IOException, YangSyntaxErrorException { final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR .newBuild(); File[] files = new File(resourceDirectory).listFiles(); for (File file : files) { if (file.getName().endsWith(YangConstants.RFC6020_YANG_FILE_EXTENSION)) { reactor.addSource(YangStatementStreamSource.create(YangTextSchemaSource.forFile(file))); } else { LOG.info("Ignoring non-yang file {}", file); } } EffectiveSchemaContext ctx = reactor.buildEffective(); return ctx.getModules(); } public static Set<Module> loadModules(final List<InputStream> streams) throws SourceException, ReactorException { final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR .newBuild(); for (InputStream inputStream : streams) { reactor.addSource(new YangStatementSourceImpl(inputStream)); } EffectiveSchemaContext ctx = reactor.buildEffective(); return ctx.getModules(); } public static Set<Module> loadYinModules(final URI resourceDirectory) throws ReactorException { final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); for (File file : new File(resourceDirectory).listFiles()) { reactor.addSource(new YinStatementSourceImpl(file.getPath(), true)); } EffectiveSchemaContext ctx = reactor.buildEffective(); return ctx.getModules(); } public static Set<Module> loadYinModules(final List<InputStream> streams) throws SourceException, ReactorException { final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); for (InputStream inputStream : streams) { reactor.addSource(new YinStatementSourceImpl(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(); reactor.addSource(new YangStatementSourceImpl(stream)); EffectiveSchemaContext ctx = reactor.buildEffective(); return ctx.getModules().iterator().next(); } public static Module loadYinModule(final InputStream stream) throws SourceException, ReactorException { final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); reactor.addSources(new YinStatementSourceImpl(stream)); EffectiveSchemaContext ctx = reactor.buildEffective(); return ctx.getModules().iterator().next(); } public static Module findModule(final Set<Module> 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<ModuleImport> 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<TypeDefinition<?>> 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<QName> 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 = SimpleDateFormatUtil.getRevisionFormat(); 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 : node.getChildNodes()) { checkIsAddedByUses(child, expected); } } public static List<Module> findModules(final Set<Module> modules, final String moduleName) { List<Module> result = new ArrayList<>(); for (Module module : modules) { if (module.getName().equals(moduleName)) { result.add(module); } } return result; } public static SchemaContext parseYangSources(final StatementStreamSource... sources) throws SourceException, ReactorException { CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR .newBuild(); reactor.addSources(sources); return reactor.buildEffective(); } public static SchemaContext parseYangSources(final File... files) throws SourceException, ReactorException, IOException, YangSyntaxErrorException { StatementStreamSource[] sources = new StatementStreamSource[files.length]; for (int i = 0; i < files.length; i++) { sources[i] = YangStatementStreamSource.create(YangTextSchemaSource.forFile(files[i])); } return parseYangSources(sources); } public static SchemaContext parseYangSources(final Collection<File> files) throws SourceException, ReactorException, IOException, YangSyntaxErrorException { return parseYangSources(files.toArray(new File[files.size()])); } public static SchemaContext parseYangSources(final String yangSourcesDirectoryPath) throws SourceException, ReactorException, URISyntaxException, IOException, YangSyntaxErrorException { URL resourceDir = StmtTestUtils.class .getResource(yangSourcesDirectoryPath); File testSourcesDir = new File(resourceDir.toURI()); return parseYangSources(testSourcesDir.listFiles()); } public static SchemaContext parseYangSource(final String yangSourceFilePath) throws SourceException, ReactorException, URISyntaxException, IOException, YangSyntaxErrorException { URL resourceFile = StmtTestUtils.class.getResource(yangSourceFilePath); File testSourcesFile = new File(resourceFile.toURI()); return parseYangSources(testSourcesFile); } }