본문 바로가기

기타 보관함/개발자정보

Java 소스와 SQL Map를 분석하여 매핑 관계 자동 추출

반응형
package viw.itf;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.utils.SourceRoot;

public class Main {
    public static void main(String[] args) {
        String javadirectoryPath = "C:\\viw\\batch";
        String sqldirectoryPath = "C:\\viw\\sql";
        try {
            List<File> files = DirectoryReader.listFiles(javadirectoryPath);
            List<File> files2 = DirectoryReader.listFiles(sqldirectoryPath);

            // Map<String, String> javaMethods = null;
            Map<String, String> javaMethods = new HashMap<>();
            Map<String, String> sqlMappings = null;

            JavaParser parser = new JavaParser();

            for (File file : files) {
                System.out.println("파일명:" + file.getName());

                System.out.println("파일 절대 경로: " + file.getAbsolutePath());
                String parent = file.getParent();
                System.out.println("부모 디렉토리 경로: " + parent.replaceAll(Pattern.quote(javadirectoryPath+"\\"),""));

                // CompilationUnit cu = JavaParser.parse(file);
                CompilationUnit cu = parser.parse(file)
                        .getResult()
                        .orElseThrow(() -> new RuntimeException("Parsing failed for file: " + file.getName()));

                // cu 사용 코드 작성

                cu.findAll(MethodDeclaration.class).forEach(method -> {
                    String methodName = method.getNameAsString();
                    String methodBody = method.toString();  // 메서드 전체 소스코드 (시그니처 + 본문)

                    System.out.println("methodName:" + methodName + ", \nmethodBody:\n"+methodBody);
                    javaMethods.put(methodName, methodBody);
                });

                /*
                if (file.getName().endsWith(".java")) {
                    javaMethods = JavaSourceParser.parseJavaFile(file.getAbsolutePath());
                    // 출력 : Java 8 이상, forEach와 람다 사용
                    javaMethods.forEach((key, value) ->
                            System.out.println("파라미터: " + key + ", 값: " + value)
                    );
                }
                */

            }

            for (File file : files2) {
                System.out.println("파일명:" + file.getName());
                System.out.println("파일 절대 경로: " + file.getAbsolutePath());
                String parent = file.getParent();
                System.out.println("부모 디렉토리 경로: " + parent.replaceAll(Pattern.quote(sqldirectoryPath+"\\"),""));

                if (file.getName().endsWith(".xml")) {
                    String content = DirectoryReader.readFileContent(file.getAbsolutePath());
                    sqlMappings = SqlMapParser.parseSqlMap(content);
                    // 출력 : Java 8 이상, forEach와 람다 사용
                    sqlMappings.forEach((key, value) ->
                            System.out.println("파라미터: " + key + ", 값: " + value)
                    );
                }
            }


            MappingExtractor.extractMappings(javaMethods, sqlMappings);
            DatabaseSaver.saveToDatabase(javaMethods, sqlMappings);

        } catch (IOException | SQLException e) {
            e.printStackTrace();
        }
    }
}

설정 한 특정 디렉토리의 아래에 있는 Java 소스와 SQL Map를 분석하여 매핑 관계 자동 추출 및 소스를 분석하여 레포트 할 수 있도록 Java 프로그램 개발

 

 

설정 한 특정 디렉토리의 아래에 있는 Java 소스와 SQL Map를 분석하여 매핑 관계 자동 추출 및 소스를 분석하여 레포트를 Mariadb에 저장하는 테이블 생성문 및 Java 프로그램 개발

 

CREATE TABLE java_methods (
    id INT AUTO_INCREMENT PRIMARY KEY,
    method_name VARCHAR(255) NOT NULL,
    method_content TEXT NOT NULL
);

CREATE TABLE sql_mappings (
    id INT AUTO_INCREMENT PRIMARY KEY,
    sql_id VARCHAR(255) NOT NULL,
    sql_content TEXT NOT NULL
);

CREATE TABLE method_sql_mappings (
    id INT AUTO_INCREMENT PRIMARY KEY,
    method_id INT NOT NULL,
    sql_id INT NOT NULL,
    FOREIGN KEY (method_id) REFERENCES java_methods(id),
    FOREIGN KEY (sql_id) REFERENCES sql_mappings(id)
);

 

디렉토리 탐색 및 파일 읽기

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class DirectoryReader {
    public static List<File> listFiles(String directoryName) {
        File directory = new File(directoryName);
        List<File> resultList = new ArrayList<>();

        File[] fList = directory.listFiles();
        if (fList != null) {
            for (File file : fList) {
                if (file.isFile()) {
                    resultList.add(file);
                } else if (file.isDirectory()) {
                    resultList.addAll(listFiles(file.getAbsolutePath()));
                }
            }
        }
        return resultList;
    }

    public static String readFileContent(String filePath) throws IOException {
        return new String(Files.readAllBytes(Paths.get(filePath)));
    }
}

 

