2 * ============LICENSE_START=======================================================
3 * ONAP : ccsdk features
4 * ================================================================================
5 * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.ccsdk.features.sdnr.wt.dataprovider.http.yangschema;
25 import java.io.FileInputStream;
26 import java.io.FilenameFilter;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.OutputStream;
30 import java.nio.file.Path;
31 import java.text.ParseException;
32 import java.util.ArrayList;
33 import java.util.Comparator;
34 import java.util.Date;
35 import java.util.List;
36 import javax.annotation.Nonnull;
37 import javax.annotation.Nullable;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 public class YangFileProvider {
43 private static final Logger LOG = LoggerFactory.getLogger(YangFileProvider.class);
45 private static final FilenameFilter yangFilenameFilter = new FilenameFilter() {
48 public boolean accept(File dir, String name) {
49 return name.toLowerCase().endsWith(".yang");
53 private static final int BUFFER_SIZE = 1024;
55 private final Path mainSourcePath;
56 private final List<Path> additionalSources;
58 public YangFileProvider(String path) {
59 this.mainSourcePath = new File(path).toPath();
60 this.additionalSources = new ArrayList<>();
63 public boolean hasFileForModule(String module, String version) {
64 return this.mainSourcePath.resolve(YangFilename.createFilename(module, version)).toFile().exists();
67 public boolean hasFileForModule(String module) {
68 return this.findYangFiles(module).size() > 0;
71 private List<YangFilename> findYangFiles(String module) {
72 LOG.debug("try to find yang files for {}", module);
73 List<YangFilename> list = new ArrayList<>();
74 String[] files = this.mainSourcePath.toFile().list(yangFilenameFilter);
75 YangFilename yangfile;
76 for (String fn : files) {
78 yangfile = new YangFilename(this.mainSourcePath.resolve(fn).toString());
79 if (yangfile.getModule().equals(module)) {
82 } catch (ParseException e) {
83 LOG.warn("unable to handle yangfile {}: {}", fn, e);
87 for (Path addPath : this.additionalSources) {
88 files = addPath.toFile().list(yangFilenameFilter);
89 for (String file : files) {
91 yangfile = new YangFilename(addPath.resolve(file).toString());
92 if (yangfile.getModule().equals(module)) {
95 } catch (ParseException e) {
96 LOG.warn("unable to handle yangfile {}: {}", file, e);
104 * get yang file from source with specified version or least newer one if version is null then the latest one
109 * @throws ParseException
111 private @Nullable YangFilename getYangFile(@Nonnull String module, @Nullable String version) throws ParseException {
112 YangFilename f = null;
113 List<YangFilename> list = this.findYangFiles(module);
115 list.sort(SortByDateAscComparator.getInstance());
117 // find specific version or nearest oldest
118 if (version != null) {
119 Date rev = YangFilename.parseRevision(version);
120 for (YangFilename item : list) {
121 if (rev.equals(item.getRevision())) {
125 if (item.getRevision().after(rev)) {
133 f = list.get(list.size() - 1);
139 * write filestream directly to output stream easier for http handling
143 * @param outputStream
145 * @throws IOException
146 * @throws ParseException
148 public int writeOutput(@Nonnull String module, @Nullable String version, @Nonnull OutputStream outputStream)
149 throws IOException, ParseException {
150 YangFilename fn = this.getYangFile(module, version);
154 byte[] buffer = new byte[BUFFER_SIZE];
157 InputStream inputStream = null;
159 inputStream = new FileInputStream(fn.getFilename());
161 while ((bytesRead = inputStream.read(buffer)) != -1) {
162 outputStream.write(buffer, 0, bytesRead);
165 } catch (IOException e) {
166 LOG.warn("problem sending {}: {}", fn.getFilename(), e);
168 if (inputStream != null) {
175 private static class SortByDateAscComparator implements Comparator<YangFilename> {
177 private static SortByDateAscComparator instance;
180 public int compare(YangFilename o1, YangFilename o2) {
181 return o1.getRevision().compareTo(o2.getRevision());
184 public static Comparator<YangFilename> getInstance() {
185 if (instance == null) {
186 instance = new SortByDateAscComparator();
193 public YangFilename getFileForModule(String module, String rev) throws ParseException {
194 return this.getYangFile(module, rev);
197 public YangFilename getFileForModule(String module) throws ParseException {
198 return this.getFileForModule(module, null);
201 public boolean hasFileOrNewerForModule(String module, String version) throws ParseException {
202 return this.getYangFile(module, version) != null;