170 lines
6.3 KiB
Java
170 lines
6.3 KiB
Java
package electrosphere.main.util;
|
|
|
|
import java.io.File;
|
|
import java.util.List;
|
|
|
|
import org.jboss.forge.roaster.model.source.Import;
|
|
import org.jboss.forge.roaster.model.source.JavaClassSource;
|
|
import org.jboss.forge.roaster.model.source.MethodSource;
|
|
|
|
import electrosphere.main.structure.BTreeIdEnum;
|
|
import electrosphere.main.structure.BehaviorTree;
|
|
import electrosphere.main.structure.ProjectStructure;
|
|
import electrosphere.main.targets.TargetFile;
|
|
|
|
/**
|
|
* Utilities for modifying the source code of a class
|
|
*/
|
|
public class ClassSourceUtils {
|
|
|
|
//The default indent for a method, field, etc
|
|
static final int DEFAULT_INDENT = 4;
|
|
|
|
|
|
/**
|
|
* Adds to replaces a method in a given behavior tree
|
|
* @param structure The project structure
|
|
* @param targetFile The targetFile
|
|
* @param methodName The name of the method
|
|
* @param methodContent The content of the method that you want to insert or replace with
|
|
*/
|
|
public static void addOrReplaceMethod(ProjectStructure structure, TargetFile targetFile, String methodName, String methodContent){
|
|
//search for method
|
|
List<MethodSource<JavaClassSource>> methods = targetFile.getSource().getMethods();
|
|
MethodSource<JavaClassSource> methodSource = null;
|
|
for(MethodSource<JavaClassSource> methodRaw : methods){
|
|
if(methodRaw.getName().equals(methodName)){
|
|
if(methodSource != null){
|
|
throw new UnknownError("Two methods in a source file have the same name. This is unsupported by the addOrReplaceMethod function at this time!");
|
|
}
|
|
methodSource = methodRaw;
|
|
}
|
|
}
|
|
StringBuilder modifiedContent = targetFile.getModifiedContent();
|
|
if(methodSource == null){
|
|
int endOfClass = findEndOfClass(modifiedContent.toString());
|
|
String indentedFragment = TemplateInjectionUtils.indentFragment(methodContent, DEFAULT_INDENT);
|
|
//must newline
|
|
String finalInsertion = indentedFragment + "\n";
|
|
modifiedContent.insert(endOfClass, finalInsertion);
|
|
} else {
|
|
//methodStart is literally the first character of the function's name
|
|
int methodStart = methodSource.getStartPosition();
|
|
int indent = getCurrentIndent(modifiedContent.toString(),methodStart - 1);
|
|
int methodEnd = methodSource.getEndPosition();
|
|
String indentedFragment = TemplateInjectionUtils.indentFragment(methodContent, indent).trim();
|
|
modifiedContent.replace(methodStart, methodEnd, indentedFragment);
|
|
}
|
|
targetFile.setModifiedContent(modifiedContent.toString());
|
|
targetFile.reparse();
|
|
}
|
|
|
|
/**
|
|
* Finds the end of a class file
|
|
* @param sourceRaw The raw source
|
|
* @return The index of the final curly brace
|
|
*/
|
|
private static int findEndOfClass(String sourceRaw){
|
|
int curr = sourceRaw.length() - 1;
|
|
while(sourceRaw.charAt(curr) != '}'){
|
|
curr--;
|
|
}
|
|
return curr;
|
|
}
|
|
|
|
/**
|
|
* Gets the current indent of the source file at a given location
|
|
* @param sourceRaw The source file
|
|
* @param position The position
|
|
* @return The indent
|
|
*/
|
|
private static int getCurrentIndent(String sourceRaw, int position){
|
|
int indent = 0;
|
|
int curr = position;
|
|
while(sourceRaw.charAt(curr) != '\n'){
|
|
curr--;
|
|
indent++;
|
|
}
|
|
return indent;
|
|
}
|
|
|
|
/**
|
|
* Generates the first part of a class declaration file
|
|
* @param name The name of the class
|
|
* @param description The description of the class
|
|
* @param isPublic True if public, false otherwise
|
|
* @return The string containing the class header
|
|
*/
|
|
public static String generateClassHeader(String name, String description, boolean isPublic){
|
|
String rVal = "/**\n * " + description + "\n */\n";
|
|
rVal = rVal + "";
|
|
rVal = rVal + (isPublic ? "public " : "");
|
|
rVal = rVal + "class " + name + " {\n";
|
|
return rVal;
|
|
}
|
|
|
|
|
|
/**
|
|
* When passed in a file object, returns the package declaration that would be used in code to import that source file
|
|
* @param fileObj The raw java file object
|
|
* @return The package declaration
|
|
*/
|
|
public static String getPackageSourcePath(ProjectStructure structure, File fileObj){
|
|
String rVal = "";
|
|
rVal = structure.getRootFolder().toURI().relativize(fileObj.toURI()).getPath();
|
|
//delete past last forwardslash
|
|
int lastSlashIndex = rVal.length() - 1;
|
|
while(rVal.charAt(lastSlashIndex) != '/'){
|
|
lastSlashIndex--;
|
|
}
|
|
rVal = rVal.substring(0, lastSlashIndex);
|
|
//delete intro part
|
|
rVal = rVal.replace("src/main/java/", "");
|
|
rVal = rVal.replace("/",".");
|
|
return rVal;
|
|
}
|
|
|
|
/**
|
|
* Gets the package declaration for a given package path
|
|
* @param structure The project structure
|
|
* @param packagePath The package path
|
|
* @return The declaration line
|
|
*/
|
|
public static String getPackageDeclaration(ProjectStructure structure, String packagePath){
|
|
String rVal = "";
|
|
rVal = "package " + packagePath + ";\n";
|
|
return rVal;
|
|
}
|
|
|
|
/**
|
|
* Generates the footer of a class declaration file
|
|
* @return The string containing the class footer
|
|
*/
|
|
public static String generateClassEnd(){
|
|
return "}\n";
|
|
}
|
|
|
|
/**
|
|
* Guarantees that a given path is imported
|
|
* @param structure The project structure
|
|
* @param tree The tree
|
|
* @param qualifiedPath The qualified name to import
|
|
*/
|
|
public static void importClass(ProjectStructure structure, TargetFile targetFile, String qualifiedPath){
|
|
StringBuilder modifiedContent = targetFile.getModifiedContent();
|
|
List<Import> imports = targetFile.getSource().getImports();
|
|
boolean present = false;
|
|
for(Import currentImport : imports){
|
|
String importName = currentImport.getQualifiedName();
|
|
if(importName.equals(qualifiedPath)){
|
|
present = true;
|
|
}
|
|
}
|
|
if(!present){
|
|
Utilities.insertIntoSource(modifiedContent, "import " + qualifiedPath + ";", 3);
|
|
targetFile.setModifiedContent(modifiedContent.toString());
|
|
}
|
|
}
|
|
|
|
}
|