Java 소스 코드 파싱

import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class JavaSourceParser {
    public static Map<String, String> parseJavaFile(String filePath) throws IOException {
        FileInputStream in = new FileInputStream(filePath);
        CompilationUnit cu = JavaParser.parse(in);
        Map<String, String> methodMap = new HashMap<>();

        cu.accept(new VoidVisitorAdapter<Void>() {
            @Override
            public void visit(MethodDeclaration md, Void arg) {
                super.visit(md, arg);
                methodMap.put(md.getNameAsString(), md.getDeclarationAsString());
            }
        }, null);

        return methodMap;
    }
}

 

SQL Map 파일 파싱

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SqlMapParser {
    public static Map<String, String> parseSqlMap(String content) {
        Map<String, String> sqlMap = new HashMap<>();
        Pattern pattern = Pattern.compile("<select id="(.*?)".*?>(.*?)</select>", Pattern.DOTALL);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            String id = matcher.group(1);
            String sql = matcher.group(2).trim();
            sqlMap.put(id, sql);
        }

        return sqlMap;
    }
}

 

매핑 관계 추출

import java.util.Map;

public class MappingExtractor {
    public static void extractMappings(Map<String, String> javaMethods, Map<String, String> sqlMappings) {
        for (Map.Entry<String, String> entry : javaMethods.entrySet()) {
            String methodName = entry.getKey();
            String methodContent = entry.getValue();

            for (Map.Entry<String, String> sqlEntry : sqlMappings.entrySet()) {
                if (methodContent.contains(sqlEntry.getKey())) {
                    System.out.println("Method: " + methodName + " is mapped to SQL: " + sqlEntry.getValue());
                }
            }
        }
    }
}

 

MariaDB에 데이터 저장

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;

public class DatabaseSaver {
    private static final String URL = "jdbc:mariadb://localhost:3306/your_database";
    private static final String USER = "your_username";
    private static final String PASSWORD = "your_password";

    public static void saveToDatabase(Map<String, String> javaMethods, Map<String, String> sqlMappings) throws SQLException {
        Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);

        String insertJavaMethod = "INSERT INTO java_methods (method_name, method_content) VALUES (?, ?)";
        String insertSqlMapping = "INSERT INTO sql_mappings (sql_id, sql_content) VALUES (?, ?)";
        String insertMapping = "INSERT INTO method_sql_mappings (method_id, sql_id) VALUES (?, ?)";

        try (PreparedStatement javaMethodStmt = connection.prepareStatement(insertJavaMethod, PreparedStatement.RETURN_GENERATED_KEYS);
             PreparedStatement sqlMappingStmt = connection.prepareStatement(insertSqlMapping, PreparedStatement.RETURN_GENERATED_KEYS);
             PreparedStatement mappingStmt = connection.prepareStatement(insertMapping)) {

            for (Map.Entry<String, String> entry : javaMethods.entrySet()) {
                javaMethodStmt.setString(1, entry.getKey());
                javaMethodStmt.setString(2, entry.getValue());
                javaMethodStmt.executeUpdate();
                int methodId = getGeneratedKey(javaMethodStmt);

                for (Map.Entry<String, String> sqlEntry : sqlMappings.entrySet()) {
                    if (entry.getValue().contains(sqlEntry.getKey())) {
                        sqlMappingStmt.setString(1, sqlEntry.getKey());
                        sqlMappingStmt.setString(2, sqlEntry.getValue());
                        sqlMappingStmt.executeUpdate();
                        int sqlId = getGeneratedKey(sqlMappingStmt);

                        mappingStmt.setInt(1, methodId);
                        mappingStmt.setInt(2, sqlId);
                        mappingStmt.executeUpdate();
                    }
                }
            }
        }
    }

    private static int getGeneratedKey(PreparedStatement stmt) throws SQLException {
        try (var rs = stmt.getGeneratedKeys()) {
            if (rs.next()) {
                return rs.getInt(1);
            }
        }
        throw new SQLException("No generated key obtained.");
    }
}

 

메인 클래스

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        String directoryPath = "your/directory/path";

        try {
            List<File> files = DirectoryReader.listFiles(directoryPath);

            Map<String, String> javaMethods = null;
            Map<String, String> sqlMappings = null;

            for (File file : files) {
                if (file.getName().endsWith(".java")) {
                    javaMethods = JavaSourceParser.parseJavaFile(file.getAbsolutePath());
                } else if (file.getName().endsWith(".xml")) {
                    String content = DirectoryReader.readFileContent(file.getAbsolutePath());
                    sqlMappings = SqlMapParser.parseSqlMap(content);
                }
            }

            MappingExtractor.extractMappings(javaMethods, sqlMappings);
            DatabaseSaver.saveToDatabase(javaMethods, sqlMappings);

        } catch (IOException | SQLException e) {
            e.printStackTrace();
        }
    }
}
반응형