Guest User

JavaCodeGenerator.java

a guest
May 4th, 2024
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.98 KB | Source Code | 0 0
  1. import java.io.BufferedWriter;
  2. import java.io.File;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.io.OutputStreamWriter;
  6. import java.lang.reflect.Field;
  7. import java.lang.reflect.Method;
  8. import java.lang.reflect.InvocationTargetException;
  9. import java.net.MalformedURLException;
  10. import java.net.URL;
  11. import java.net.URLClassLoader;
  12. import java.nio.charset.StandardCharsets;
  13. import java.util.ArrayList;
  14. import java.util.Arrays;
  15. import java.util.HashMap;
  16. import java.util.List;
  17. import java.util.Map;
  18. import java.util.TreeMap;
  19. import java.util.UUID;
  20.  
  21. public class JavaCodeGenerator {
  22.     private static List<String> generateSource(String className, Map<String, String> fields, Map<String, List<String>> methods)
  23.     throws IllegalArgumentException {
  24.         if (!validName(className)) { throw new IllegalArgumentException("className"); }
  25.         if (fields == null) { throw new IllegalArgumentException("fields"); }
  26.         if (methods == null) { throw new IllegalArgumentException("methods"); }
  27.         final List<String> source = new ArrayList<>();
  28.         source.add(String.format("public class %s {", className));
  29.         for (Map.Entry<String, String> entry : fields.entrySet()) {
  30.             if (!validName(entry.getKey())) { throw new IllegalArgumentException("fields"); }
  31.             source.add("");
  32.             source.add(String.format("    public %s %s;", entry.getValue(), entry.getKey()));
  33.         }
  34.         for (Map.Entry<String, List<String>> entry : methods.entrySet()) {
  35.             if (!validName(entry.getKey())) { throw new IllegalArgumentException("methods"); }
  36.             source.add("");
  37.             source.add(String.format("    public void %s() {", entry.getKey()));
  38.             for (String statement : entry.getValue()) {
  39.                 final String trimStatement = statement.trim();
  40.                 if (statement.startsWith("PRINT")) {
  41.                     final String value = statement.substring("PRINT".length()).trim();
  42.                     if (!value.startsWith("#")) {
  43.                         if (validName(value)) {
  44.                             if (fields.get(value) != null) {
  45.                                 source.add(String.format("        System.out.println(%s);", value));
  46.                             } else {
  47.                                 throw new IllegalArgumentException("methods");
  48.                             }
  49.                         } else if (validString(value) || validNumber(value)) {
  50.                             source.add(String.format("        System.out.println(%s);", value));
  51.                         } else {
  52.                             throw new IllegalArgumentException("methods");
  53.                         }
  54.                     }
  55.                 }
  56.             }
  57.             source.add("    }");
  58.         }
  59.         source.add("}");
  60.         return source;
  61.     }
  62.  
  63.     private static String buildClassFile(String className, List<String> source, String path)
  64.     throws IllegalArgumentException, IOException, InterruptedException {
  65.         if (!validName(className)) { throw new IllegalArgumentException("className"); }
  66.         if (source == null || source.isEmpty()) { throw new IllegalArgumentException("source"); }
  67.         if (path == null || path.isEmpty()) { throw new IllegalArgumentException("path"); }
  68.         final File directory = new File(path,  UUID.randomUUID().toString());
  69.         directory.mkdir();
  70.         final File sourceFile = new File(directory, className + ".java");
  71.         try (
  72.             FileOutputStream fos = new FileOutputStream(sourceFile);
  73.             OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
  74.             BufferedWriter bw = new BufferedWriter(osw)
  75.         ) {
  76.             for (String line : source) {
  77.                 bw.write(line);
  78.                 bw.newLine();
  79.             }
  80.         } catch (IOException ex) {
  81.             throw ex;
  82.         }
  83.         if (sourceFile.exists()) {
  84.             final String fs = System.getProperty("file.separator");
  85.             final Process process = new ProcessBuilder(
  86.                 System.getenv("JAVA_HOME") + fs + "bin" + fs + "javac",
  87.                 "-source",
  88.                 "8",
  89.                 "-target",
  90.                 "8",
  91.                 "-encoding",
  92.                 "utf8",
  93.                 "-cp",
  94.                 directory.getAbsolutePath(),
  95.                 "-d",
  96.                 directory.getAbsolutePath(),
  97.                 sourceFile.getAbsolutePath()
  98.             ).start();
  99.             final int exitCode = process.waitFor();
  100.             sourceFile.delete();
  101.             if (exitCode != 0) {
  102.                 final File classFile = new File(directory, className + ".class");
  103.                 if (classFile.exists()) {
  104.                     classFile.delete();
  105.                 }
  106.                 directory.delete();
  107.                 return "";
  108.             }
  109.         }
  110.         return directory.getAbsolutePath();
  111.     }
  112.  
  113.     private static boolean validName(String name) {
  114.         if (name == null || name.isEmpty()) return false;
  115.         final char[] chars = name.toCharArray();
  116.         if (chars[0] != '_' && !Character.isLetter(chars[0])) return false;
  117.         for (int i = 1; i < chars.length; i++) {
  118.             if (chars[i] != '_' && !Character.isLetter(chars[i]) && !Character.isDigit(chars[i])) return false;
  119.         }
  120.         return true;
  121.     }
  122.  
  123.     private static boolean validString(String str) {
  124.         if (str == null || str.isEmpty()) return false;
  125.         final char[] chars = str.toCharArray();
  126.         if (chars.length < 2) return false;
  127.         if (chars[0] != '\"') return false;
  128.         if (chars[chars.length - 1] != '\"') return false;
  129.         for (int i = 1; i < chars.length - 1; i++) {
  130.             if (chars[i] == '\"') return false;
  131.         }
  132.         return true;
  133.     }
  134.  
  135.     private static boolean validNumber(String number) {
  136.         if (number == null || number.isEmpty()) return false;
  137.         final char[] chars = number.toCharArray();
  138.         for (int i = 0; i < chars.length; i++) {
  139.             if (!Character.isDigit(chars[i])) return false;
  140.         }
  141.         return true;
  142.     }
  143.  
  144.     private static int parseNumber(String number) {
  145.         try {
  146.             return Integer.parseInt(number);
  147.         } catch (NumberFormatException ex) {
  148.             return 0;
  149.         }
  150.     }
  151.  
  152.     private static void usingClass(String className, String path)
  153.     throws ClassNotFoundException, MalformedURLException,
  154.             IllegalAccessException, NoSuchFieldException, InstantiationException,
  155.             NoSuchMethodException, InvocationTargetException {
  156.         final URL[] urls = { new File(path).toURI().toURL() };
  157.         final URLClassLoader classLoader = new URLClassLoader(urls);
  158.         final Class userClass = classLoader.loadClass(className);
  159.         final Field id = userClass.getField("id");
  160.         final Field name = userClass.getField("name");
  161.         final Field password = userClass.getField("password");
  162.         final Method printHello = userClass.getMethod("printHello");
  163.         final Object user = userClass.newInstance();
  164.         id.set(user, Integer.valueOf(1013));
  165.         name.set(user, "FoxMulder");
  166.         password.set(user, "trustno1");
  167.         dumpObject(user);
  168.         printHello.invoke(user);
  169.     }
  170.  
  171.     private static void dumpObject(Object object)
  172.     throws IllegalAccessException, NoSuchFieldException {
  173.         final Field[] fields = object.getClass().getDeclaredFields();
  174.         final Map<String, String> sortedFields = new TreeMap<>();
  175.         for (Field field : fields) {
  176.             final String name = field.getName();
  177.             final Object value = field.get(object);
  178.             sortedFields.put(name, value != null ? value.toString() : "");
  179.         }
  180.         final String className = object.getClass().getCanonicalName();
  181.         System.out.println(String.format("<%s>", className));
  182.         for (Map.Entry<String, String> entry : sortedFields.entrySet()) {
  183.             final String name = entry.getKey();
  184.             final String value = entry.getValue();
  185.             System.out.println(String.format("  <%s>%s</%s>", name, replaceSpecialXmlChars(value), name));
  186.         }
  187.         System.out.println(String.format("</%s>", className));
  188.     }
  189.  
  190.     private static String replaceSpecialXmlChars(String str) {
  191.         if (str == null || str.isEmpty()) return str;
  192.         return str.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;");
  193.     }
  194.  
  195.     public static void main(String[] args) {
  196.         try {
  197.             final Map<String, String> fields = new HashMap<>();
  198.             fields.put("id", "Integer");
  199.             fields.put("name", "String");
  200.             fields.put("password", "String");
  201.             final Map<String, List<String>> methods = new HashMap<>();
  202.             final List<String> methodCode = new ArrayList<>();
  203.             methodCode.add("PRINT \"Password is:\"");
  204.             methodCode.add("PRINT password");
  205.             methods.put("printHello", methodCode);
  206.             System.out.println("SUB printHello()");
  207.             for (String line : methodCode) {
  208.                 System.out.println(line);
  209.             }
  210.             System.out.println("END SUB");
  211.             final List<String> source = generateSource("User", fields, methods);
  212.             final String path = buildClassFile("User", source, System.getProperty("user.dir"));
  213.             if (!path.isEmpty() && (new File(path, "User.class")).exists()) {
  214.                 System.out.println("Class User created in: " + path);
  215.                 try {
  216.                     usingClass("User", path);
  217.                 } catch (Exception ex) {
  218.                     System.err.println("[ERROR] " + ex.getClass().getName() + ' ' + ex.getMessage());
  219.                 } finally {
  220.                     (new File(path, "User.class")).delete();
  221.                     (new File(path)).delete();
  222.                 }
  223.             }
  224.         } catch (Exception ex) {
  225.             System.err.println("[ERROR] " + ex.getClass().getName() + ' ' + ex.getMessage());
  226.         }
  227.     }
  228. }
Add Comment
Please, Sign In to add comment