blob: ccb43e35f23c3833b368978d281ab4ff8f1d9a41 [file] [log] [blame]
Gaurav Agrawal8a5af142016-06-15 13:58:01 +05301/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.yangutils.plugin.manager;
18
19import java.io.File;
20import java.io.FileInputStream;
21import java.io.FileOutputStream;
22import java.io.IOException;
23import java.io.InputStream;
24import java.io.ObjectInputStream;
25import java.io.ObjectOutputStream;
26import java.nio.file.Files;
27import java.nio.file.StandardCopyOption;
28import java.util.ArrayList;
29import java.util.Enumeration;
30import java.util.Iterator;
31import java.util.List;
32import java.util.Set;
33import java.util.jar.JarEntry;
34import java.util.jar.JarFile;
Bharat saraswal246a70c2016-06-16 13:24:06 +053035
Gaurav Agrawal8a5af142016-06-15 13:58:01 +053036import org.apache.maven.artifact.repository.ArtifactRepository;
37import org.apache.maven.model.Dependency;
38import org.apache.maven.model.Resource;
39import org.apache.maven.project.MavenProject;
40import org.onosproject.yangutils.datamodel.YangNode;
41import org.slf4j.Logger;
42import org.sonatype.plexus.build.incremental.BuildContext;
43
44import static org.onosproject.yangutils.utils.UtilConstants.HYPHEN;
45import static org.onosproject.yangutils.utils.UtilConstants.JAR;
46import static org.onosproject.yangutils.utils.UtilConstants.PERIOD;
47import static org.onosproject.yangutils.utils.UtilConstants.SLASH;
48import static org.onosproject.yangutils.utils.UtilConstants.TEMP;
49import static org.onosproject.yangutils.utils.UtilConstants.YANG_RESOURCES;
50import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCamelCase;
51import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getPackageDirPathFromJavaJPackage;
52import static org.slf4j.LoggerFactory.getLogger;
53
54/**
55 * Represents YANG plugin utilities.
56 */
57public final class YangPluginUtils {
58
59 private static final Logger log = getLogger(YangPluginUtils.class);
60
61 private static final String TARGET_RESOURCE_PATH = SLASH + TEMP + SLASH + YANG_RESOURCES + SLASH;
62
63 private static final String SERIALIZED_FILE_EXTENSION = ".ser";
64
65 private YangPluginUtils() {
66 }
67
68 /**
69 * Adds generated source directory to the compilation root.
70 *
71 * @param source directory
72 * @param project current maven project
73 * @param context current build context
74 */
75 public static void addToCompilationRoot(String source, MavenProject project, BuildContext context) {
76 project.addCompileSourceRoot(source);
77 context.refresh(project.getBasedir());
78 log.info("Source directory added to compilation root: " + source);
79 }
80
81 /**
82 * Copies YANG files to the current project's output directory.
83 *
84 * @param yangFileInfo list of YANG files
85 * @param outputDir project's output directory
86 * @param project maven project
87 * @throws IOException when fails to copy files to destination resource directory
88 */
89 public static void copyYangFilesToTarget(Set<YangFileInfo> yangFileInfo, String outputDir, MavenProject project)
90 throws IOException {
91
92 List<File> files = getListOfFile(yangFileInfo);
93
94 String path = outputDir + TARGET_RESOURCE_PATH;
95 File targetDir = new File(path);
96 targetDir.mkdirs();
97
98 for (File file : files) {
99 Files.copy(file.toPath(),
100 new File(path + file.getName()).toPath(),
101 StandardCopyOption.REPLACE_EXISTING);
102 }
103 addToProjectResource(outputDir + SLASH + TEMP + SLASH, project);
104 }
105
106 /**
107 * Provides a list of files from list of strings.
108 *
109 * @param yangFileInfo set of yang file information
110 * @return list of files
111 */
112 private static List<File> getListOfFile(Set<YangFileInfo> yangFileInfo) {
113 List<File> files = new ArrayList<>();
114 Iterator<YangFileInfo> yangFileIterator = yangFileInfo.iterator();
115 while (yangFileIterator.hasNext()) {
116 YangFileInfo yangFile = yangFileIterator.next();
117 if (yangFile.isForTranslator()) {
118 files.add(new File(yangFile.getYangFileName()));
119 }
120 }
121 return files;
122 }
123
124 /**
125 * Serializes data-model.
126 *
127 * @param directory base directory for serialized files
128 * @param fileInfoSet YANG file info set
129 * @param project maven project
130 * @param operation true if need to add to resource
131 * @throws IOException when fails to do IO operations
132 */
133 public static void serializeDataModel(String directory, Set<YangFileInfo> fileInfoSet,
134 MavenProject project, boolean operation) throws IOException {
135
136 String serFileDirPath = directory + TARGET_RESOURCE_PATH;
137 File dir = new File(serFileDirPath);
138 dir.mkdirs();
139
140 if (operation) {
141 addToProjectResource(directory + SLASH + TEMP + SLASH, project);
142 }
143
144 for (YangFileInfo fileInfo : fileInfoSet) {
145
146 String serFileName = serFileDirPath + getCamelCase(fileInfo.getRootNode().getName(), null)
147 + SERIALIZED_FILE_EXTENSION;
148 fileInfo.setSerializedFile(serFileName);
149 FileOutputStream fileOutputStream = new FileOutputStream(serFileName);
150 ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
151 objectOutputStream.writeObject(fileInfo.getRootNode());
152 objectOutputStream.close();
153 fileOutputStream.close();
154 }
155 }
156
157 /**
158 * Returns de-serializes YANG data-model nodes.
159 *
160 * @param serailizedfileInfoSet YANG file info set
161 * @return de-serializes YANG data-model nodes
162 * @throws IOException when fails do IO operations
163 */
164 public static List<YangNode> deSerializeDataModel(List<String> serailizedfileInfoSet) throws IOException {
165
166 List<YangNode> nodes = new ArrayList<>();
167 for (String fileInfo : serailizedfileInfoSet) {
168 YangNode node = null;
169 try {
170 FileInputStream fileInputStream = new FileInputStream(fileInfo);
171 ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
172 node = (YangNode) objectInputStream.readObject();
173 nodes.add(node);
174 objectInputStream.close();
175 fileInputStream.close();
176 } catch (IOException | ClassNotFoundException e) {
177 throw new IOException(fileInfo + " not found.");
178 }
179 }
180 return nodes;
181 }
182
183 /**
184 * Returns list of jar path.
185 *
186 * @param project maven project
187 * @param localRepository local repository
188 * @param remoteRepos remote repository
189 * @return list of jar paths
190 */
191 private static List<String> resolveDependecyJarPath(MavenProject project, ArtifactRepository localRepository,
192 List<ArtifactRepository> remoteRepos) {
193
194 StringBuilder path = new StringBuilder();
195 List<String> jarPaths = new ArrayList<>();
Bharat saraswal246a70c2016-06-16 13:24:06 +0530196 for (Object obj : project.getDependencies()) {
Gaurav Agrawal8a5af142016-06-15 13:58:01 +0530197
Bharat saraswal246a70c2016-06-16 13:24:06 +0530198 Dependency dependency = (Dependency) obj;
Gaurav Agrawal8a5af142016-06-15 13:58:01 +0530199 path.append(localRepository.getBasedir());
200 path.append(SLASH);
201 path.append(getPackageDirPathFromJavaJPackage(dependency.getGroupId()));
202 path.append(SLASH);
203 path.append(dependency.getArtifactId());
204 path.append(SLASH);
205 path.append(dependency.getVersion());
206 path.append(SLASH);
207 path.append(dependency.getArtifactId() + HYPHEN + dependency.getVersion() + PERIOD + JAR);
208 File jarFile = new File(path.toString());
209 if (jarFile.exists()) {
210 jarPaths.add(path.toString());
211 }
212 path.delete(0, path.length());
213 }
214
215 for (ArtifactRepository repo : remoteRepos) {
216 // TODO: add resolver for remote repo.
217 }
218 return jarPaths;
219 }
220
221 /**
222 * Resolves inter jar dependencies.
223 *
224 * @param project current maven project
225 * @param localRepository local maven repository
226 * @param remoteRepos list of remote repository
227 * @param directory directory for serialized files
228 * @return list of resolved datamodel nodes
229 * @throws IOException when fails to do IO operations
230 */
231 public static List<YangNode> resolveInterJarDependencies(MavenProject project, ArtifactRepository localRepository,
232 List<ArtifactRepository> remoteRepos, String directory)
233 throws IOException {
234
235 List<String> dependeciesJarPaths = resolveDependecyJarPath(project, localRepository, remoteRepos);
236 List<YangNode> resolvedDataModelNodes = new ArrayList<>();
237 for (String dependecy : dependeciesJarPaths) {
238 resolvedDataModelNodes.addAll(deSerializeDataModel(parseJarFile(dependecy, directory)));
239 }
240 return resolvedDataModelNodes;
241 }
242
243 /**
244 * Parses jar file and returns list of serialized file names.
245 *
246 * @param jarFile jar file to be parsed
247 * @param directory directory for keeping the searized files
248 * @return list of serialized files
249 * @throws IOException when fails to do IO operations
250 */
251 public static List<String> parseJarFile(String jarFile, String directory)
252 throws IOException {
253
254 List<String> serailizedFiles = new ArrayList<>();
255 JarFile jar = new JarFile(jarFile);
256 Enumeration<?> enumEntries = jar.entries();
257
258 File serializedFileDir = new File(directory);
259 serializedFileDir.mkdirs();
260 while (enumEntries.hasMoreElements()) {
261 JarEntry file = (JarEntry) enumEntries.nextElement();
262 if (file.getName().endsWith(SERIALIZED_FILE_EXTENSION)) {
263 if (file.getName().contains(SLASH)) {
264 String[] strArray = file.getName().split(SLASH);
265 String tempPath = "";
266 for (int i = 0; i < strArray.length - 1; i++) {
267 tempPath = SLASH + tempPath + SLASH + strArray[i];
268 }
269 File dir = new File(directory + tempPath);
270 dir.mkdirs();
271 }
272 File serailizedFile = new File(directory + SLASH + file.getName());
273 if (file.isDirectory()) {
274 serailizedFile.mkdirs();
275 continue;
276 }
277 InputStream inputStream = jar.getInputStream(file);
278
279 FileOutputStream fileOutputStream = new FileOutputStream(serailizedFile);
280 while (inputStream.available() > 0) {
281 fileOutputStream.write(inputStream.read());
282 }
283 fileOutputStream.close();
284 inputStream.close();
285 serailizedFiles.add(serailizedFile.toString());
286 }
287 }
288 jar.close();
289 return serailizedFiles;
290 }
291
292 /* Adds directory to resources of project */
293 private static void addToProjectResource(String dir, MavenProject project) {
294 Resource rsc = new Resource();
295 rsc.setDirectory(dir);
296 project.addResource(rsc);
297 }
298}