Remove deprecated Yin/YangStatementSourceImpl
[yangtools.git] / yang / yang-test-util / src / main / java / org / opendaylight / yangtools / yang / test / util / YangParserTestUtils.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.yangtools.yang.test.util;
10
11 import com.google.common.annotations.Beta;
12 import java.io.File;
13 import java.io.FileFilter;
14 import java.io.IOException;
15 import java.net.URI;
16 import java.net.URISyntaxException;
17 import java.util.ArrayList;
18 import java.util.Arrays;
19 import java.util.Collection;
20 import java.util.List;
21 import java.util.Set;
22 import java.util.stream.Collectors;
23 import org.opendaylight.yangtools.yang.common.QName;
24 import org.opendaylight.yangtools.yang.common.YangConstants;
25 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
26 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
27 import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode;
28 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
29 import org.opendaylight.yangtools.yang.parser.rfc6020.repo.YangStatementStreamSource;
30 import org.opendaylight.yangtools.yang.parser.rfc6020.repo.YinStatementStreamSource;
31 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
32 import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
33 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
34 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
35
36 /**
37  * Utility class which provides convenience methods for producing effective schema context based on the supplied
38  * yang/yin sources or paths to these sources.
39  */
40 @Beta
41 public final class YangParserTestUtils {
42
43     private static final FileFilter YANG_FILE_FILTER = file -> {
44         final String name = file.getName().toLowerCase();
45         return name.endsWith(YangConstants.RFC6020_YANG_FILE_EXTENSION) && file.isFile();
46     };
47
48     private YangParserTestUtils() {
49         throw new UnsupportedOperationException("Utility class should not be instantiated.");
50     }
51
52     /**
53      * Creates a new effective schema context containing the specified YANG source. Statement parser mode is set to
54      * default mode and all YANG features are supported.
55      *
56      * @param resource relative path to the YANG file to be parsed
57      *
58      * @return effective schema context
59      */
60     public static SchemaContext parseYangResource(final String resource) {
61         return parseYangResource(resource, StatementParserMode.DEFAULT_MODE);
62     }
63
64     /**
65      * Creates a new effective schema context containing the specified YANG source. All YANG features are supported.
66      *
67      * @param resource relative path to the YANG file to be parsed
68      * @param parserMode mode of statement parser
69      * @return effective schema context
70      */
71     public static SchemaContext parseYangResource(final String resource, final StatementParserMode parserMode) {
72         return parseYangResource(resource, parserMode, null);
73     }
74
75     /**
76      * Creates a new effective schema context containing the specified YANG source. Statement parser mode is set to
77      * default mode.
78      *
79      * @param resource relative path to the YANG file to be parsed
80      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
81      *                          model are resolved
82      * @return effective schema context
83      */
84     public static SchemaContext parseYangResource(final String resource, final Set<QName> supportedFeatures) {
85         return parseYangResource(resource, StatementParserMode.DEFAULT_MODE, supportedFeatures);
86     }
87
88     /**
89      * Creates a new effective schema context containing the specified YANG source.
90      *
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
93      *                          model are resolved
94      * @param parserMode mode of statement parser
95      * @return effective schema context
96      */
97     public static SchemaContext parseYangResource(final String resource, final StatementParserMode parserMode,
98             final Set<QName> supportedFeatures) {
99         final YangTextSchemaSource source = YangTextSchemaSource.forResource(YangParserTestUtils.class, resource);
100         return parseYangSources(parserMode, supportedFeatures, source);
101     }
102
103     /**
104      * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
105      * default mode and all YANG features are supported.
106      *
107      * @param files YANG files to be parsed
108      * @return effective schema context
109      */
110     public static SchemaContext parseYangFiles(final File... files) {
111         return parseYangFiles(Arrays.asList(files));
112     }
113
114     /**
115      * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
116      * default mode and all YANG features are supported.
117      *
118      * @param files collection of YANG files to be parsed
119      * @return effective schema context
120      */
121     public static SchemaContext parseYangFiles(final Collection<File> files) {
122         return parseYangFiles(StatementParserMode.DEFAULT_MODE, files);
123     }
124
125     /**
126      * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
127      * default mode.
128      *
129      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
130      *                          models are resolved
131      * @param files YANG files to be parsed
132      * @return effective schema context
133      */
134     public static SchemaContext parseYangFiles(final Set<QName> supportedFeatures, final File... files) {
135         return parseYangFiles(supportedFeatures, Arrays.asList(files));
136     }
137
138     public static SchemaContext parseYangFiles(final Set<QName> supportedFeatures, final Collection<File> files) {
139         return parseYangFiles(supportedFeatures, StatementParserMode.DEFAULT_MODE, files);
140     }
141
142     /**
143      * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
144      *
145      * @param parserMode mode of statement parser
146      * @param files YANG files to be parsed
147      * @return effective schema context
148      */
149     public static SchemaContext parseYangFiles(final StatementParserMode parserMode, final File... files) {
150         return parseYangFiles(parserMode, Arrays.asList(files));
151     }
152
153     /**
154      * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
155      *
156      * @param parserMode mode of statement parser
157      * @param files collection of YANG files to be parsed
158      * @return effective schema context
159      */
160     public static SchemaContext parseYangFiles(final StatementParserMode parserMode, final Collection<File> files) {
161         return parseYangFiles(null, parserMode, files);
162     }
163
164     /**
165      * Creates a new effective schema context containing the specified YANG sources.
166      *
167      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
168      *                          models are resolved
169      * @param parserMode mode of statement parser
170      * @param files YANG files to be parsed
171      * @return effective schema context
172      */
173     public static SchemaContext parseYangFiles(final Set<QName> supportedFeatures,
174             final StatementParserMode parserMode, final File... files) {
175         return parseYangFiles(supportedFeatures, parserMode, Arrays.asList(files));
176     }
177
178     /**
179      * Creates a new effective schema context containing the specified YANG sources.
180      *
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
186      */
187     public static SchemaContext parseYangFiles(final Set<QName> supportedFeatures,
188             final StatementParserMode parserMode, final Collection<File> files) {
189         return parseYangSources(supportedFeatures, parserMode,
190             files.stream().map(YangTextSchemaSource::forFile).collect(Collectors.toList()));
191     }
192
193     /**
194      * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
195      * default mode and all YANG features are supported.
196      *
197      * @param resourcePath relative path to the directory with YANG files to be parsed
198      * @return effective schema context
199      */
200     public static SchemaContext parseYangResourceDirectory(final String resourcePath) {
201         return parseYangResourceDirectory(resourcePath, StatementParserMode.DEFAULT_MODE);
202     }
203
204     /**
205      * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
206      *
207      * @param resourcePath relative path to the directory with YANG files to be parsed
208      * @param parserMode mode of statement parser
209      * @return effective schema context
210      */
211     public static SchemaContext parseYangResourceDirectory(final String resourcePath,
212             final StatementParserMode parserMode) {
213         return parseYangResourceDirectory(resourcePath, null, parserMode);
214     }
215
216     /**
217      * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
218      * default mode.
219      *
220      * @param resourcePath relative path to the directory with YANG files to be parsed
221      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
222      *                          models are resolved
223      * @return effective schema context
224      */
225     public static SchemaContext parseYangResourceDirectory(final String resourcePath,
226             final Set<QName> supportedFeatures) {
227         return parseYangResourceDirectory(resourcePath, supportedFeatures, StatementParserMode.DEFAULT_MODE);
228     }
229
230     /**
231      * Creates a new effective schema context containing the specified YANG sources.
232      *
233      * @param resourcePath relative path to the directory with YANG files to be parsed
234      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
235      *                          models are resolved
236      * @param parserMode mode of statement parser
237      * @return effective schema context
238      */
239     public static SchemaContext parseYangResourceDirectory(final String resourcePath,
240             final Set<QName> supportedFeatures, final StatementParserMode parserMode) {
241         final URI directoryPath;
242         try {
243             directoryPath = YangParserTestUtils.class.getResource(resourcePath).toURI();
244         } catch (URISyntaxException e) {
245             throw new IllegalArgumentException("Failed to open resource " + resourcePath, e);
246         }
247         return parseYangFiles(supportedFeatures, parserMode, new File(directoryPath).listFiles(YANG_FILE_FILTER));
248     }
249
250     /**
251      * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
252      * default mode and all YANG features are supported.
253      *
254      * @param clazz Resource lookup base
255      * @param resources Resource names to be looked up
256      * @return effective schema context
257      */
258     public static SchemaContext parseYangResources(final Class<?> clazz, final String... resources) {
259         final List<YangTextSchemaSource> sources = new ArrayList<>(resources.length);
260         for (final String r : resources) {
261             sources.add(YangTextSchemaSource.forResource(clazz, r));
262         }
263         return parseYangSources(null, StatementParserMode.DEFAULT_MODE, sources);
264     }
265
266     /**
267      * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
268      * default mode.
269      *
270      * @param yangDirs relative paths to the directories containing YANG files to be parsed
271      * @param yangFiles relative paths to the YANG files to be parsed
272      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
273      *                          models are resolved
274      * @return effective schema context
275      */
276     public static SchemaContext parseYangResources(final List<String> yangDirs, final List<String> yangFiles,
277             final Set<QName> supportedFeatures) {
278         return parseYangResources(yangDirs, yangFiles, supportedFeatures, StatementParserMode.DEFAULT_MODE);
279     }
280
281     /**
282      * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
283      *
284      * @param yangResourceDirs relative paths to the directories containing YANG files to be parsed
285      * @param yangResources relative paths to the YANG files to be parsed
286      * @param statementParserMode mode of statement parser
287      * @return effective schema context
288      */
289     public static SchemaContext parseYangResources(final List<String> yangResourceDirs,
290             final List<String> yangResources, final StatementParserMode statementParserMode) {
291         return parseYangResources(yangResourceDirs, yangResources, null, statementParserMode);
292     }
293
294     /**
295      * Creates a new effective schema context containing the specified YANG sources.
296      *
297      * @param yangResourceDirs relative paths to the directories containing YANG files to be parsed
298      * @param yangResources relative paths to the YANG files to be parsed
299      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
300      *                          models are resolved
301      * @param statementParserMode mode of statement parser
302      * @return effective schema context
303      */
304     public static SchemaContext parseYangResources(final List<String> yangResourceDirs,
305             final List<String> yangResources, final Set<QName> supportedFeatures,
306             final StatementParserMode statementParserMode) {
307         final List<File> allYangFiles = new ArrayList<>();
308         for (final String yangDir : yangResourceDirs) {
309             allYangFiles.addAll(getYangFiles(yangDir));
310         }
311
312         for (final String yangFile : yangResources) {
313             try {
314                 allYangFiles.add(new File(YangParserTestUtils.class.getResource(yangFile).toURI()));
315             } catch (URISyntaxException e) {
316                 throw new IllegalArgumentException("Invalid resource " + yangFile, e);
317             }
318         }
319
320         return parseYangFiles(supportedFeatures, statementParserMode, allYangFiles);
321     }
322
323     public static SchemaContext parseYangSources(final StatementParserMode parserMode,
324             final Set<QName> supportedFeatures, final YangTextSchemaSource... sources) {
325         return parseYangSources(supportedFeatures, parserMode, Arrays.asList(sources));
326     }
327
328     public static SchemaContext parseYangSources(final Set<QName> supportedFeatures,
329             final StatementParserMode parserMode, final Collection<? extends YangTextSchemaSource> sources) {
330         final Collection<YangStatementStreamSource> streams = new ArrayList<>(sources.size());
331         for (YangTextSchemaSource source : sources) {
332             try {
333                 streams.add(YangStatementStreamSource.create(source));
334             } catch (IOException e) {
335                 throw new IllegalArgumentException("Failed to read source " + source, e);
336             } catch (YangSyntaxErrorException e) {
337                 throw new IllegalArgumentException("Malformed source " + source, e);
338             }
339         }
340
341         return parseSources(supportedFeatures, parserMode, streams);
342     }
343
344     /**
345      * Creates a new effective schema context containing the specified YIN sources. Statement parser mode is set to
346      * default mode and all YANG features are supported.
347      *
348      * @param sources YIN sources to be parsed
349      * @return effective schema context
350      */
351     public static SchemaContext parseYinSources(final YinStatementStreamSource... sources) {
352         return parseYinSources(StatementParserMode.DEFAULT_MODE, sources);
353     }
354
355     /**
356      * Creates a new effective schema context containing the specified YIN sources. Statement parser mode is set to
357      * default mode.
358      *
359      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YIN
360      *                          models are resolved
361      * @param sources YIN sources to be parsed
362      *
363      * @return effective schema context
364      * @throws ReactorException if there is an error in one of the parsed YIN sources
365      */
366     public static SchemaContext parseYinSources(final Set<QName> supportedFeatures,
367             final YinStatementStreamSource... sources) throws ReactorException {
368         return parseSources(supportedFeatures, StatementParserMode.DEFAULT_MODE, sources);
369     }
370
371     /**
372      * Creates a new effective schema context containing the specified YIN sources. All YANG features are supported.
373      *
374      * @param statementParserMode mode of statement parser
375      * @param sources YIN sources to be parsed
376      * @return effective schema context
377      */
378     public static SchemaContext parseYinSources(final StatementParserMode statementParserMode,
379             final YinStatementStreamSource... sources) {
380         return parseSources(null, statementParserMode, sources);
381     }
382
383     /**
384      * Creates a new effective schema context containing the specified YANG sources.
385      *
386      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
387      *                          models are resolved
388      * @param parserMode mode of statement parser
389      * @param sources sources to be parsed
390      *
391      * @return effective schema context
392      */
393     public static SchemaContext parseSources(final Set<QName> supportedFeatures,
394             final StatementParserMode parserMode, final StatementStreamSource... sources) {
395         return parseSources(supportedFeatures, parserMode, Arrays.asList(sources));
396     }
397
398     /**
399      * Creates a new effective schema context containing the specified YANG sources.
400      *
401      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
402      *                          models are resolved
403      * @param statementParserMode mode of statement parser
404      * @param sources sources to be parsed
405      *
406      * @return effective schema context
407      */
408     public static SchemaContext parseSources(final Set<QName> supportedFeatures,
409             final StatementParserMode statementParserMode, final Collection<? extends StatementStreamSource> sources) {
410         final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(
411                 statementParserMode);
412         if (supportedFeatures != null) {
413             reactor.setSupportedFeatures(supportedFeatures);
414         }
415         reactor.addSources(sources);
416
417         try {
418             return reactor.buildEffective();
419         } catch (ReactorException e) {
420             throw new IllegalStateException(e);
421         }
422     }
423
424     private static Collection<File> getYangFiles(final String resourcePath) {
425         final URI directoryPath;
426         try {
427             directoryPath = YangParserTestUtils.class.getResource(resourcePath).toURI();
428         } catch (URISyntaxException e) {
429             throw new IllegalArgumentException("Failed to open resource directory " + resourcePath, e);
430         }
431         return Arrays.asList(new File(directoryPath).listFiles(YANG_FILE_FILTER));
432     }
433 }