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
9 package org.opendaylight.yangtools.yang.test.util;
11 import com.google.common.annotations.Beta;
12 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
14 import java.io.FileFilter;
15 import java.io.IOException;
17 import java.net.URISyntaxException;
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.Collection;
21 import java.util.Iterator;
22 import java.util.List;
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.SchemaContext;
30 import org.opendaylight.yangtools.yang.model.parser.api.YangParser;
31 import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
32 import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
33 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
34 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
35 import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode;
36 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
39 * Utility class which provides convenience methods for producing effective schema context based on the supplied
40 * yang/yin sources or paths to these sources.
43 public final class YangParserTestUtils {
45 private static final FileFilter YANG_FILE_FILTER = file -> {
46 final String name = file.getName().toLowerCase();
47 return name.endsWith(YangConstants.RFC6020_YANG_FILE_EXTENSION) && file.isFile();
50 private static final @NonNull YangParserFactory PARSER_FACTORY;
53 final Iterator<@NonNull YangParserFactory> it = ServiceLoader.load(YangParserFactory.class).iterator();
55 throw new IllegalStateException("No YangParserFactory found");
57 PARSER_FACTORY = it.next();
60 private YangParserTestUtils() {
61 throw new UnsupportedOperationException("Utility class should not be instantiated.");
65 * Creates a new effective schema context containing the specified YANG source. Statement parser mode is set to
66 * default mode and all YANG features are supported.
68 * @param resource relative path to the YANG file to be parsed
70 * @return effective schema context
72 public static SchemaContext parseYangResource(final String resource) {
73 return parseYangResource(resource, StatementParserMode.DEFAULT_MODE);
77 * Creates a new effective schema context containing the specified YANG source. All YANG features are supported.
79 * @param resource relative path to the YANG file to be parsed
80 * @param parserMode mode of statement parser
81 * @return effective schema context
83 public static SchemaContext parseYangResource(final String resource, final StatementParserMode parserMode) {
84 return parseYangResource(resource, parserMode, null);
88 * Creates a new effective schema context containing the specified YANG source. Statement parser mode is set to
91 * @param resource relative path to the YANG file to be parsed
92 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
94 * @return effective schema context
96 public static SchemaContext parseYangResource(final String resource, final Set<QName> supportedFeatures) {
97 return parseYangResource(resource, StatementParserMode.DEFAULT_MODE, supportedFeatures);
101 * Creates a new effective schema context containing the specified YANG source.
103 * @param resource relative path to the YANG file to be parsed
104 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
106 * @param parserMode mode of statement parser
107 * @return effective schema context
109 public static SchemaContext parseYangResource(final String resource, final StatementParserMode parserMode,
110 final Set<QName> supportedFeatures) {
111 final YangTextSchemaSource source = YangTextSchemaSource.forResource(YangParserTestUtils.class, resource);
112 return parseYangSources(parserMode, supportedFeatures, source);
116 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
117 * default mode and all YANG features are supported.
119 * @param files YANG files to be parsed
120 * @return effective schema context
122 public static SchemaContext parseYangFiles(final File... files) {
123 return parseYangFiles(Arrays.asList(files));
127 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
128 * default mode and all YANG features are supported.
130 * @param files collection of YANG files to be parsed
131 * @return effective schema context
133 public static SchemaContext parseYangFiles(final Collection<File> files) {
134 return parseYangFiles(StatementParserMode.DEFAULT_MODE, files);
138 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
141 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
142 * models are resolved
143 * @param files YANG files to be parsed
144 * @return effective schema context
146 public static SchemaContext parseYangFiles(final Set<QName> supportedFeatures, final File... files) {
147 return parseYangFiles(supportedFeatures, Arrays.asList(files));
150 public static SchemaContext parseYangFiles(final Set<QName> supportedFeatures, final Collection<File> files) {
151 return parseYangFiles(supportedFeatures, StatementParserMode.DEFAULT_MODE, files);
155 * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
157 * @param parserMode mode of statement parser
158 * @param files YANG files to be parsed
159 * @return effective schema context
161 public static SchemaContext parseYangFiles(final StatementParserMode parserMode, final File... files) {
162 return parseYangFiles(parserMode, Arrays.asList(files));
166 * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
168 * @param parserMode mode of statement parser
169 * @param files collection of YANG files to be parsed
170 * @return effective schema context
172 public static SchemaContext parseYangFiles(final StatementParserMode parserMode, final Collection<File> files) {
173 return parseYangFiles(null, parserMode, files);
177 * Creates a new effective schema context containing the specified YANG sources.
179 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
180 * models are resolved
181 * @param parserMode mode of statement parser
182 * @param files YANG files to be parsed
183 * @return effective schema context
185 public static SchemaContext parseYangFiles(final Set<QName> supportedFeatures,
186 final StatementParserMode parserMode, final File... files) {
187 return parseYangFiles(supportedFeatures, parserMode, Arrays.asList(files));
191 * Creates a new effective schema context containing the specified YANG sources.
193 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
194 * models are resolved
195 * @param parserMode mode of statement parser
196 * @param files YANG files to be parsed
197 * @return effective schema context
199 public static SchemaContext parseYangFiles(final Set<QName> supportedFeatures,
200 final StatementParserMode parserMode, final Collection<File> files) {
201 return parseSources(parserMode, supportedFeatures,
202 files.stream().map(YangTextSchemaSource::forFile).collect(Collectors.toList()));
206 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
207 * default mode and all YANG features are supported.
209 * @param resourcePath relative path to the directory with YANG files to be parsed
210 * @return effective schema context
212 public static SchemaContext parseYangResourceDirectory(final String resourcePath) {
213 return parseYangResourceDirectory(resourcePath, StatementParserMode.DEFAULT_MODE);
217 * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
219 * @param resourcePath relative path to the directory with YANG files to be parsed
220 * @param parserMode mode of statement parser
221 * @return effective schema context
223 public static SchemaContext parseYangResourceDirectory(final String resourcePath,
224 final StatementParserMode parserMode) {
225 return parseYangResourceDirectory(resourcePath, null, parserMode);
229 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
232 * @param resourcePath relative path to the directory with YANG files to be parsed
233 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
234 * models are resolved
235 * @return effective schema context
237 public static SchemaContext parseYangResourceDirectory(final String resourcePath,
238 final Set<QName> supportedFeatures) {
239 return parseYangResourceDirectory(resourcePath, supportedFeatures, StatementParserMode.DEFAULT_MODE);
243 * Creates a new effective schema context containing the specified YANG sources.
245 * @param resourcePath relative path to the directory with YANG files to be parsed
246 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
247 * models are resolved
248 * @param parserMode mode of statement parser
249 * @return effective schema context
251 @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Wrong inferent on listFiles")
252 public static SchemaContext parseYangResourceDirectory(final String resourcePath,
253 final Set<QName> supportedFeatures, final StatementParserMode parserMode) {
254 final URI directoryPath;
256 directoryPath = YangParserTestUtils.class.getResource(resourcePath).toURI();
257 } catch (URISyntaxException e) {
258 throw new IllegalArgumentException("Failed to open resource " + resourcePath, e);
260 return parseYangFiles(supportedFeatures, parserMode, new File(directoryPath).listFiles(YANG_FILE_FILTER));
264 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
265 * default mode and all YANG features are supported.
267 * @param clazz Resource lookup base
268 * @param resources Resource names to be looked up
269 * @return effective schema context
271 public static SchemaContext parseYangResources(final Class<?> clazz, final String... resources) {
272 return parseYangResources(clazz, Arrays.asList(resources));
275 public static SchemaContext parseYangResources(final Class<?> clazz, final Collection<String> resources) {
276 final List<YangTextSchemaSource> sources = new ArrayList<>(resources.size());
277 for (final String r : resources) {
278 sources.add(YangTextSchemaSource.forResource(clazz, r));
280 return parseSources(StatementParserMode.DEFAULT_MODE, null, sources);
284 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
287 * @param yangDirs relative paths to the directories containing YANG files to be parsed
288 * @param yangFiles relative paths to the YANG files to be parsed
289 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
290 * models are resolved
291 * @return effective schema context
293 public static SchemaContext parseYangResources(final List<String> yangDirs, final List<String> yangFiles,
294 final Set<QName> supportedFeatures) {
295 return parseYangResources(yangDirs, yangFiles, supportedFeatures, StatementParserMode.DEFAULT_MODE);
299 * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
301 * @param yangResourceDirs relative paths to the directories containing YANG files to be parsed
302 * @param yangResources relative paths to the YANG files to be parsed
303 * @param statementParserMode mode of statement parser
304 * @return effective schema context
306 public static SchemaContext parseYangResources(final List<String> yangResourceDirs,
307 final List<String> yangResources, final StatementParserMode statementParserMode) {
308 return parseYangResources(yangResourceDirs, yangResources, null, statementParserMode);
312 * Creates a new effective schema context containing the specified YANG sources.
314 * @param yangResourceDirs relative paths to the directories containing YANG files to be parsed
315 * @param yangResources relative paths to the YANG files to be parsed
316 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
317 * models are resolved
318 * @param statementParserMode mode of statement parser
319 * @return effective schema context
321 public static SchemaContext parseYangResources(final List<String> yangResourceDirs,
322 final List<String> yangResources, final Set<QName> supportedFeatures,
323 final StatementParserMode statementParserMode) {
324 final List<File> allYangFiles = new ArrayList<>();
325 for (final String yangDir : yangResourceDirs) {
326 allYangFiles.addAll(getYangFiles(yangDir));
329 for (final String yangFile : yangResources) {
331 allYangFiles.add(new File(YangParserTestUtils.class.getResource(yangFile).toURI()));
332 } catch (URISyntaxException e) {
333 throw new IllegalArgumentException("Invalid resource " + yangFile, e);
337 return parseYangFiles(supportedFeatures, statementParserMode, allYangFiles);
340 public static SchemaContext parseYangSources(final StatementParserMode parserMode,
341 final Set<QName> supportedFeatures, final YangTextSchemaSource... sources) {
342 return parseSources(parserMode, supportedFeatures, Arrays.asList(sources));
345 public static SchemaContext parseSources(final StatementParserMode parserMode, final Set<QName> supportedFeatures,
346 final Collection<? extends SchemaSourceRepresentation> sources) {
347 final YangParser parser = PARSER_FACTORY.createParser(parserMode);
348 if (supportedFeatures != null) {
349 parser.setSupportedFeatures(supportedFeatures);
353 parser.addSources(sources);
354 } catch (YangSyntaxErrorException e) {
355 throw new IllegalArgumentException("Malformed source", e);
356 } catch (IOException e) {
357 throw new IllegalArgumentException("Failed to read a source", e);
361 return parser.buildSchemaContext();
362 } catch (YangParserException e) {
363 throw new IllegalStateException("Failed to assemble SchemaContext", e);
367 @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Wrong inferent on listFiles")
368 private static Collection<File> getYangFiles(final String resourcePath) {
369 final URI directoryPath;
371 directoryPath = YangParserTestUtils.class.getResource(resourcePath).toURI();
372 } catch (URISyntaxException e) {
373 throw new IllegalArgumentException("Failed to open resource directory " + resourcePath, e);
375 return Arrays.asList(new File(directoryPath).listFiles(YANG_FILE_FILTER));