d54afd64296a5d37d43d896d5eee8b594ec0459d
[ccsdk/features.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property.
6  * All rights reserved.
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
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
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=========================================================
20  *
21  */
22 package org.onap.ccsdk.features.sdnr.wt.dataprovider.data;
23
24 import java.io.File;
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
37 import javax.annotation.Nonnull;
38 import javax.annotation.Nullable;
39
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 public class YangFileProvider {
44
45         private static final Logger LOG = LoggerFactory.getLogger(YangFileProvider.class);
46
47         private static final FilenameFilter yangFilenameFilter = new FilenameFilter() {
48
49                 @Override
50                 public boolean accept(File dir, String name) {
51                         return name.toLowerCase().endsWith(".yang");
52                 }
53         };
54
55         private static final int BUFFER_SIZE = 1024;
56
57         private final Path mainSourcePath;
58         private final List<Path> additionalSources;
59
60         public YangFileProvider(String path) {
61                 this.mainSourcePath = new File(path).toPath();
62                 this.additionalSources = new ArrayList<>();
63         }
64
65         public boolean hasFileForModule(String module, String version) {
66                 return this.mainSourcePath.resolve(YangFilename.createFilename(module, version)).toFile().exists();
67         }
68
69         public boolean hasFileForModule(String module) {
70                 return this.findYangFiles(module).size() > 0;
71         }
72
73         private List<YangFilename> findYangFiles(String module) {
74                 List<YangFilename> list = new ArrayList<>();
75                 String[] files = this.mainSourcePath.toFile().list(yangFilenameFilter);
76                 YangFilename yangfile;
77                 for (String file : files) {
78                         files = this.mainSourcePath.toFile().list(yangFilenameFilter);
79                         for (String fn : files) {
80                                 try {
81                                         yangfile = new YangFilename(this.mainSourcePath.resolve(fn).toString());
82                                         if (yangfile.getModule().equals(module)) {
83                                                 list.add(yangfile);
84                                         }
85                                 } catch (ParseException e) {
86                                         LOG.warn("unable to handle yangfile {}: {}", file, e);
87                                 }
88                         }
89                 }
90                 for (Path addPath : this.additionalSources) {
91                         files = addPath.toFile().list(yangFilenameFilter);
92                         for (String file : files) {
93                                 try {
94                                         yangfile = new YangFilename(addPath.resolve(file).toString());
95                                         if (yangfile.getModule().equals(module)) {
96                                                 list.add(yangfile);
97                                         }
98                                 } catch (ParseException e) {
99                                         LOG.warn("unable to handle yangfile {}: {}", file, e);
100                                 }
101                         }
102                 }
103                 return list;
104         }
105
106         /**
107          * get yang file from source with specified version or least newer one if
108          * version is null then the latest one
109          * 
110          * @param module
111          * @param version
112          * @return
113          * @throws ParseException
114          */
115         private @Nullable YangFilename getYangFile(@Nonnull String module, @Nullable String version) throws ParseException {
116                 YangFilename f = null;
117                 List<YangFilename> list = this.findYangFiles(module);
118
119                 list.sort(SortByDateAscComparator.getInstance());
120
121                 // find specific version or nearest oldest
122                 if (version != null) {
123                         Date rev = YangFilename.parseRevision(version);
124                         for (YangFilename item : list) {
125                                 if (rev.equals(item.getRevision())) {
126                                         f = item;
127                                         break;
128                                 }
129                                 if (item.getRevision().after(rev)) {
130                                         f = item;
131                                         break;
132                                 }
133                         }
134                 }
135                 // get latest
136                 else {
137                         f = list.get(list.size() - 1);
138                 }
139                 return f;
140         }
141
142         /**
143          * write filestream directly to output stream easier for http handling
144          * 
145          * @param module
146          * @param version
147          * @param outputStream
148          * @return
149          * @throws IOException
150          * @throws ParseException
151          */
152         public int writeOutput(@Nonnull String module, @Nullable String version, @Nonnull OutputStream outputStream)
153                         throws IOException, ParseException {
154                 YangFilename fn = this.getYangFile(module, version);
155                 if(fn==null) {
156                         return 0;
157                 }
158                 byte[] buffer = new byte[BUFFER_SIZE];
159                 int bytesRead = -1;
160                 int sumlen = 0;
161                 InputStream inputStream = null ;
162                 try {
163                         inputStream= new FileInputStream(fn.getFilename());
164
165                 while ((bytesRead = inputStream.read(buffer)) != -1) {
166                         outputStream.write(buffer, 0, bytesRead);
167                         sumlen += bytesRead;
168                 }}
169                 catch(IOException e) {
170                         LOG.warn("problem sending {}: {}",fn.getFilename(),e);
171                 }
172                 finally {
173                         if(inputStream!=null) {
174                                 inputStream.close();            
175                         }
176                 }
177                 return sumlen;
178         }
179
180         private static class SortByDateAscComparator implements Comparator<YangFilename> {
181
182                 private static SortByDateAscComparator instance;
183
184                 @Override
185                 public int compare(YangFilename o1, YangFilename o2) {
186                         return o1.getRevision().compareTo(o2.getRevision());
187                 }
188
189                 public static Comparator<YangFilename> getInstance() {
190                         if (instance == null) {
191                                 instance = new SortByDateAscComparator();
192                         }
193                         return instance;
194                 }
195
196         }
197
198         public YangFilename getFileForModule(String module, String rev) throws ParseException {
199                 return this.getYangFile(module, rev);
200         }
201
202         public YangFilename getFileForModule(String module) throws ParseException {
203                 return this.getFileForModule(module, null);
204         }
205
206         public boolean hasFileOrNewerForModule(String module, String version) throws ParseException {
207                 return this.getYangFile(module, version) != null;
208         }
209
210 }