불친절한 코드 생성기 5(일단 끝) - 프리마커 기반 코드 생성기 만들기
서비스 인터페이스를 만듭니다.
void generateController(String module, Class domainClass) throws CodeGenerationException;
}
일단은 컨트롤러만 생성할테니, 컨틀로러 생성 메서드만 만듭니다. 이때 만들어질 컨트롤러가 속할 module의 이름과 어떤 도메인 클래스에 대한 컨트롤러인지 알려줍니다.
문제가 생기면 RuntimeException을 던집니다. 자, 이제 이 인터페이스를 프리마커 기반으로 구현할 시간이군요.
private Configuration configuration;
private Template controllerTemplate;
private String destinationDir;
private Stack<File> createdFilesWhileGenerateController;
public FreemarkerCodeGenerationService(Configuration configuration, String controllerTemplateName, String destinationDir){
this.destinationDir = destinationDir;
this.configuration = configuration;
try {
this.controllerTemplate = configuration.getTemplate(controllerTemplateName);
} catch (IOException e) {
throw new CodeGenerationException("template file loading fail with [" + controllerTemplateName + "]", e);
}
}
public void generateController(String module, Class domainClass) throws CodeGenerationException {
createdFilesWhileGenerateController = new Stack<File>();
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));
File desticationFolder = new File(destinationDir);
boolean created = desticationFolder.mkdir();
if(created)
createdFilesWhileGenerateController.push(desticationFolder);
desticationFolder = new File(destinationDir + "/" + module);
created = desticationFolder.mkdir();
if(created)
createdFilesWhileGenerateController.push(desticationFolder);
File destinationFile = new File(destinationDir + "/" + 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) {
}
}
}
...
public void deleteController() {
while(!createdFilesWhileGenerateController.empty()){
File file = createdFilesWhileGenerateController.pop();
System.out.println(file.getAbsolutePath());
boolean deleted = file.delete();
if(deleted)
System.out.println(file.getAbsolutePath() + " deleted");
else
System.out.println(file.getAbsolutePath() + " not deleted");
}
}
}
왠지 좀.. 부끄럽네요. 으흑;;
저 클래스에 필요한 속성(configuration 타입 객체, 템플릿 파일들이 들어있는 위치, 컨틀롤러 템플릿 파일)을 봄싹 프로젝트에 맞게 기본으로 가지고 있는 클래스를 하나 만듭니다.
private static final String DESTINATION_DIR = "src/springsprout/modules";
private static final String CONTROLLER_TEMPLATE_NAME = "controller.ftl";
public SpringSproutCodeGenerationService(Configuration configuration) {
super(configuration, CONTROLLER_TEMPLATE_NAME, DESTINATION_DIR);
}
}
이제 테스트를 해봅니다.
@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 SpringSproutCodeGenerationService(configuration);
service.setDestinationDir("test/springsprout/modules");
service.generateController("test", Study.class);
assertTrue(new File("test/springsprout/modules/test/StudyController.java").exists());
service.deleteController();
assertFalse(new File("test/springsprout/modules/test/StudyController.java").exists());
}
}
끝...