이번에도;; 새 기능을 추가하려다보니까 기존의 코드에서 분리 시켜야 새 메서드에서 재사용 할 수 있는 부분들이 보이길래, 기존의 코드를 쪼개서 리팩토링 했습니다. 그러면서 일부 기능은 프리마커 코드 생성기에서 컨트롤러 설정 부분으로 이동시켰습니다. 아무래도, 최종적으로 생성해야 할 장소와, 파일에 대한 정보는 설정 객체가 받은 기본 정보를 토대로 가공해서 코드 생성기 쪽으로 전달해주는게 나을 것 같아서요.

    public void generateController(ControllerSettings settings) throws CodeGenerationException {
        generatedFiles = new Stack<File>();
        FreemarkerControllerSetting fcSettings = (FreemarkerControllerSetting)settings;
        generateDirs(fcSettings.getDestinationDirs());
        generateCode(fcSettings.getTemplateFileName(), fcSettings.getModelMap(), fcSettings.getDestinationFile());
    }

이 부분이 이전 글에서 엄청나게 길었던, 코드 생성코드입니다.
1. 먼저 생성된 파일 정보를 저장해둘 컬렉션을 초기화 합니다.
2. 프리마커 컨트롤러 설정으로 타입을 변환하고
3. 최종 코드가 생성될 디렉토리를 만듭니다.
4. 최종 코드를 만듭니다.

3, 4 번이 핵심 기능인데, 이 기능들은 다른 코드 생성 메서드에서도 사용할 수 있어야 하기 때문에 기존 코드에서 분리했습니다.

그리고 기존 코드 생성기에 있던 코드 중에 일부를 컨트롤러 설정 쪽으로 옮겼습니다.

public class FreemarkerControllerSetting implements ControllerSettings {

    private String module;
    private String templateFileName;
    private String destinationDirPath;
    private Class domainClass;

    private Map<String, String> modelMap;
    private File destinationFile;
    private List<File> destinationDirs;

    public FreemarkerControllerSetting(String module, String templateFileName, String destinationDirPath, Class domainClass) {
        this.module = module;
        this.templateFileName = templateFileName;
        this.destinationDirPath = destinationDirPath;
        this.domainClass = domainClass;

        modelMap = new HashMap<String,  String>();
        String className = domainClass.getSimpleName();
        modelMap.put("module", module);
        modelMap.put("domainClass", className);
        modelMap.put("domainName", ClassUtils.getShortNameAsProperty(domainClass));

        destinationFile = new File(destinationDirPath + "/" + module + "/" + domainClass.getSimpleName() + "Controller.java");

        destinationDirs = new ArrayList<File>();
        destinationDirs.add(new File(destinationDirPath));
        destinationDirs.add(new File(destinationDirPath + "/" + module));
    }

    public String getModule() {
        return module;
    }
    public String getTemplateFileName() {
        return templateFileName;
    }
    public String getDestinationDirPath() {
        return destinationDirPath;
    }
    public Class getDomainClass() {
        return domainClass;
    }

    public Map<String, String> getModelMap() {
        return modelMap;
    }
    public File getDestinationFile() {
        return destinationFile;
    }
    public List<File> getDestinationDirs() {
        return destinationDirs;
    }
}

1. 프리마커 Template을 가공할 때 사용할 modelMap.
2. 코드가 될 파일.
3. 코드가 담길 폴더들(기본 목적 폴더 + 모듈 폴더)

아 그리고 은근슬쩍 수정한 것이 있는데, domainClass를 generateContoller() 호출시에 넘겨주지 않고, ControllerSettings에 포함시켰습니다. 이녀석도 생성시에 필요한 설정 정보에 해당하는 건데 왜 이전 설계 변경할 때 빼먹었는지 모르겠네요. @_@;;

자 이번엔 진짜로 새 기능을 만들어 볼까요;;

아차차.. 테스트는 잘 돌아갑니다. 리팩토링 중에 중간 중간 돌려서 제대로 돌아가는지 확인할 수 있어서 좋았습니다. 코드를 엄청 많이 바꿨는데도 맘이 놓이네요. 안심이에요.