import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.zip.InflaterInputStream;
@RequestMapping(value = "/importDoc", method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> importDoc(@RequestParam("file") MultipartFile importFile) throws IOException {
@Controller
public class ImportController {
static String ROOT_PATH = "C:\\workspace\\synapEditorsample\\out\\artifacts\\synapEditorsample_war_exploded";
static String DOC_UPLOAD_DIR = "uploads\\docs";
static String OUTPUT_DIR = "uploads\\output";
@RequestMapping(value = "/importDoc", method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> importDoc(@RequestParam("file") MultipartFile importFile) throws IOException {
String fileName = importFile.getOriginalFilename();
String uploadPath = ROOT_PATH + File.separator + DOC_UPLOAD_DIR;
File uploadDir = new File(uploadPath);
if(!uploadDir.exists()) {
uploadDir.mkdirs();
}
}
byte[] bytes = new byte[0];
try {
bytes = importFile.getBytes();
} catch (IOException e) {
e.printStackTrace();
}
}
Path inputFilePath = Paths.get(uploadPath + File.separator + fileName);
try {
Files.write(inputFilePath, bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
Calendar cal = Calendar.getInstance();
String yearMonth = String.format("%04d%02d", cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1);
// 파일별로 변환결과를 저장할 경로 생성
String uuid = UUID.randomUUID().toString();
File worksDir = new File(ROOT_PATH + File.separator + OUTPUT_DIR + File.separator + yearMonth + File.separator + uuid);
if(!worksDir.exists()) {
worksDir.mkdirs();
}
}
// 문서 변환
executeConverter(inputFilePath.toAbsolutePath().toString(), worksDir.getAbsolutePath());
// 변환이 끝난 원본파일은 삭제한다.
Files.delete(inputFilePath);
Integer[] serializedData = serializePbData(worksDir + File.separator + "document.word.pb");
Files.delete(Paths.get(worksDir + File.separator + "document.word.pb"));
Map<String, Object> map = new HashMap<>();
map.put("serializedData", serializedData);
// 브라우저에서 접근가능한 경로를 importPath에 담아서 넘겨줍니다.
map.put("importPath", "uploads/output/" + yearMonth + "/" + uuid);
return map;
}
protected public static int executeConverter(String inputFilePath, String outputPathoutputFilePath) {
String SEDOC_CONVERT_DIR = "C:\\sedocConverter\\sedocConverter.exe";
String FONT_DIR = "C:\\sedocConverter\\sedocConverter\\fonts";
String TEMP_DIR = "C:\\sedocConverter\\sedocConverter\\tmp";
File tempDir = new File(TEMP_DIR);
if(!tempDir.exists()) {
tempDir.mkdirs();
}
}
File fontDir = new File(FONT_DIR);
if(!fontDir.exists()) {
fontDir.mkdirs();
} }
// 변환 명령 구성 String[] cmd = {SEDOC_CONVERT_DIR, "-f", FONT_DIR, inputFilePath, outputPathoutputFilePath, TEMP_DIR};
try {
Timer t = new Timer();
Process proc = Runtime.getRuntime().exec(cmd);
TimerTask killer = new TimeoutProcessKiller(proc);
t.schedule(killer, 20000); // 20초 (변환이 20초 안에 완료되지 않으면 프로세스 종료)
int exitValue = proc.waitFor();
killer.cancel();
return exitValue;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
public Integer[] serializePbData(String pbFilePath) throws IOException {
List<Integer> serializedData = new ArrayList<Integer>();
FileInputStream fis = new FileInputStream(pbFilePath);
Integer[] data = null;
fis.skip(16);
InflaterInputStream ifis = new InflaterInputStream(fis);
byte[] buffer = new byte[1024];
int len = -1;
while ((len = ifis.read(buffer)) != -1) {
for (int i = 0; i < len; i++) {
serializedData.add(buffer[i] & 0xFF);
}
}
data = serializedData.toArray(new Integer[serializedData.size()]);
ifis.close();
fis.close();
return data;
}
private static class TimeoutProcessKiller extends TimerTask {
private Process p;
public TimeoutProcessKiller(Process p) {
this.p = p;
}
@Override
public void run() {
p.destroy();
}
}
} |