2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.onap.ccsdk.features.sdnr.wt.devicemanager.onf14.util;
10 import com.google.common.annotations.Beta;
12 import java.io.FileFilter;
13 import java.io.IOException;
15 import java.net.URISyntaxException;
16 import java.nio.file.Path;
17 import java.util.ArrayList;
18 import java.util.Arrays;
19 import java.util.Collection;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Locale;
23 import java.util.ServiceLoader;
25 import java.util.stream.Collectors;
26 import org.eclipse.jdt.annotation.NonNull;
27 import org.opendaylight.yangtools.yang.common.QName;
28 import org.opendaylight.yangtools.yang.common.YangConstants;
29 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
30 import org.opendaylight.yangtools.yang.parser.api.YangParser;
31 import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
32 import org.opendaylight.yangtools.yang.parser.api.YangParserException;
33 import org.opendaylight.yangtools.yang.parser.api.YangParserFactory;
34 import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException;
35 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
36 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
37 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
40 * Utility class which provides convenience methods for producing effective schema context based on the supplied
41 * yang/yin sources or paths to these sources.
44 public final class YangParserTestUtils {
46 private static final FileFilter YANG_FILE_FILTER = file -> {
47 // Locale keeps SpotBugs happy. It should not matter that much anyway.
48 final String name = file.getName().toLowerCase(Locale.ENGLISH);
49 return name.endsWith(YangConstants.RFC6020_YANG_FILE_EXTENSION) && file.isFile();
52 private static final @NonNull YangParserFactory PARSER_FACTORY;
55 final Iterator<@NonNull YangParserFactory> it = ServiceLoader.load(YangParserFactory.class).iterator();
57 throw new IllegalStateException("No YangParserFactory found");
59 PARSER_FACTORY = it.next();
62 private YangParserTestUtils() {
67 * Creates a new effective schema context containing the specified YANG source. Statement parser mode is set to
68 * default mode and all YANG features are supported.
70 * @param resource relative path to the YANG file to be parsed
72 * @return effective schema context
74 public static EffectiveModelContext parseYangResource(final String resource) {
75 return parseYangResource(resource, YangParserConfiguration.DEFAULT);
79 * Creates a new effective schema context containing the specified YANG source. All YANG features are supported.
81 * @param resource relative path to the YANG file to be parsed
82 * @param parserMode mode of statement parser
83 * @return effective schema context
85 public static EffectiveModelContext parseYangResource(final String resource, final YangParserConfiguration config) {
86 return parseYangResource(resource, config, null);
90 * Creates a new effective schema context containing the specified YANG source. Statement parser mode is set to
93 * @param resource relative path to the YANG file to be parsed
94 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
96 * @return effective schema context
98 public static EffectiveModelContext parseYangResource(final String resource, final Set<QName> supportedFeatures) {
99 return parseYangResource(resource, YangParserConfiguration.DEFAULT, supportedFeatures);
103 * Creates a new effective schema context containing the specified YANG source.
105 * @param resource relative path to the YANG file to be parsed
106 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
108 * @param parserMode mode of statement parser
109 * @return effective schema context
111 public static EffectiveModelContext parseYangResource(final String resource, final YangParserConfiguration config,
112 final Set<QName> supportedFeatures) {
113 final YangTextSchemaSource source = YangTextSchemaSource.forResource(YangParserTestUtils.class, resource);
114 return parseYangSources(config, supportedFeatures, source);
118 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
119 * default mode and all YANG features are supported.
121 * @param files YANG files to be parsed
122 * @return effective schema context
124 public static EffectiveModelContext parseYangFiles(final File... files) {
125 return parseYangFiles(Arrays.asList(files));
129 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
130 * default mode and all YANG features are supported.
132 * @param files collection of YANG files to be parsed
133 * @return effective schema context
135 public static EffectiveModelContext parseYangFiles(final Collection<File> files) {
136 return parseYangFiles(YangParserConfiguration.DEFAULT, files);
140 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
143 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
144 * models are resolved
145 * @param files YANG files to be parsed
146 * @return effective schema context
148 public static EffectiveModelContext parseYangFiles(final Set<QName> supportedFeatures, final File... files) {
149 return parseYangFiles(supportedFeatures, Arrays.asList(files));
152 public static EffectiveModelContext parseYangFiles(final Set<QName> supportedFeatures,
153 final Collection<File> files) {
154 return parseYangFiles(supportedFeatures, YangParserConfiguration.DEFAULT, files.stream().map(e->e.toPath()).collect(Collectors.toList()));
158 * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
160 * @param parserMode mode of statement parser
161 * @param files YANG files to be parsed
162 * @return effective schema context
164 public static EffectiveModelContext parseYangFiles(final YangParserConfiguration config, final File... files) {
165 return parseYangFiles(config, Arrays.asList(files));
169 * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
171 * @param parserMode mode of statement parser
172 * @param files collection of YANG files to be parsed
173 * @return effective schema context
175 public static EffectiveModelContext parseYangFiles(final YangParserConfiguration config,
176 final Collection<File> files) {
177 return parseYangFiles(null, config, files.stream().map(e->e.toPath()).collect(Collectors.toList()));
181 * Creates a new effective schema context containing the specified YANG sources.
183 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
184 * models are resolved
185 * @param parserMode mode of statement parser
186 * @param files YANG files to be parsed
187 * @return effective schema context
189 public static EffectiveModelContext parseYangFiles(final Set<QName> supportedFeatures,
190 final YangParserConfiguration config, final Path... files) {
191 return parseYangFiles(supportedFeatures, config, Arrays.asList(files));
195 * Creates a new effective schema context containing the specified YANG sources.
197 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
198 * models are resolved
199 * @param parserMode mode of statement parser
200 * @param files YANG files to be parsed
201 * @return effective schema context
203 public static EffectiveModelContext parseYangFiles(final Set<QName> supportedFeatures,
204 final YangParserConfiguration config, final Collection<Path> files) {
205 return parseSources(config, supportedFeatures,
206 files.stream().map(YangTextSchemaSource::forPath).collect(Collectors.toList()));
210 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
211 * default mode and all YANG features are supported.
213 * @param resourcePath relative path to the directory with YANG files to be parsed
214 * @return effective schema context
216 public static EffectiveModelContext parseYangResourceDirectory(final String resourcePath) {
217 return parseYangResourceDirectory(resourcePath, YangParserConfiguration.DEFAULT);
221 * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
223 * @param resourcePath relative path to the directory with YANG files to be parsed
224 * @param parserMode mode of statement parser
225 * @return effective schema context
227 public static EffectiveModelContext parseYangResourceDirectory(final String resourcePath,
228 final YangParserConfiguration config) {
229 return parseYangResourceDirectory(resourcePath, null, config);
233 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
236 * @param resourcePath relative path to the directory with YANG files to be parsed
237 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
238 * models are resolved
239 * @return effective schema context
241 public static EffectiveModelContext parseYangResourceDirectory(final String resourcePath,
242 final Set<QName> supportedFeatures) {
243 return parseYangResourceDirectory(resourcePath, supportedFeatures, YangParserConfiguration.DEFAULT);
247 * Creates a new effective schema context containing the specified YANG sources.
249 * @param resourcePath relative path to the directory with YANG files to be parsed
250 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
251 * models are resolved
252 * @param parserMode mode of statement parser
253 * @return effective schema context
255 @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Wrong inferent on listFiles")
256 public static EffectiveModelContext parseYangResourceDirectory(final String resourcePath,
257 final Set<QName> supportedFeatures, final YangParserConfiguration config) {
258 final URI directoryPath;
260 directoryPath = YangParserTestUtils.class.getResource(resourcePath).toURI();
261 } catch (URISyntaxException e) {
262 throw new IllegalArgumentException("Failed to open resource " + resourcePath, e);
264 File[] files = new File(directoryPath).listFiles(YANG_FILE_FILTER);
265 return parseYangFiles(supportedFeatures, config, Arrays.asList(files).stream().map(e->e.toPath()).collect(Collectors.toList()));
269 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
270 * default mode and all YANG features are supported.
272 * @param clazz Resource lookup base
273 * @param resources Resource names to be looked up
274 * @return effective schema context
276 public static EffectiveModelContext parseYangResources(final Class<?> clazz, final String... resources) {
277 return parseYangResources(clazz, Arrays.asList(resources));
280 public static EffectiveModelContext parseYangResources(final Class<?> clazz, final Collection<String> resources) {
281 final List<YangTextSchemaSource> sources = new ArrayList<>(resources.size());
282 for (final String r : resources) {
283 sources.add(YangTextSchemaSource.forResource(clazz, r));
285 return parseSources(YangParserConfiguration.DEFAULT, null, sources);
289 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
292 * @param yangDirs relative paths to the directories containing YANG files to be parsed
293 * @param yangFiles relative paths to the YANG files to be parsed
294 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
295 * models are resolved
296 * @return effective schema context
298 public static EffectiveModelContext parseYangResources(final List<String> yangDirs, final List<String> yangFiles,
299 final Set<QName> supportedFeatures) {
300 return parseYangResources(yangDirs, yangFiles, supportedFeatures, YangParserConfiguration.DEFAULT);
304 * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
306 * @param yangResourceDirs relative paths to the directories containing YANG files to be parsed
307 * @param yangResources relative paths to the YANG files to be parsed
308 * @param statementParserMode mode of statement parser
309 * @return effective schema context
311 public static EffectiveModelContext parseYangResources(final List<String> yangResourceDirs,
312 final List<String> yangResources, final YangParserConfiguration config) {
313 return parseYangResources(yangResourceDirs, yangResources, null, config);
317 * Creates a new effective schema context containing the specified YANG sources.
319 * @param yangResourceDirs relative paths to the directories containing YANG files to be parsed
320 * @param yangResources relative paths to the YANG files to be parsed
321 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
322 * models are resolved
323 * @param statementParserMode mode of statement parser
324 * @return effective schema context
326 public static EffectiveModelContext parseYangResources(final List<String> yangResourceDirs,
327 final List<String> yangResources, final Set<QName> supportedFeatures,
328 final YangParserConfiguration config) {
329 final List<File> allYangFiles = new ArrayList<>();
330 for (final String yangDir : yangResourceDirs) {
331 allYangFiles.addAll(getYangFiles(yangDir));
334 for (final String yangFile : yangResources) {
336 allYangFiles.add(new File(YangParserTestUtils.class.getResource(yangFile).toURI()));
337 } catch (URISyntaxException e) {
338 throw new IllegalArgumentException("Invalid resource " + yangFile, e);
342 return parseYangFiles(supportedFeatures, config, allYangFiles.stream().map(e->e.toPath()).collect(Collectors.toList()));
345 public static EffectiveModelContext parseYangSources(final YangParserConfiguration config,
346 final Set<QName> supportedFeatures, final YangTextSchemaSource... sources) {
347 return parseSources(config, supportedFeatures, Arrays.asList(sources));
350 public static EffectiveModelContext parseSources(final YangParserConfiguration config,
351 final Set<QName> supportedFeatures, final Collection<? extends SchemaSourceRepresentation> sources) {
352 final YangParser parser = PARSER_FACTORY.createParser(config);
353 if (supportedFeatures != null) {
354 parser.setSupportedFeatures(supportedFeatures);
358 parser.addSources(sources);
359 } catch (YangSyntaxErrorException e) {
360 throw new IllegalArgumentException("Malformed source", e);
361 } catch (IOException e) {
362 throw new IllegalArgumentException("Failed to read a source", e);
366 return parser.buildEffectiveModel();
367 } catch (YangParserException e) {
368 throw new IllegalStateException("Failed to assemble SchemaContext", e);
372 @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Wrong inferent on listFiles")
373 private static Collection<File> getYangFiles(final String resourcePath) {
374 final URI directoryPath;
376 directoryPath = YangParserTestUtils.class.getResource(resourcePath).toURI();
377 } catch (URISyntaxException e) {
378 throw new IllegalArgumentException("Failed to open resource directory " + resourcePath, e);
380 return Arrays.asList(new File(directoryPath).listFiles(YANG_FILE_FILTER));