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.Locale;
24 import java.util.ServiceLoader;
26 import java.util.stream.Collectors;
27 import org.eclipse.jdt.annotation.NonNull;
28 import org.opendaylight.yangtools.yang.common.QName;
29 import org.opendaylight.yangtools.yang.common.YangConstants;
30 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
31 import org.opendaylight.yangtools.yang.model.parser.api.YangParser;
32 import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
33 import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
34 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
35 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
36 import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode;
37 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
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() {
63 throw new UnsupportedOperationException("Utility class should not be instantiated.");
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 SchemaContext parseYangResource(final String resource) {
75 return parseYangResource(resource, StatementParserMode.DEFAULT_MODE);
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 SchemaContext parseYangResource(final String resource, final StatementParserMode parserMode) {
86 return parseYangResource(resource, parserMode, 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 SchemaContext parseYangResource(final String resource, final Set<QName> supportedFeatures) {
99 return parseYangResource(resource, StatementParserMode.DEFAULT_MODE, 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 SchemaContext parseYangResource(final String resource, final StatementParserMode parserMode,
112 final Set<QName> supportedFeatures) {
113 final YangTextSchemaSource source = YangTextSchemaSource.forResource(YangParserTestUtils.class, resource);
114 return parseYangSources(parserMode, 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 SchemaContext 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 SchemaContext parseYangFiles(final Collection<File> files) {
136 return parseYangFiles(StatementParserMode.DEFAULT_MODE, 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 SchemaContext parseYangFiles(final Set<QName> supportedFeatures, final File... files) {
149 return parseYangFiles(supportedFeatures, Arrays.asList(files));
152 public static SchemaContext parseYangFiles(final Set<QName> supportedFeatures, final Collection<File> files) {
153 return parseYangFiles(supportedFeatures, StatementParserMode.DEFAULT_MODE, files);
157 * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
159 * @param parserMode mode of statement parser
160 * @param files YANG files to be parsed
161 * @return effective schema context
163 public static SchemaContext parseYangFiles(final StatementParserMode parserMode, final File... files) {
164 return parseYangFiles(parserMode, Arrays.asList(files));
168 * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
170 * @param parserMode mode of statement parser
171 * @param files collection of YANG files to be parsed
172 * @return effective schema context
174 public static SchemaContext parseYangFiles(final StatementParserMode parserMode, final Collection<File> files) {
175 return parseYangFiles(null, parserMode, files);
179 * Creates a new effective schema context containing the specified YANG sources.
181 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
182 * models are resolved
183 * @param parserMode mode of statement parser
184 * @param files YANG files to be parsed
185 * @return effective schema context
187 public static SchemaContext parseYangFiles(final Set<QName> supportedFeatures,
188 final StatementParserMode parserMode, final File... files) {
189 return parseYangFiles(supportedFeatures, parserMode, Arrays.asList(files));
193 * Creates a new effective schema context containing the specified YANG sources.
195 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
196 * models are resolved
197 * @param parserMode mode of statement parser
198 * @param files YANG files to be parsed
199 * @return effective schema context
201 public static SchemaContext parseYangFiles(final Set<QName> supportedFeatures,
202 final StatementParserMode parserMode, final Collection<File> files) {
203 return parseSources(parserMode, supportedFeatures,
204 files.stream().map(YangTextSchemaSource::forFile).collect(Collectors.toList()));
208 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
209 * default mode and all YANG features are supported.
211 * @param resourcePath relative path to the directory with YANG files to be parsed
212 * @return effective schema context
214 public static SchemaContext parseYangResourceDirectory(final String resourcePath) {
215 return parseYangResourceDirectory(resourcePath, StatementParserMode.DEFAULT_MODE);
219 * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
221 * @param resourcePath relative path to the directory with YANG files to be parsed
222 * @param parserMode mode of statement parser
223 * @return effective schema context
225 public static SchemaContext parseYangResourceDirectory(final String resourcePath,
226 final StatementParserMode parserMode) {
227 return parseYangResourceDirectory(resourcePath, null, parserMode);
231 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
234 * @param resourcePath relative path to the directory with YANG files to be parsed
235 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
236 * models are resolved
237 * @return effective schema context
239 public static SchemaContext parseYangResourceDirectory(final String resourcePath,
240 final Set<QName> supportedFeatures) {
241 return parseYangResourceDirectory(resourcePath, supportedFeatures, StatementParserMode.DEFAULT_MODE);
245 * Creates a new effective schema context containing the specified YANG sources.
247 * @param resourcePath relative path to the directory with YANG files to be parsed
248 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
249 * models are resolved
250 * @param parserMode mode of statement parser
251 * @return effective schema context
253 @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Wrong inferent on listFiles")
254 public static SchemaContext parseYangResourceDirectory(final String resourcePath,
255 final Set<QName> supportedFeatures, final StatementParserMode parserMode) {
256 final URI directoryPath;
258 directoryPath = YangParserTestUtils.class.getResource(resourcePath).toURI();
259 } catch (URISyntaxException e) {
260 throw new IllegalArgumentException("Failed to open resource " + resourcePath, e);
262 return parseYangFiles(supportedFeatures, parserMode, new File(directoryPath).listFiles(YANG_FILE_FILTER));
266 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
267 * default mode and all YANG features are supported.
269 * @param clazz Resource lookup base
270 * @param resources Resource names to be looked up
271 * @return effective schema context
273 public static SchemaContext parseYangResources(final Class<?> clazz, final String... resources) {
274 return parseYangResources(clazz, Arrays.asList(resources));
277 public static SchemaContext parseYangResources(final Class<?> clazz, final Collection<String> resources) {
278 final List<YangTextSchemaSource> sources = new ArrayList<>(resources.size());
279 for (final String r : resources) {
280 sources.add(YangTextSchemaSource.forResource(clazz, r));
282 return parseSources(StatementParserMode.DEFAULT_MODE, null, sources);
286 * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
289 * @param yangDirs relative paths to the directories containing YANG files to be parsed
290 * @param yangFiles relative paths to the YANG files to be parsed
291 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
292 * models are resolved
293 * @return effective schema context
295 public static SchemaContext parseYangResources(final List<String> yangDirs, final List<String> yangFiles,
296 final Set<QName> supportedFeatures) {
297 return parseYangResources(yangDirs, yangFiles, supportedFeatures, StatementParserMode.DEFAULT_MODE);
301 * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
303 * @param yangResourceDirs relative paths to the directories containing YANG files to be parsed
304 * @param yangResources relative paths to the YANG files to be parsed
305 * @param statementParserMode mode of statement parser
306 * @return effective schema context
308 public static SchemaContext parseYangResources(final List<String> yangResourceDirs,
309 final List<String> yangResources, final StatementParserMode statementParserMode) {
310 return parseYangResources(yangResourceDirs, yangResources, null, statementParserMode);
314 * Creates a new effective schema context containing the specified YANG sources.
316 * @param yangResourceDirs relative paths to the directories containing YANG files to be parsed
317 * @param yangResources relative paths to the YANG files to be parsed
318 * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
319 * models are resolved
320 * @param statementParserMode mode of statement parser
321 * @return effective schema context
323 public static SchemaContext parseYangResources(final List<String> yangResourceDirs,
324 final List<String> yangResources, final Set<QName> supportedFeatures,
325 final StatementParserMode statementParserMode) {
326 final List<File> allYangFiles = new ArrayList<>();
327 for (final String yangDir : yangResourceDirs) {
328 allYangFiles.addAll(getYangFiles(yangDir));
331 for (final String yangFile : yangResources) {
333 allYangFiles.add(new File(YangParserTestUtils.class.getResource(yangFile).toURI()));
334 } catch (URISyntaxException e) {
335 throw new IllegalArgumentException("Invalid resource " + yangFile, e);
339 return parseYangFiles(supportedFeatures, statementParserMode, allYangFiles);
342 public static SchemaContext parseYangSources(final StatementParserMode parserMode,
343 final Set<QName> supportedFeatures, final YangTextSchemaSource... sources) {
344 return parseSources(parserMode, supportedFeatures, Arrays.asList(sources));
347 public static SchemaContext parseSources(final StatementParserMode parserMode, final Set<QName> supportedFeatures,
348 final Collection<? extends SchemaSourceRepresentation> sources) {
349 final YangParser parser = PARSER_FACTORY.createParser(parserMode);
350 if (supportedFeatures != null) {
351 parser.setSupportedFeatures(supportedFeatures);
355 parser.addSources(sources);
356 } catch (YangSyntaxErrorException e) {
357 throw new IllegalArgumentException("Malformed source", e);
358 } catch (IOException e) {
359 throw new IllegalArgumentException("Failed to read a source", e);
363 return parser.buildSchemaContext();
364 } catch (YangParserException e) {
365 throw new IllegalStateException("Failed to assemble SchemaContext", e);
369 @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Wrong inferent on listFiles")
370 private static Collection<File> getYangFiles(final String resourcePath) {
371 final URI directoryPath;
373 directoryPath = YangParserTestUtils.class.getResource(resourcePath).toURI();
374 } catch (URISyntaxException e) {
375 throw new IllegalArgumentException("Failed to open resource directory " + resourcePath, e);
377 return Arrays.asList(new File(directoryPath).listFiles(YANG_FILE_FILTER));