Remove yang-maven-plugin version
[ccsdk/features.git] / sdnr / wt / devicemanager-o-ran-sc / o-ran / ru-fh / provider / src / test / java / org / onap / ccsdk / features / sdnr / wt / devicemanager / oran / impl / dom / 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 package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.dom;
9
10 import com.google.common.annotations.Beta;
11 import java.io.File;
12 import java.io.FileFilter;
13 import java.io.IOException;
14 import java.net.URI;
15 import java.net.URISyntaxException;
16 import java.util.ArrayList;
17 import java.util.Arrays;
18 import java.util.Collection;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.Locale;
22 import java.util.ServiceLoader;
23 import java.util.Set;
24 import java.util.stream.Collectors;
25 import org.eclipse.jdt.annotation.NonNull;
26 import org.opendaylight.yangtools.yang.common.QName;
27 import org.opendaylight.yangtools.yang.common.YangConstants;
28 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
29 import org.opendaylight.yangtools.yang.parser.api.YangParser;
30 import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
31 import org.opendaylight.yangtools.yang.parser.api.YangParserException;
32 import org.opendaylight.yangtools.yang.parser.api.YangParserFactory;
33 import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException;
34 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
35 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
36 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
37
38 /**
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.
41  */
42 @Beta
43 public final class YangParserTestUtils {
44
45     private static final FileFilter YANG_FILE_FILTER = file -> {
46         // Locale keeps SpotBugs happy. It should not matter that much anyway.
47         final String name = file.getName().toLowerCase(Locale.ENGLISH);
48         return name.endsWith(YangConstants.RFC6020_YANG_FILE_EXTENSION) && file.isFile();
49     };
50
51     private static final @NonNull YangParserFactory PARSER_FACTORY;
52
53     static {
54         final Iterator<@NonNull YangParserFactory> it = ServiceLoader.load(YangParserFactory.class).iterator();
55         if (!it.hasNext()) {
56             throw new IllegalStateException("No YangParserFactory found");
57         }
58         PARSER_FACTORY = it.next();
59     }
60
61     private YangParserTestUtils() {
62         // Hidden on purpose
63     }
64
65     /**
66      * Creates a new effective schema context containing the specified YANG source. Statement parser mode is set to
67      * default mode and all YANG features are supported.
68      *
69      * @param resource relative path to the YANG file to be parsed
70      *
71      * @return effective schema context
72      */
73     public static EffectiveModelContext parseYangResource(final String resource) {
74         return parseYangResource(resource, YangParserConfiguration.DEFAULT);
75     }
76
77     /**
78      * Creates a new effective schema context containing the specified YANG source. All YANG features are supported.
79      *
80      * @param resource relative path to the YANG file to be parsed
81      * @param parserMode mode of statement parser
82      * @return effective schema context
83      */
84     public static EffectiveModelContext parseYangResource(final String resource, final YangParserConfiguration config) {
85         return parseYangResource(resource, config, null);
86     }
87
88     /**
89      * Creates a new effective schema context containing the specified YANG source. Statement parser mode is set to
90      * default mode.
91      *
92      * @param resource relative path to the YANG file to be parsed
93      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
94      *                          model are resolved
95      * @return effective schema context
96      */
97     public static EffectiveModelContext parseYangResource(final String resource, final Set<QName> supportedFeatures) {
98         return parseYangResource(resource, YangParserConfiguration.DEFAULT, supportedFeatures);
99     }
100
101     /**
102      * Creates a new effective schema context containing the specified YANG source.
103      *
104      * @param resource relative path to the YANG file to be parsed
105      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
106      *                          model are resolved
107      * @param parserMode mode of statement parser
108      * @return effective schema context
109      */
110     public static EffectiveModelContext parseYangResource(final String resource, final YangParserConfiguration config,
111             final Set<QName> supportedFeatures) {
112         final YangTextSchemaSource source = YangTextSchemaSource.forResource(YangParserTestUtils.class, resource);
113         return parseYangSources(config, supportedFeatures, source);
114     }
115
116     /**
117      * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
118      * default mode and all YANG features are supported.
119      *
120      * @param files YANG files to be parsed
121      * @return effective schema context
122      */
123     public static EffectiveModelContext parseYangFiles(final File... files) {
124         return parseYangFiles(Arrays.asList(files));
125     }
126
127     /**
128      * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
129      * default mode and all YANG features are supported.
130      *
131      * @param files collection of YANG files to be parsed
132      * @return effective schema context
133      */
134     public static EffectiveModelContext parseYangFiles(final Collection<File> files) {
135         return parseYangFiles(YangParserConfiguration.DEFAULT, files);
136     }
137
138     /**
139      * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
140      * default mode.
141      *
142      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
143      *                          models are resolved
144      * @param files YANG files to be parsed
145      * @return effective schema context
146      */
147     public static EffectiveModelContext parseYangFiles(final Set<QName> supportedFeatures, final File... files) {
148         return parseYangFiles(supportedFeatures, Arrays.asList(files));
149     }
150
151     public static EffectiveModelContext parseYangFiles(final Set<QName> supportedFeatures,
152             final Collection<File> files) {
153         return parseYangFiles(supportedFeatures, YangParserConfiguration.DEFAULT, files);
154     }
155
156     /**
157      * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
158      *
159      * @param parserMode mode of statement parser
160      * @param files YANG files to be parsed
161      * @return effective schema context
162      */
163     public static EffectiveModelContext parseYangFiles(final YangParserConfiguration config, final File... files) {
164         return parseYangFiles(config, Arrays.asList(files));
165     }
166
167     /**
168      * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
169      *
170      * @param parserMode mode of statement parser
171      * @param files collection of YANG files to be parsed
172      * @return effective schema context
173      */
174     public static EffectiveModelContext parseYangFiles(final YangParserConfiguration config,
175             final Collection<File> files) {
176         return parseYangFiles(null, config, files);
177     }
178
179     /**
180      * Creates a new effective schema context containing the specified YANG sources.
181      *
182      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
183      *                          models are resolved
184      * @param parserMode mode of statement parser
185      * @param files YANG files to be parsed
186      * @return effective schema context
187      */
188     public static EffectiveModelContext parseYangFiles(final Set<QName> supportedFeatures,
189                 final YangParserConfiguration config, final File... files) {
190         return parseYangFiles(supportedFeatures, config, Arrays.asList(files));
191     }
192
193     /**
194      * Creates a new effective schema context containing the specified YANG sources.
195      *
196      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
197      *                          models are resolved
198      * @param parserMode mode of statement parser
199      * @param files YANG files to be parsed
200      * @return effective schema context
201      */
202     public static EffectiveModelContext parseYangFiles(final Set<QName> supportedFeatures,
203                 final YangParserConfiguration config, final Collection<File> files) {
204         return parseSources(config, supportedFeatures,
205             files.stream().map(YangTextSchemaSource::forFile).collect(Collectors.toList()));
206     }
207
208     /**
209      * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
210      * default mode and all YANG features are supported.
211      *
212      * @param resourcePath relative path to the directory with YANG files to be parsed
213      * @return effective schema context
214      */
215     public static EffectiveModelContext parseYangResourceDirectory(final String resourcePath) {
216         return parseYangResourceDirectory(resourcePath, YangParserConfiguration.DEFAULT);
217     }
218
219     /**
220      * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
221      *
222      * @param resourcePath relative path to the directory with YANG files to be parsed
223      * @param parserMode mode of statement parser
224      * @return effective schema context
225      */
226     public static EffectiveModelContext parseYangResourceDirectory(final String resourcePath,
227                 final YangParserConfiguration config) {
228         return parseYangResourceDirectory(resourcePath, null, config);
229     }
230
231     /**
232      * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
233      * default mode.
234      *
235      * @param resourcePath relative path to the directory with YANG files to be parsed
236      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
237      *                          models are resolved
238      * @return effective schema context
239      */
240     public static EffectiveModelContext parseYangResourceDirectory(final String resourcePath,
241             final Set<QName> supportedFeatures) {
242         return parseYangResourceDirectory(resourcePath, supportedFeatures, YangParserConfiguration.DEFAULT);
243     }
244
245     /**
246      * Creates a new effective schema context containing the specified YANG sources.
247      *
248      * @param resourcePath relative path to the directory with YANG files to be parsed
249      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
250      *                          models are resolved
251      * @param parserMode mode of statement parser
252      * @return effective schema context
253      */
254     @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Wrong inferent on listFiles")
255     public static EffectiveModelContext parseYangResourceDirectory(final String resourcePath,
256             final Set<QName> supportedFeatures, final YangParserConfiguration config) {
257         final URI directoryPath;
258         try {
259             directoryPath = YangParserTestUtils.class.getResource(resourcePath).toURI();
260         } catch (URISyntaxException e) {
261             throw new IllegalArgumentException("Failed to open resource " + resourcePath, e);
262         }
263         return parseYangFiles(supportedFeatures, config, new File(directoryPath).listFiles(YANG_FILE_FILTER));
264     }
265
266     /**
267      * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
268      * default mode and all YANG features are supported.
269      *
270      * @param clazz Resource lookup base
271      * @param resources Resource names to be looked up
272      * @return effective schema context
273      */
274     public static EffectiveModelContext parseYangResources(final Class<?> clazz, final String... resources) {
275         return parseYangResources(clazz, Arrays.asList(resources));
276     }
277
278     public static EffectiveModelContext parseYangResources(final Class<?> clazz, final Collection<String> resources) {
279         final List<YangTextSchemaSource> sources = new ArrayList<>(resources.size());
280         for (final String r : resources) {
281             sources.add(YangTextSchemaSource.forResource(clazz, r));
282         }
283         return parseSources(YangParserConfiguration.DEFAULT, null, sources);
284     }
285
286     /**
287      * Creates a new effective schema context containing the specified YANG sources. Statement parser mode is set to
288      * default mode.
289      *
290      * @param yangDirs relative paths to the directories containing YANG files to be parsed
291      * @param yangFiles relative paths to the YANG files to be parsed
292      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
293      *                          models are resolved
294      * @return effective schema context
295      */
296     public static EffectiveModelContext parseYangResources(final List<String> yangDirs, final List<String> yangFiles,
297             final Set<QName> supportedFeatures) {
298         return parseYangResources(yangDirs, yangFiles, supportedFeatures, YangParserConfiguration.DEFAULT);
299     }
300
301     /**
302      * Creates a new effective schema context containing the specified YANG sources. All YANG features are supported.
303      *
304      * @param yangResourceDirs relative paths to the directories containing YANG files to be parsed
305      * @param yangResources relative paths to the YANG files to be parsed
306      * @param statementParserMode mode of statement parser
307      * @return effective schema context
308      */
309     public static EffectiveModelContext parseYangResources(final List<String> yangResourceDirs,
310             final List<String> yangResources, final YangParserConfiguration config) {
311         return parseYangResources(yangResourceDirs, yangResources, null, config);
312     }
313
314     /**
315      * Creates a new effective schema context containing the specified YANG sources.
316      *
317      * @param yangResourceDirs relative paths to the directories containing YANG files to be parsed
318      * @param yangResources relative paths to the YANG files to be parsed
319      * @param supportedFeatures set of supported features based on which all if-feature statements in the parsed YANG
320      *                          models are resolved
321      * @param statementParserMode mode of statement parser
322      * @return effective schema context
323      */
324     public static EffectiveModelContext parseYangResources(final List<String> yangResourceDirs,
325             final List<String> yangResources, final Set<QName> supportedFeatures,
326             final YangParserConfiguration config) {
327         final List<File> allYangFiles = new ArrayList<>();
328         for (final String yangDir : yangResourceDirs) {
329             allYangFiles.addAll(getYangFiles(yangDir));
330         }
331
332         for (final String yangFile : yangResources) {
333             try {
334                 allYangFiles.add(new File(YangParserTestUtils.class.getResource(yangFile).toURI()));
335             } catch (URISyntaxException e) {
336                 throw new IllegalArgumentException("Invalid resource " + yangFile, e);
337             }
338         }
339
340         return parseYangFiles(supportedFeatures, config, allYangFiles);
341     }
342
343     public static EffectiveModelContext parseYangSources(final YangParserConfiguration config,
344             final Set<QName> supportedFeatures, final YangTextSchemaSource... sources) {
345         return parseSources(config, supportedFeatures, Arrays.asList(sources));
346     }
347
348     public static EffectiveModelContext parseSources(final YangParserConfiguration config,
349             final Set<QName> supportedFeatures, final Collection<? extends SchemaSourceRepresentation> sources) {
350         final YangParser parser = PARSER_FACTORY.createParser(config);
351         if (supportedFeatures != null) {
352             parser.setSupportedFeatures(supportedFeatures);
353         }
354
355         try {
356             parser.addSources(sources);
357         } catch (YangSyntaxErrorException e) {
358             throw new IllegalArgumentException("Malformed source", e);
359         } catch (IOException e) {
360             throw new IllegalArgumentException("Failed to read a source", e);
361         }
362
363         try {
364             return parser.buildEffectiveModel();
365         } catch (YangParserException e) {
366             throw new IllegalStateException("Failed to assemble SchemaContext", e);
367         }
368     }
369
370     @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Wrong inferent on listFiles")
371     private static Collection<File> getYangFiles(final String resourcePath) {
372         final URI directoryPath;
373         try {
374             directoryPath = YangParserTestUtils.class.getResource(resourcePath).toURI();
375         } catch (URISyntaxException e) {
376             throw new IllegalArgumentException("Failed to open resource directory " + resourcePath, e);
377         }
378         return Arrays.asList(new File(directoryPath).listFiles(YANG_FILE_FILTER));
379     }
380 }