조금 친절한 코드 생성기 3 - 설계 변경 적용(Map)
먼저 인터페이스를 변경합니다. (TDD 프로라면 테스트 코드부터 바꾸셨겠지만, 저는 TDD 아마추어라;;)
void generateController(Map<String, String> settings, Class domainClass) throws CodeGenerationException;
}
Map을 사용하도록 바꿨습니다. 그리고 구현체에서 에러가 날테니 에러를 따라가서(인텔리J에서는 에러나는 코드로 알아서 자동으로 이동해 줍니다. 저는 걍 눈뜨고 손들고 있으면 알아서 코딩할 곳으로 데려다주죠.ㅋ)
private Configuration configuration;
private Stack<File> createdFilesWhileGenerateController;
private Stack<File> createdFilesWhileGenerateDao;
public FreemarkerCodeGenerationService(Configuration configuration){
this.configuration = configuration;
}
public void generateController(Map<String, String> settings, Class domainClass) throws CodeGenerationException {
createdFilesWhileGenerateController = new Stack<File>();
String module = settings.get("module");
String templateFileName = settings.get("templateFileName");
String destinationDirName = settings.get("destinationDirName");
//TODO check not null
Map<String, String> map = new HashMap<String, String>();
String className = domainClass.getSimpleName();
map.put("module", module);
map.put("domainClass", className);
map.put("domainName", ClassUtils.getShortNameAsProperty(domainClass));
Template controllerTemplate = null;
try {
controllerTemplate = configuration.getTemplate(templateFileName);
} catch (IOException e) {
throw new CodeGenerationException("template file loading fail with [" + templateFileName + "]", e);
}
File desticationFolder = new File(destinationDirName);
boolean created = desticationFolder.mkdir();
if(created)
createdFilesWhileGenerateController.push(desticationFolder);
desticationFolder = new File(destinationDirName + "/" + module);
created = desticationFolder.mkdir();
if(created)
createdFilesWhileGenerateController.push(desticationFolder);
File destinationFile = new File(destinationDirName + "/" + module + "/" + className + "Controller.java");
FileWriter writer = null;
try {
writer = new FileWriter(destinationFile);
controllerTemplate.process(map, writer);
writer.flush();
writer.close();
System.out.println(destinationFile.getAbsolutePath() + " created");
createdFilesWhileGenerateController.push(destinationFile);
} catch (IOException e) {
throw new CodeGenerationException("destincation file creation fail", e);
} catch (TemplateException e) {
throw new CodeGenerationException("template processing fail", e);
} finally {
try {
writer.close();
} catch (IOException e) {
}
}
}
...
}
코드는 이런식으로 바꼈습니다. 생성자가 한결 깔끔해 졌으며 generateCotroller에서는 settings 맵에서 필요한 값들을 꺼내서 작업하고 있습니다.
문제는
1. Map에 필요한 데이터가 없으면 어쩐댜?
2. 클라이언트 입장에서 필요한 속성이 뭔지 모르겠다.. @_@
일단 계속해서 테스트 코드를 수정합니다.
@Test
public void generationTst() throws IOException {
Configuration configuration = new Configuration();
configuration.setObjectWrapper(new DefaultObjectWrapper());
configuration.setDirectoryForTemplateLoading(new FileSystemResource("doc/template").getFile());
assertNotNull(configuration);
FreemarkerCodeGenerationService service = new FreemarkerCodeGenerationService(configuration);
Map<String, String> settings = new HashMap<String, String>();
settings.put("module", "test");
settings.put("templateFileName", "controller.ftl");
settings.put("destinationDirName", "test/springsprout/modules");
service.generateController(settings, Study.class);
assertTrue(new File("test/springsprout/modules/test/StudyController.java").exists());
service.deleteController();
assertFalse(new File("test/springsprout/modules/test/StudyController.java").exists());
}
}
맵을 만들어서 넘겨줘야 했기 때문에 약간 길어졌지만, 테스트는 무사히 통과했습니다. 그리 큰 설계 변경은 아니지만 이 테스트 덕분에 맘이 편히 할 수 있었네요. 이제는 3번째 방안으로 구현해 보겠습니다.