package org.krakenapps.docxcod; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import org.krakenapps.docxcod.util.ZipHelper; public class RptTemplateProcessor { private static final int BUFFER_SIZE = 1024 * 8; private HashMap<String, Object> dataSource = new HashMap<String, Object>(); private FileDocumentSource docSource; private Config docConfig; public RptTemplateProcessor(Config defaultConfig) { docConfig = defaultConfig; // 작업 디렉토리를 로컬에 저장. } public void setDataSource(HashMap<String, Object> rootObj) { dataSource = rootObj; } public void setDocumentSource(FileDocumentSource fileDocumentSource) { docSource = fileDocumentSource; } public RptOutput generateOutput() throws Exception { // 일단 전제 조건들을 체크 (위의 함수들이 제대로 호출되었는가) if (docSource == null) return null; // 체크하고 나서 documentSource 로부터 docx 를 읽고 config.workingDir 아래에 파일 압축을 풀고 // workingDir 아래의 docSource.hashCode() 디렉토리에 docx 압축을 푼다. unzipDocument(); // 압축을 푼 파일을 적절히 바꾸고 // processDocument(); // 적절히 바뀐 파일들을 다시 압축을 하고 압축 푼 파일을 기반으로 RptOutput 객체를 만든다. RptOutput output = makeRptOutput(); // cleanUp 함수를 부른다. cleanUp(); // 만들어둔 RptOutput 객체를 리턴. return output; } private void unzipDocument() { InputStream is; try { is = docSource.getInputStream(); } catch (FileNotFoundException e) { e.printStackTrace(); System.err.println("file open failed"); return; } File baseDir = new File(docConfig.workingDir, Integer.toString(docSource.hashCode())); baseDir.mkdirs(); try { ZipHelper.extract(is, baseDir); } catch (FileNotFoundException e) { e.printStackTrace(); } } //압축하기 private RptOutput makeRptOutput() throws Exception { RptOutput output = new RptOutput(); File outputFile = zipDocument(); if (outputFile != null) { output.setFile(outputFile); return output; } else return null; } public File zipDocument() throws Exception { FileOutputStream fos = null; ZipOutputStream zos = null; File baseDir = new File(Integer.toString(docSource.hashCode())); try { File outputFile = getDocxOutputFile(); fos = new FileOutputStream(outputFile); zos = new ZipOutputStream(fos); List<File> files = new ArrayList<File>(); ZipHelper.getFilesRecursivelyIn(baseDir, files); ZipHelper.archive(zos, files, baseDir); // zipDir(baseDir, Integer.toString(docSource.hashCode()), zos); zos.finish(); return outputFile; } catch (IOException e) { e.printStackTrace(); } finally { if (zos != null) { zos.close(); } if (fos != null) fos.close(); } return null; } private File getDocxOutputFile() throws IOException { return new File(docConfig.workingDir, File.createTempFile("docxcod", ".docx").getName()); } private static void zipDir(File entry, String basePath, ZipOutputStream zos) throws Exception { if (entry.isDirectory()) { File[] fileList = entry.listFiles(); for (int i = 0; i < fileList.length; i++) { zipDir(fileList[i], basePath, zos); } } else { BufferedInputStream bis = null; try { String filePath = entry.getPath(); // zip 안에 들어갈 상대경로를 추출 String zipEntryName = filePath.substring(basePath.length() + 1, filePath.length()); bis = new BufferedInputStream(new FileInputStream(entry)); ZipEntry zEntry = new ZipEntry(zipEntryName); zEntry.setTime(entry.lastModified()); zos.putNextEntry(zEntry); byte[] buffer = new byte[BUFFER_SIZE]; int cnt = 0; while ((cnt = bis.read(buffer, 0, BUFFER_SIZE)) != -1) { zos.write(buffer, 0, cnt); } zos.closeEntry(); } finally { if (bis != null) { bis.close(); } } } } private void cleanUp() { File baseDirName = new File(docConfig.workingDir, Integer.toString(docSource.hashCode())); System.err.println(baseDirName); if (!baseDirName.exists()) return; deleteDir(baseDirName); } public static void deleteDir(File file) { if (file.isDirectory()) { if (file.listFiles().length != 0) { File[] fileList = file.listFiles(); for (int i = 0; i < fileList.length; i++) { deleteDir(fileList[i]); file.delete(); } } else { file.delete(); } } else { file.delete(); } } }