조금 친절한 코드 생성기 3 - 설계 변경 적용(Map)
모하니?/Coding : 2009. 12. 4. 13:40
먼저 인터페이스를 변경합니다. (TDD 프로라면 테스트 코드부터 바꾸셨겠지만, 저는 TDD 아마추어라;;)
Map을 사용하도록 바꿨습니다. 그리고 구현체에서 에러가 날테니 에러를 따라가서(인텔리J에서는 에러나는 코드로 알아서 자동으로 이동해 줍니다. 저는 걍 눈뜨고 손들고 있으면 알아서 코딩할 곳으로 데려다주죠.ㅋ)
코드는 이런식으로 바꼈습니다. 생성자가 한결 깔끔해 졌으며 generateCotroller에서는 settings 맵에서 필요한 값들을 꺼내서 작업하고 있습니다.
문제는
1. Map에 필요한 데이터가 없으면 어쩐댜?
2. 클라이언트 입장에서 필요한 속성이 뭔지 모르겠다.. @_@
일단 계속해서 테스트 코드를 수정합니다.
맵을 만들어서 넘겨줘야 했기 때문에 약간 길어졌지만, 테스트는 무사히 통과했습니다. 그리 큰 설계 변경은 아니지만 이 테스트 덕분에 맘이 편히 할 수 있었네요. 이제는 3번째 방안으로 구현해 보겠습니다.
public interface CodeGenerationService {
void generateController(Map<String, String> settings, Class domainClass) throws CodeGenerationException;
}
void generateController(Map<String, String> settings, Class domainClass) throws CodeGenerationException;
}
Map을 사용하도록 바꿨습니다. 그리고 구현체에서 에러가 날테니 에러를 따라가서(인텔리J에서는 에러나는 코드로 알아서 자동으로 이동해 줍니다. 저는 걍 눈뜨고 손들고 있으면 알아서 코딩할 곳으로 데려다주죠.ㅋ)
public class FreemarkerCodeGenerationService implements CodeGenerationService {
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) {
}
}
}
...
}
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. 클라이언트 입장에서 필요한 속성이 뭔지 모르겠다.. @_@
일단 계속해서 테스트 코드를 수정합니다.
public class FreemarkerCodeGenerationServiceTest {
@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());
}
}
@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번째 방안으로 구현해 보겠습니다.
'모하니? > Coding' 카테고리의 다른 글
스프링이 컴포넌트 스캔을 할 때 클래스로딩을 하지 않는다는 증거 (2) | 2009.12.09 |
---|---|
조금 친절한 코드 생성기 7(일단 완성) - DAO 생성기 코딩 (0) | 2009.12.04 |
조금 친절한 코드 생성기 6 - 테스트 코드 리팩토링 (0) | 2009.12.04 |
조금 친절한 코드 생성기 5 - 리팩토링 (0) | 2009.12.04 |
조금 친절한 코드 생성기 4 - 설계 변경 적용(인터페이스) (0) | 2009.12.04 |
조금 친절한 코드 생성기 3 - 설계 변경 적용(Map) (0) | 2009.12.04 |
조금 친절한 코드 생성기 2 - 설계 변경 (0) | 2009.12.04 |
조금 친절한 코드 생성기 1 - 구상 (0) | 2009.12.04 |
불친절한 코드 생성기 5(일단 끝) - 프리마커 기반 코드 생성기 만들기 (2) | 2009.12.03 |
불친절한 코드 생성기 4 - 템플릿 만들기 (0) | 2009.12.03 |
불친절한 코드 생성기 3 - Freemarker 학습 테스트 (0) | 2009.12.03 |