blob: 40c5b0eee9ce1381bd2adc02b5b28e31b326ee8e [file] [log] [blame]
Bharat saraswal97459962016-02-20 21:57:16 +05301/*
2 * Copyright 2016 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.translator.tojava;
18
19import java.io.File;
20import java.io.IOException;
21import java.util.LinkedList;
22import java.util.List;
23import java.util.SortedSet;
24import java.util.TreeSet;
25
26import org.onosproject.yangutils.datamodel.YangType;
Vinod Kumar S08710982016-03-03 19:55:30 +053027import org.onosproject.yangutils.datamodel.YangTypeDef;
Bharat saraswal97459962016-02-20 21:57:16 +053028import org.onosproject.yangutils.translator.CachedFileHandle;
29import org.onosproject.yangutils.translator.GeneratedFileType;
Bharat saraswalc46ee2a2016-02-25 02:26:43 +053030import org.onosproject.yangutils.translator.tojava.utils.AttributesJavaDataType;
Bharat saraswalc46ee2a2016-02-25 02:26:43 +053031import org.onosproject.yangutils.translator.tojava.utils.JavaFileGenerator;
Bharat saraswal97459962016-02-20 21:57:16 +053032import org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax;
Bharat saraswal97459962016-02-20 21:57:16 +053033import org.onosproject.yangutils.utils.UtilConstants;
Bharat saraswal97459962016-02-20 21:57:16 +053034
35/**
36 * Maintain the information about the java file to be generated.
37 */
38public class CachedJavaFileHandle implements CachedFileHandle {
39
Bharat saraswal97459962016-02-20 21:57:16 +053040 private static final int MAX_CACHABLE_ATTR = 64;
41 private static final String JAVA_FILE_EXTENSION = ".java";
42 private static final String TEMP_FILE_EXTENSION = ".tmp";
43
44 /**
45 * The type(s) of java source file(s) to be generated when the cached file
46 * handle is closed.
47 */
Vinod Kumar S08710982016-03-03 19:55:30 +053048 private int genFileTypes;
Bharat saraswal5e3c45c2016-02-22 22:15:21 +053049
50 /**
Bharat saraswal97459962016-02-20 21:57:16 +053051 * Name of the object in YANG file.
52 */
53 private String yangName;
54
55 /**
56 * Sorted set of import info, to be used to maintain the set of classes to
57 * be imported in the generated class.
58 */
Vinod Kumar S08710982016-03-03 19:55:30 +053059 private SortedSet<ImportInfo> importSet;
Bharat saraswal97459962016-02-20 21:57:16 +053060
61 /**
62 * Cached list of attribute info.
63 */
64 private List<AttributeInfo> attributeList;
65
66 /**
Bharat saraswalc46ee2a2016-02-25 02:26:43 +053067 * File generation directory path.
68 */
Vinod Kumar S08710982016-03-03 19:55:30 +053069 private String relativeFilePath;
70
71 /**
72 * Typedef Info.
73 */
74 private YangTypeDef typedefInfo;
Bharat saraswalc46ee2a2016-02-25 02:26:43 +053075
76 /**
Bharat saraswal97459962016-02-20 21:57:16 +053077 * Prevent invoking default constructor.
78 */
Bharat saraswalc46ee2a2016-02-25 02:26:43 +053079 public CachedJavaFileHandle() {
Bharat saraswal97459962016-02-20 21:57:16 +053080 setCachedAttributeList(new LinkedList<AttributeInfo>());
81 }
82
83 /**
84 * Create a cached file handle which takes care of adding attributes to the
85 * generated java file.
86 *
Vinod Kumar S08710982016-03-03 19:55:30 +053087 * @param pcg package in which class/interface need to be generated
88 * @param yangName name of the attribute in YANG file
89 * @param types the types of files that needs to be generated
90 * @throws IOException file IO exception
Bharat saraswal97459962016-02-20 21:57:16 +053091 */
Vinod Kumar S08710982016-03-03 19:55:30 +053092 public CachedJavaFileHandle(String pcg, String yangName, int types) throws IOException {
93 setCachedAttributeList(new LinkedList<AttributeInfo>());
94 setImportSet(new TreeSet<ImportInfo>());
95 setRelativeFilePath(pcg.replace(".", "/"));
Bharat saraswalc46ee2a2016-02-25 02:26:43 +053096 setGeneratedFileTypes(types);
Bharat saraswalc46ee2a2016-02-25 02:26:43 +053097 setYangName(yangName);
Bharat saraswal97459962016-02-20 21:57:16 +053098 }
99
100 /**
101 * Get the types of files being generated corresponding to the YANG
102 * definition.
103 *
104 * @return the types of files being generated corresponding to the YANG
Vinod Kumar S08710982016-03-03 19:55:30 +0530105 * definition
Bharat saraswal97459962016-02-20 21:57:16 +0530106 */
Vinod Kumar S08710982016-03-03 19:55:30 +0530107 public int getGeneratedFileTypes() {
Bharat saraswal97459962016-02-20 21:57:16 +0530108 return genFileTypes;
109 }
110
111 /**
112 * Set the types of files being generated corresponding to the YANG
113 * definition.
114 *
115 * @param fileTypes the types of files being generated corresponding to the
Vinod Kumar S08710982016-03-03 19:55:30 +0530116 * YANG definition
Bharat saraswal97459962016-02-20 21:57:16 +0530117 */
Vinod Kumar S08710982016-03-03 19:55:30 +0530118 public void setGeneratedFileTypes(int fileTypes) {
Bharat saraswal97459962016-02-20 21:57:16 +0530119 genFileTypes = fileTypes;
120 }
121
122 /**
123 * Get the corresponding name defined in YANG.
124 *
Vinod Kumar S08710982016-03-03 19:55:30 +0530125 * @return the corresponding name defined in YANG
Bharat saraswal97459962016-02-20 21:57:16 +0530126 */
127 public String getYangName() {
128 return yangName;
129 }
130
131 /**
132 * Set the corresponding name defined in YANG.
133 *
Vinod Kumar S08710982016-03-03 19:55:30 +0530134 * @param yangName the corresponding name defined in YANG
Bharat saraswal97459962016-02-20 21:57:16 +0530135 */
136 public void setYangName(String yangName) {
137 this.yangName = yangName;
138 }
139
140 /**
Bharat saraswal97459962016-02-20 21:57:16 +0530141 * Get the set containing the imported class/interface info.
142 *
Vinod Kumar S08710982016-03-03 19:55:30 +0530143 * @return the set containing the imported class/interface info
Bharat saraswal97459962016-02-20 21:57:16 +0530144 */
Vinod Kumar S08710982016-03-03 19:55:30 +0530145 public SortedSet<ImportInfo> getImportSet() {
Bharat saraswal97459962016-02-20 21:57:16 +0530146 return importSet;
147 }
148
149 /**
150 * Assign the set containing the imported class/interface info.
151 *
Vinod Kumar S08710982016-03-03 19:55:30 +0530152 * @param importSet the set containing the imported class/interface info
Bharat saraswal97459962016-02-20 21:57:16 +0530153 */
Vinod Kumar S08710982016-03-03 19:55:30 +0530154 private void setImportSet(SortedSet<ImportInfo> importSet) {
Bharat saraswal97459962016-02-20 21:57:16 +0530155 this.importSet = importSet;
156 }
157
158 /**
159 * Add an imported class/interface info is it is not already part of the
160 * set. If already part of the set, return false, else add to set and return
161 * true.
162 *
Vinod Kumar S08710982016-03-03 19:55:30 +0530163 * @param importInfo class/interface info being imported
Bharat saraswal97459962016-02-20 21:57:16 +0530164 * @return status of new addition of class/interface to the import set
165 */
166 public boolean addImportInfo(ImportInfo importInfo) {
Vinod Kumar S08710982016-03-03 19:55:30 +0530167 return getImportSet().add(importInfo);
Bharat saraswal97459962016-02-20 21:57:16 +0530168 }
169
170 /**
171 * Get the list of cached attribute list.
172 *
Vinod Kumar S08710982016-03-03 19:55:30 +0530173 * @return the set containing the imported class/interface info
Bharat saraswal97459962016-02-20 21:57:16 +0530174 */
175 public List<AttributeInfo> getCachedAttributeList() {
176 return attributeList;
177 }
178
179 /**
180 * Set the cached attribute list.
181 *
Vinod Kumar S08710982016-03-03 19:55:30 +0530182 * @param attrList attribute list
Bharat saraswal97459962016-02-20 21:57:16 +0530183 */
184 private void setCachedAttributeList(List<AttributeInfo> attrList) {
185 attributeList = attrList;
186 }
187
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530188 /**
Vinod Kumar S08710982016-03-03 19:55:30 +0530189 * Set the package relative path.
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530190 *
Vinod Kumar S08710982016-03-03 19:55:30 +0530191 * @param path package relative path
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530192 */
Vinod Kumar S08710982016-03-03 19:55:30 +0530193 @Override
194 public void setRelativeFilePath(String path) {
195 relativeFilePath = path;
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530196 }
197
Bharat saraswal97459962016-02-20 21:57:16 +0530198 /**
Vinod Kumar S08710982016-03-03 19:55:30 +0530199 * Get the package relative path.
200 *
201 * @return package relative path
Bharat saraswal97459962016-02-20 21:57:16 +0530202 */
Vinod Kumar S08710982016-03-03 19:55:30 +0530203 @Override
204 public String getRelativeFilePath() {
205 return relativeFilePath;
206 }
207
208 /**
209 * Flush the cached attribute list to the corresponding temporary file.
210 */
211 private void flushCacheAttrToTempFile() {
Bharat saraswal97459962016-02-20 21:57:16 +0530212
213 for (AttributeInfo attr : getCachedAttributeList()) {
Vinod Kumar S08710982016-03-03 19:55:30 +0530214 JavaFileGenerator.parseAttributeInfo(attr, getGeneratedFileTypes(), getYangName());
Bharat saraswal97459962016-02-20 21:57:16 +0530215 }
216
217 /*
218 * clear the contents from the cached attribute list.
219 */
220 getCachedAttributeList().clear();
221 }
222
223 /**
224 * Add a new attribute to the file(s).
225 *
Vinod Kumar S08710982016-03-03 19:55:30 +0530226 * @param attrType data type of the added attribute
227 * @param name name of the attribute
Bharat saraswal97459962016-02-20 21:57:16 +0530228 * @param isListAttr if the current added attribute needs to be maintained
Vinod Kumar S08710982016-03-03 19:55:30 +0530229 * in a list
Bharat saraswal97459962016-02-20 21:57:16 +0530230 */
231 @Override
232 public void addAttributeInfo(YangType<?> attrType, String name, boolean isListAttr) {
Vinod Kumar S08710982016-03-03 19:55:30 +0530233 /* YANG name is mapped to java name */
234 name = JavaIdentifierSyntax.getCamelCase(name);
235
236 ImportInfo importInfo = new ImportInfo();
237 boolean isImport = false;
Bharat saraswal97459962016-02-20 21:57:16 +0530238
239 AttributeInfo newAttr = new AttributeInfo();
Bharat saraswal5e3c45c2016-02-22 22:15:21 +0530240 if (attrType != null) {
Bharat saraswal5e3c45c2016-02-22 22:15:21 +0530241 newAttr.setAttributeType(attrType);
Vinod Kumar S08710982016-03-03 19:55:30 +0530242 String importStr = AttributesJavaDataType.getJavaImportClass(attrType, isListAttr);
243 if (importStr != null) {
244 importInfo.setClassInfo(importStr);
245 importStr = AttributesJavaDataType.getJavaImportPackage(attrType, isListAttr);
246 importInfo.setPkgInfo(importStr);
247 isImport = true;
Bharat saraswal5e3c45c2016-02-22 22:15:21 +0530248 } else {
Vinod Kumar S08710982016-03-03 19:55:30 +0530249 importStr = AttributesJavaDataType.getJavaDataType(attrType);
250 if (importStr == null) {
251 throw new RuntimeException("not supported data type");
252 //TODO: need to change to translator exception.
253 }
254 importInfo.setClassInfo(importStr);
Bharat saraswal5e3c45c2016-02-22 22:15:21 +0530255 }
256
Vinod Kumar S08710982016-03-03 19:55:30 +0530257 } else {
258 importInfo.setClassInfo(JavaIdentifierSyntax.getCaptialCase(name));
259
260 importInfo.setPkgInfo(getRelativeFilePath().replace('/', '.')
261 + "." + getYangName());
262 isImport = true;
Bharat saraswal97459962016-02-20 21:57:16 +0530263 }
Vinod Kumar S08710982016-03-03 19:55:30 +0530264
265 newAttr.setQualifiedName(false);
266 if (isImport) {
267 boolean isNewImport = addImportInfo(importInfo);
268 if (!isNewImport) {
269 newAttr.setQualifiedName(true);
270 }
271 }
272
Bharat saraswal97459962016-02-20 21:57:16 +0530273 newAttr.setAttributeName(name);
274 newAttr.setListAttr(isListAttr);
Vinod Kumar S08710982016-03-03 19:55:30 +0530275 newAttr.setImportInfo(importInfo);
Bharat saraswal97459962016-02-20 21:57:16 +0530276
Vinod Kumar S08710982016-03-03 19:55:30 +0530277 if (getCachedAttributeList().size() == MAX_CACHABLE_ATTR) {
278 flushCacheAttrToTempFile();
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530279 }
Vinod Kumar S08710982016-03-03 19:55:30 +0530280 getCachedAttributeList().add(newAttr);
Bharat saraswal97459962016-02-20 21:57:16 +0530281 }
282
283 /**
284 * Flushes the cached contents to the target file, frees used resources.
285 */
286 @Override
287 public void close() throws IOException {
288
Vinod Kumar S08710982016-03-03 19:55:30 +0530289 flushCacheAttrToTempFile();
290
Bharat saraswal97459962016-02-20 21:57:16 +0530291 String className = getYangName();
Bharat saraswal5e3c45c2016-02-22 22:15:21 +0530292 className = JavaIdentifierSyntax.getCaptialCase(className);
Vinod Kumar S08710982016-03-03 19:55:30 +0530293 String path = getRelativeFilePath();
294 int fileType = getGeneratedFileTypes();
Bharat saraswal97459962016-02-20 21:57:16 +0530295
Bharat saraswal97459962016-02-20 21:57:16 +0530296 /*
297 * TODO: add the file header using
298 * JavaCodeSnippetGen.getFileHeaderComment
299 */
Bharat saraswal97459962016-02-20 21:57:16 +0530300
Bharat saraswal5e3c45c2016-02-22 22:15:21 +0530301 List<String> imports = new LinkedList<>();
Vinod Kumar S08710982016-03-03 19:55:30 +0530302 String importString;
Bharat saraswal5e3c45c2016-02-22 22:15:21 +0530303
Vinod Kumar S08710982016-03-03 19:55:30 +0530304 for (ImportInfo importInfo : getImportSet()) {
305 importString = "";
306 if (importInfo.getPkgInfo() != null) {
307 importString = importString + importInfo.getPkgInfo() + ".";
Bharat saraswal97459962016-02-20 21:57:16 +0530308 }
Vinod Kumar S08710982016-03-03 19:55:30 +0530309 importString = importString + importInfo.getClassInfo();
310 imports.add(importString);
Bharat saraswal97459962016-02-20 21:57:16 +0530311 }
312
Bharat saraswal97459962016-02-20 21:57:16 +0530313 /**
Bharat saraswal5e3c45c2016-02-22 22:15:21 +0530314 * Start generation of files.
315 */
Vinod Kumar S08710982016-03-03 19:55:30 +0530316 if ((fileType & GeneratedFileType.INTERFACE_MASK) != 0
317 || fileType == GeneratedFileType.GENERATE_INTERFACE_WITH_BUILDER) {
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530318
319 /**
320 * Create interface file.
321 */
322 String interfaceFileName = className;
Vinod Kumar S08710982016-03-03 19:55:30 +0530323 File interfaceFile = JavaFileGenerator.getFileObject(path, interfaceFileName, JAVA_FILE_EXTENSION);
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530324 interfaceFile = JavaFileGenerator.generateInterfaceFile(interfaceFile, className, imports,
Vinod Kumar S08710982016-03-03 19:55:30 +0530325 getCachedAttributeList(), path.replace('/', '.'));
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530326
327 /**
328 * Create temp builder interface file.
329 */
330 String builderInterfaceFileName = className + UtilConstants.BUILDER + UtilConstants.INTERFACE;
Vinod Kumar S08710982016-03-03 19:55:30 +0530331 File builderInterfaceFile = JavaFileGenerator.getFileObject(path, builderInterfaceFileName,
332 TEMP_FILE_EXTENSION);
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530333 builderInterfaceFile = JavaFileGenerator.generateBuilderInterfaceFile(builderInterfaceFile, className,
Vinod Kumar S08710982016-03-03 19:55:30 +0530334 path.replace('/', '.'), getCachedAttributeList());
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530335
336 /**
337 * Append builder interface file to interface file and close it.
338 */
339 JavaFileGenerator.appendFileContents(builderInterfaceFile, interfaceFile);
340 JavaFileGenerator.insert(interfaceFile,
Vinod Kumar S08710982016-03-03 19:55:30 +0530341 JavaFileGenerator.closeFile(GeneratedFileType.INTERFACE_MASK, interfaceFileName));
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530342
343 /**
344 * Remove temp files.
345 */
346 JavaFileGenerator.clean(builderInterfaceFile);
Bharat saraswal5e3c45c2016-02-22 22:15:21 +0530347 }
348
Vinod Kumar S08710982016-03-03 19:55:30 +0530349 if ((fileType & GeneratedFileType.BUILDER_CLASS_MASK) != 0
350 || fileType == GeneratedFileType.GENERATE_INTERFACE_WITH_BUILDER) {
Bharat saraswal5e3c45c2016-02-22 22:15:21 +0530351
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530352 /**
353 * Create builder class file.
Bharat saraswal97459962016-02-20 21:57:16 +0530354 */
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530355 String builderFileName = className + UtilConstants.BUILDER;
Vinod Kumar S08710982016-03-03 19:55:30 +0530356 File builderFile = JavaFileGenerator.getFileObject(path, builderFileName, JAVA_FILE_EXTENSION);
357 builderFile = JavaFileGenerator.generateBuilderClassFile(builderFile, className, imports,
358 path.replace('/', '.'), getCachedAttributeList());
Bharat saraswal97459962016-02-20 21:57:16 +0530359
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530360 /**
361 * Create temp impl class file.
362 */
Bharat saraswal97459962016-02-20 21:57:16 +0530363
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530364 String implFileName = className + UtilConstants.IMPL;
Vinod Kumar S08710982016-03-03 19:55:30 +0530365 File implTempFile = JavaFileGenerator.getFileObject(path, implFileName, TEMP_FILE_EXTENSION);
366 implTempFile = JavaFileGenerator.generateImplClassFile(implTempFile, className,
367 path.replace('/', '.'), getCachedAttributeList());
Bharat saraswal97459962016-02-20 21:57:16 +0530368
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530369 /**
370 * Append impl class to builder class and close it.
371 */
372 JavaFileGenerator.appendFileContents(implTempFile, builderFile);
373 JavaFileGenerator.insert(builderFile,
Vinod Kumar S08710982016-03-03 19:55:30 +0530374 JavaFileGenerator.closeFile(GeneratedFileType.BUILDER_CLASS_MASK, builderFileName));
Bharat saraswal97459962016-02-20 21:57:16 +0530375
Bharat saraswalc46ee2a2016-02-25 02:26:43 +0530376 /**
377 * Remove temp files.
378 */
379 JavaFileGenerator.clean(implTempFile);
Bharat saraswal97459962016-02-20 21:57:16 +0530380 }
381 }
Vinod Kumar S08710982016-03-03 19:55:30 +0530382
383 public YangTypeDef getTypedefInfo() {
384 return typedefInfo;
385 }
386
387 public void setTypedefInfo(YangTypeDef typedefInfo) {
388 this.typedefInfo = typedefInfo;
389 }
Bharat saraswal97459962016-02-20 21:57:16 +0530390}