blob: ab537c8419d1d34350a0c39a7c2cd1e6ce8d1468 [file] [log] [blame]
/*
* Copyright 2016 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.yangutils.translator.tojava.utils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.translator.tojava.HasJavaFileInfo;
import org.onosproject.yangutils.translator.tojava.HasTempJavaCodeFragmentFiles;
import org.onosproject.yangutils.translator.tojava.JavaFileInfo;
import org.onosproject.yangutils.translator.tojava.TempJavaCodeFragmentFiles;
import org.onosproject.yangutils.utils.UtilConstants;
import org.onosproject.yangutils.utils.io.impl.CopyrightHeader;
import org.onosproject.yangutils.utils.io.impl.FileSystemUtil;
import org.onosproject.yangutils.utils.io.impl.JavaDocGen;
import org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.BUILDER_CLASS_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.BUILDER_INTERFACE_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_TYPEDEF_CLASS;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.IMPL_CLASS_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.INTERFACE_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.ATTRIBUTES_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.CONSTRUCTOR_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.EQUALS_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.GETTER_FOR_CLASS_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.GETTER_FOR_INTERFACE_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.HASH_CODE_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.SETTER_FOR_CLASS_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.SETTER_FOR_INTERFACE_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.TO_STRING_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getCaptialCase;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getBuildString;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getConstructorStart;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getDefaultConstructorString;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getEqualsMethodClose;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getEqualsMethodOpen;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getHashCodeMethodClose;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getHashCodeMethodOpen;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getToStringMethodClose;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getToStringMethodOpen;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.parseBuilderInterfaceBuildMethodString;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.partString;
/**
* Generates java file.
*/
public final class JavaFileGenerator {
/**
* Default constructor.
*/
private JavaFileGenerator() {
}
/**
* Returns a file object for generated file.
*
* @param fileName file name
* @param filePath file package path
* @param extension file extension
* @param handle cached file handle
* @return file object
*/
public static File getFileObject(String filePath, String fileName, String extension, JavaFileInfo handle) {
return new File(handle.getBaseCodeGenPath() + filePath + File.separator + fileName + extension);
}
/**
* Returns generated interface file for current node.
*
* @param file file
* @param imports imports for the file
* @param curNode current YANG node
* @return interface file
* @throws IOException when fails to write in file
*/
public static File generateInterfaceFile(File file, List<String> imports, YangNode curNode) throws IOException {
JavaFileInfo javaFileInfo = ((HasJavaFileInfo) curNode).getJavaFileInfo();
String className = getCaptialCase(javaFileInfo.getJavaName());
String path = javaFileInfo.getBaseCodeGenPath() + javaFileInfo.getPackageFilePath();
initiateFile(file, className, INTERFACE_MASK, imports, path);
/**
* Add getter methods to interface file.
*/
try {
appendMethod(file, getDataFromTempFileHandle(GETTER_FOR_INTERFACE_MASK, curNode));
} catch (IOException e) {
throw new IOException("No data found in temporary java code fragment files for " + className
+ " while interface file generation");
}
return file;
}
/**
* Return generated builder interface file for current node.
*
* @param file file
* @param curNode current YANG node
* @return builder interface file
* @throws IOException when fails to write in file
*/
public static File generateBuilderInterfaceFile(File file, YangNode curNode) throws IOException {
JavaFileInfo javaFileInfo = ((HasJavaFileInfo) curNode).getJavaFileInfo();
String className = getCaptialCase(javaFileInfo.getJavaName());
String path = javaFileInfo.getBaseCodeGenPath() + javaFileInfo.getPackageFilePath();
initiateFile(file, className, BUILDER_INTERFACE_MASK, null, path);
List<String> methods = new ArrayList<>();
try {
methods.add(UtilConstants.FOUR_SPACE_INDENTATION
+ getDataFromTempFileHandle(GETTER_FOR_INTERFACE_MASK, curNode));
methods.add(UtilConstants.NEW_LINE);
methods.add(UtilConstants.FOUR_SPACE_INDENTATION
+ getDataFromTempFileHandle(SETTER_FOR_INTERFACE_MASK, curNode));
} catch (IOException e) {
throw new IOException("No data found in temporary java code fragment files for " + className
+ " while builder interface file generation");
}
/**
* Add build method to builder interface file.
*/
methods.add(parseBuilderInterfaceBuildMethodString(className));
/**
* Add getters and setters in builder interface.
*/
for (String method : methods) {
appendMethod(file, method);
}
insert(file, UtilConstants.CLOSE_CURLY_BRACKET + UtilConstants.NEW_LINE);
return file;
}
/**
* Returns generated builder class file for current node.
*
* @param file file
* @param imports imports for the file
* @param curNode current YANG node
* @return builder class file
* @throws IOException when fails to write in file
*/
public static File generateBuilderClassFile(File file, List<String> imports, YangNode curNode) throws IOException {
JavaFileInfo javaFileInfo = ((HasJavaFileInfo) curNode).getJavaFileInfo();
String className = getCaptialCase(javaFileInfo.getJavaName());
String path = javaFileInfo.getBaseCodeGenPath() + javaFileInfo.getPackageFilePath();
initiateFile(file, className, BUILDER_CLASS_MASK, imports, path);
List<String> methods = new ArrayList<>();
/**
* Add attribute strings.
*/
try {
insert(file, UtilConstants.NEW_LINE + UtilConstants.FOUR_SPACE_INDENTATION
+ getDataFromTempFileHandle(ATTRIBUTES_MASK, curNode));
} catch (IOException e) {
throw new IOException("No data found in temporary java code fragment files for " + className
+ " while builder class file generation");
}
try {
methods.add(getDataFromTempFileHandle(GETTER_FOR_CLASS_MASK, curNode));
methods.add(getDataFromTempFileHandle(SETTER_FOR_CLASS_MASK, curNode) + UtilConstants.NEW_LINE);
} catch (IOException e) {
throw new IOException("No data found in temporary java code fragment files for " + className
+ " while builder class file generation");
}
/**
* Add default constructor and build method impl.
*/
methods.add(getBuildString(className) + UtilConstants.NEW_LINE);
methods.add(UtilConstants.NEW_LINE
+ getDefaultConstructorString(className + UtilConstants.BUILDER, UtilConstants.PUBLIC));
/**
* Add methods in builder class.
*/
for (String method : methods) {
appendMethod(file, method);
}
return file;
}
/**
* Returns generated impl class file for current node.
*
* @param file file
* @param curNode current YANG node
* @return impl class file
* @throws IOException when fails to write in file
*/
public static File generateImplClassFile(File file, YangNode curNode)
throws IOException {
JavaFileInfo javaFileInfo = ((HasJavaFileInfo) curNode).getJavaFileInfo();
String className = getCaptialCase(javaFileInfo.getJavaName());
String path = javaFileInfo.getBaseCodeGenPath() + javaFileInfo.getPackageFilePath();
initiateFile(file, className, IMPL_CLASS_MASK, null, path);
List<String> methods = new ArrayList<>();
/**
* Add attribute strings.
*/
try {
insert(file, UtilConstants.NEW_LINE + UtilConstants.FOUR_SPACE_INDENTATION
+ getDataFromTempFileHandle(ATTRIBUTES_MASK, curNode));
} catch (IOException e) {
throw new IOException("No data found in temporary java code fragment files for " + className
+ " while impl class file generation");
}
insert(file, UtilConstants.NEW_LINE);
try {
methods.add(getDataFromTempFileHandle(GETTER_FOR_CLASS_MASK, curNode));
methods.add(getHashCodeMethodClose(getHashCodeMethodOpen() + partString(
getDataFromTempFileHandle(HASH_CODE_IMPL_MASK, curNode).replace(UtilConstants.NEW_LINE,
UtilConstants.EMPTY_STRING))));
methods.add(getEqualsMethodClose(getEqualsMethodOpen(className + UtilConstants.IMPL)
+ getDataFromTempFileHandle(EQUALS_IMPL_MASK, curNode)));
methods.add(getToStringMethodOpen() + getDataFromTempFileHandle(TO_STRING_IMPL_MASK, curNode)
+ getToStringMethodClose());
} catch (IOException e) {
throw new IOException("No data found in temporary java code fragment files for " + className
+ " while impl class file generation");
}
try {
methods.add(getConstructorStart(className) + getDataFromTempFileHandle(CONSTRUCTOR_IMPL_MASK, curNode)
+ UtilConstants.FOUR_SPACE_INDENTATION + UtilConstants.CLOSE_CURLY_BRACKET);
} catch (IOException e) {
throw new IOException("No data found in temporary java code fragment files for " + className
+ " while impl class file generation");
}
/**
* Add methods in impl class.
*/
for (String method : methods) {
appendMethod(file, UtilConstants.FOUR_SPACE_INDENTATION + method + UtilConstants.NEW_LINE);
}
insert(file, UtilConstants.CLOSE_CURLY_BRACKET + UtilConstants.NEW_LINE);
return file;
}
/**
* Return data stored in temporary files.
*
* @param curNode current YANG node
* @param generatedTempFiles mask for the types of files being generated
* @return data stored in temporary files
* @throws IOException when failed to get the data from temporary file
* handle
*/
private static String getDataFromTempFileHandle(int generatedTempFiles, YangNode curNode) throws IOException {
TempJavaCodeFragmentFiles tempJavaCodeFragmentFiles = ((HasTempJavaCodeFragmentFiles) curNode)
.getTempJavaCodeFragmentFiles();
if ((generatedTempFiles & ATTRIBUTES_MASK) != 0) {
return tempJavaCodeFragmentFiles
.getTemporaryDataFromFileHandle(tempJavaCodeFragmentFiles.getAttributesTempFileHandle());
} else if ((generatedTempFiles & GETTER_FOR_INTERFACE_MASK) != 0) {
return tempJavaCodeFragmentFiles
.getTemporaryDataFromFileHandle(tempJavaCodeFragmentFiles.getGetterInterfaceTempFileHandle());
} else if ((generatedTempFiles & SETTER_FOR_INTERFACE_MASK) != 0) {
return tempJavaCodeFragmentFiles
.getTemporaryDataFromFileHandle(tempJavaCodeFragmentFiles.getSetterInterfaceTempFileHandle());
} else if ((generatedTempFiles & GETTER_FOR_CLASS_MASK) != 0) {
return tempJavaCodeFragmentFiles
.getTemporaryDataFromFileHandle(tempJavaCodeFragmentFiles.getGetterImplTempFileHandle());
} else if ((generatedTempFiles & SETTER_FOR_CLASS_MASK) != 0) {
return tempJavaCodeFragmentFiles
.getTemporaryDataFromFileHandle(tempJavaCodeFragmentFiles.getSetterImplTempFileHandle());
} else if ((generatedTempFiles & CONSTRUCTOR_IMPL_MASK) != 0) {
return tempJavaCodeFragmentFiles
.getTemporaryDataFromFileHandle(tempJavaCodeFragmentFiles.getConstructorImplTempFileHandle());
} else if ((generatedTempFiles & HASH_CODE_IMPL_MASK) != 0) {
return tempJavaCodeFragmentFiles
.getTemporaryDataFromFileHandle(tempJavaCodeFragmentFiles.getHashCodeImplTempFileHandle());
} else if ((generatedTempFiles & EQUALS_IMPL_MASK) != 0) {
return tempJavaCodeFragmentFiles
.getTemporaryDataFromFileHandle(tempJavaCodeFragmentFiles.getEqualsImplTempFileHandle());
} else if ((generatedTempFiles & TO_STRING_IMPL_MASK) != 0) {
return tempJavaCodeFragmentFiles
.getTemporaryDataFromFileHandle(tempJavaCodeFragmentFiles.getToStringImplTempFileHandle());
}
return null;
}
/**
* Initiate generation of file based on generated file type.
*
* @param file generated file
* @param className generated file class name
* @param type generated file type
* @param imports imports for the file
* @param pkg generated file package
* @throws IOException when fails to generate a file
*/
private static void initiateFile(File file, String className, int type, List<String> imports,
String pkg) throws IOException {
try {
file.createNewFile();
appendContents(file, className, type, imports, pkg);
} catch (IOException e) {
throw new IOException("Failed to create " + file.getName() + " class file.");
}
}
/**
* Appends the temp files to main files.
*
* @param appendFile temp file
* @param srcFile main file
* @throws IOException when fails to append contents
*/
public static void appendFileContents(File appendFile, File srcFile) throws IOException {
try {
FileSystemUtil.appendFileContents(appendFile, srcFile);
} catch (IOException e) {
throw new IOException("Failed to append " + appendFile + " in " + srcFile);
}
}
/**
* Append methods to the generated files.
*
* @param file file in which method needs to be appended
* @param method method which needs to be appended
* @throws IOException IO operation failure
*/
private static void appendMethod(File file, String method) throws IOException {
insert(file, method);
}
/**
* Appends all the contents into a generated java file.
*
* @param file generated file
* @param fileName generated file name
* @param type generated file type
* @param pkg generated file package
* @param importsList list of java imports.
* @throws IOException when fails to append contents
*/
private static void appendContents(File file, String fileName, int type, List<String> importsList,
String pkg) throws IOException {
String pkgString = parsePackageString(pkg, importsList);
if ((type & IMPL_CLASS_MASK) != 0) {
write(file, fileName, type, JavaDocType.IMPL_CLASS);
} else if ((type & BUILDER_INTERFACE_MASK) != 0) {
write(file, fileName, type, JavaDocType.BUILDER_INTERFACE);
} else if ((type & GENERATE_TYPEDEF_CLASS) != 0) {
appendHeaderContents(file, pkgString, importsList);
write(file, fileName, type, JavaDocType.IMPL_CLASS);
} else if ((type & INTERFACE_MASK) != 0) {
appendHeaderContents(file, pkgString, importsList);
write(file, fileName, type, JavaDocType.INTERFACE);
} else if ((type & BUILDER_CLASS_MASK) != 0) {
appendHeaderContents(file, pkgString, importsList);
write(file, fileName, type, JavaDocType.BUILDER_CLASS);
}
}
/**
* Removes base directory path from package and generates package string for
* file.
*
* @param pkg generated package
* @param importsList list of imports
* @return package string
*/
private static String parsePackageString(String pkg, List<String> importsList) {
if (pkg.contains(UtilConstants.ORG)) {
String[] strArray = pkg.split(UtilConstants.ORG);
pkg = UtilConstants.ORG + strArray[1].replace(UtilConstants.SLASH, UtilConstants.PERIOD);
}
if (importsList != null) {
if (!importsList.isEmpty()) {
return UtilConstants.PACKAGE + UtilConstants.SPACE + pkg + UtilConstants.SEMI_COLAN
+ UtilConstants.NEW_LINE;
} else {
return UtilConstants.PACKAGE + UtilConstants.SPACE + pkg + UtilConstants.SEMI_COLAN;
}
} else {
return UtilConstants.PACKAGE + UtilConstants.SPACE + pkg + UtilConstants.SEMI_COLAN;
}
}
/**
* Appends other contents to interface, builder and typedef classes. for
* example : ONOS copyright, imports and package.
*
* @param file generated file
* @param pkg generated package
* @param importsList list of imports
* @throws IOException when fails to append contents.
*/
private static void appendHeaderContents(File file, String pkg, List<String> importsList) throws IOException {
insert(file, CopyrightHeader.getCopyrightHeader());
insert(file, pkg);
/*
* TODO: add the file header using
* JavaCodeSnippetGen.getFileHeaderComment
*/
if (importsList != null) {
insert(file, UtilConstants.NEW_LINE);
for (String imports : importsList) {
insert(file, imports);
}
}
}
/**
* Write data to the specific generated file.
*
* @param file generated file
* @param fileName file name
* @param genType generated file type
* @param javaDocType java doc type
* @throws IOException when fails to write into a file
*/
private static void write(File file, String fileName, int genType, JavaDocGen.JavaDocType javaDocType)
throws IOException {
insert(file, JavaDocGen.getJavaDoc(javaDocType, fileName, false));
insert(file, JavaCodeSnippetGen.getJavaClassDefStart(genType, fileName));
}
/**
* Insert in the generated file.
*
* @param file file in which need to be inserted
* @param data data which need to be inserted
* @throws IOException when fails to insert into file
*/
public static void insert(File file, String data) throws IOException {
try {
FileSystemUtil.updateFileHandle(file, data, false);
} catch (IOException e) {
throw new IOException("Failed to insert in " + file + "file");
}
}
/**
* Closes the files handle for generate files.
*
* @param file generate files
* @throws IOException when failed to close the file handle
*/
public static void closeFileHandles(File file) throws IOException {
try {
FileSystemUtil.updateFileHandle(file, null, true);
} catch (IOException e) {
throw new IOException("Failed to close file handle for " + file + "file");
}
}
/**
* Removes temp files.
*
* @param file file to be removed
*/
public static void clean(File file) {
if (file.exists()) {
file.delete();
}
}
/**
* Removes temp files.
*
* @param tempDir temp directory
* @throws IOException when fails to delete the directory
*/
public static void cleanTempFiles(File tempDir) throws IOException {
FileUtils.deleteDirectory(tempDir);
}
}