diff --git a/src/main/java/cokr/xit/base/file/FileInfo.java b/src/main/java/cokr/xit/base/file/FileInfo.java index 2c55491..ea0ada3 100644 --- a/src/main/java/cokr/xit/base/file/FileInfo.java +++ b/src/main/java/cokr/xit/base/file/FileInfo.java @@ -5,6 +5,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; +import java.io.OutputStream; import java.net.URLConnection; import java.util.ArrayList; import java.util.Arrays; @@ -24,64 +25,119 @@ import cokr.xit.foundation.Assert; * @author mjkhan */ public class FileInfo { - /**objs를 대시(-)로 연결하여 infoKey를 반환한다. - * @param objs 아이디로 쓰이는 필드값 - * @return infoKey + /**파일의 관계 정보 + * @author mjkhan */ - public static String InfoKey(Object... objs) { - if (Assert.isEmpty(objs)) - return ""; + public static class Relation { + private String infoType; + private String infoKey; + private String subType; + + /**objs를 대시(-)로 연결하여 infoKey를 반환한다. + * @param objs 아이디로 쓰이는 필드값 + * @return infoKey + */ + public static String InfoKey(Object... objs) { + if (Assert.isEmpty(objs)) + return ""; + + return Stream.of(objs) + .filter(obj -> !Assert.isEmpty(obj)) + .map(obj -> obj.toString()) + .collect(Collectors.joining("-")); + } + + /**관계 정보의 유형을 반환한다. + * @return 관계 정보의 유형 + */ + public String getInfoType() { + return infoType; + } + + /**관계 정보의 유형을 설정한다. + * @param infoType 관계 정보의 유형 + * @return 현재 Relation + */ + public Relation setInfoType(String infoType) { + this.infoType = infoType; + return this; + } + + /**관계 정보의 키를 반환한다. + * @return 관계 정보의 키 + */ + public String getInfoKey() { + return infoKey; + } + + /**관계 정보의 키를 설정한다. + * @param infoType 관계 정보의 키를 + * @return 현재 Relation + */ + public Relation setInfoKey(String infoKey) { + this.infoKey = infoKey; + return this; + } + + /**관계 정보의 하위 유형을 반환한다. + * @return 관계 정보의 하위 유형 + */ + public String getSubType() { + return subType; + } + + /**관계 정보의 하위 유형을 설정한다. + * @param infoType 관계 정보의 하위 유형 + * @return 현재 Relation + */ + public Relation setSubType(String subType) { + this.subType = subType; + return this; + } - return Stream.of(objs) - .filter(obj -> !Assert.isEmpty(obj)) - .map(obj -> obj.toString()) - .collect(Collectors.joining("-")); + /**관계 정보의 유형, 키, 하위 유형을 fileInfo에 설정한다. + * @param fileInfo FileInfo + */ + public void setInfo(FileInfo fileInfo) { + fileInfo.setInfoType(Assert.notEmpty(infoType, "infoType")); + fileInfo.setInfoKey(Assert.notEmpty(infoKey, "infoKey")); + fileInfo.setSubType(subType); + } } /**파일 데이터 홀더 * @author mjkhan */ public static class DataHolder { - private String infoType; - private String infoKey; + private Relation relation; private String filename; private byte[] data; /**새 DataHolder를 생성한다. - * @param infoType 관계 정보 유형 - * @param infoKey 관계 정보 키 + * @param relation 관계 정보 * @param filename 파일 이름 * @param data 파일 데이터 */ - public DataHolder(String infoType, String infoKey, String filename, byte[] data) { - this.infoType = infoType; - this.infoKey = infoKey; + public DataHolder(Relation relation, String filename, byte[] data) { + this.relation = relation; this.filename = filename; this.data = data != null ? data : new byte[0]; } /**새 DataHolder를 생성한다. - * @param infoType 관계 정보 유형 - * @param infoKey 관계 정보 키 + * @param relation 관계 정보 * @param filename 파일 이름 * @param data 파일 데이터 */ - public DataHolder(String infoType, String infoKey, String filename, String data) { - this(infoType, infoKey, filename, !Assert.isEmpty(data) ? Base64.getDecoder().decode(data.getBytes()) : null); + public DataHolder(Relation relation, String filename, String data) { + this(relation, filename, !Assert.isEmpty(data) ? Base64.getDecoder().decode(data.getBytes()) : null); } - /**관계 정보 유형을 반환한다. - * @return 관계 정보 유형 + /**관계 정보를 반환한다. + * @return 관계 정보 */ - public String getInfoType() { - return infoType; - } - - /**관계 정보 키를 반환한다. - * @return 관계 정보 키 - */ - public String getInfoKey() { - return infoKey; + public Relation getRelation() { + return relation; } /**파일이름을 반환한다. @@ -121,14 +177,11 @@ public class FileInfo { */ public static class Factory extends AbstractComponent { /**주어진 관계 정보 유형과 키, 그리고 파일로 FileInfo 목록을 생성한다. - * @param infoType 관계 정보 유형 - * @param infoKey 관계 정보 키 + * @param relation 관계 정보 * @param files 파일 * @return FileInfo 목록 */ - public List createFileInfos(String infoType, String infoKey, Iterable files) { - notEmpty(infoType, "infoType"); - notEmpty(infoKey, "infoKey"); + public List createFileInfos(Relation relation, Iterable files) { if (isEmpty(files)) return Collections.emptyList(); @@ -138,8 +191,7 @@ public class FileInfo { if (file == null) continue; FileInfo info = new FileInfo(); - info.setInfoType(infoType); - info.setInfoKey(infoKey); + relation.setInfo(info); String filename = file.getName(); info.setName(filename); InputStream input = new FileInputStream(file); @@ -158,23 +210,21 @@ public class FileInfo { } /**주어진 관계 정보 유형과 키, 그리고 파일로 FileInfo 목록을 생성한다. - * @param infoType 관계 정보 유형 - * @param infoKey 관계 정보 키 + * @param relation 관계 정보 * @param files 파일 * @return FileInfo 목록 */ - public List createFileInfos(String infoType, String infoKey, File... files) { - return createFileInfos(infoType, infoKey, Arrays.asList(files)); + public List createFileInfos(Relation relation, File... files) { + return createFileInfos(relation, Arrays.asList(files)); } /**주어진 관계 정보 유형과 키, 그리고 파일로 FileInfo을 생성한다. - * @param infoType 관계 정보 유형 - * @param infoKey 관계 정보 키 + * @param relation 관계 정보 * @param file 파일 * @return FileInfo */ - public FileInfo create(String infoType, String infoKey, File file) { - List fileInfos = createFileInfos(infoType, infoKey, file); + public FileInfo create(Relation relation, File file) { + List fileInfos = createFileInfos(relation, file); return !fileInfos.isEmpty() ? fileInfos.get(0) : null; } @@ -191,8 +241,7 @@ public class FileInfo { if (holder == null) continue; FileInfo info = new FileInfo(); - info.setInfoType(holder.infoType); - info.setInfoKey(holder.infoKey); + holder.getRelation().setInfo(info); String filename = holder.getFilename(); info.setName(filename); InputStream input = new ByteArrayInputStream(holder.data); @@ -327,9 +376,11 @@ public class FileInfo { /**관계 정보 기준 하위분류를 설정한다. 프로그램에서 정의 * @param subType 관계 정보 기준 하위분류 + * @return 현재 FileInfo */ - public void setSubType(String subType) { + public FileInfo setSubType(String subType) { this.subType = subType; + return this; } /**파일이름을 반환한다. @@ -530,18 +581,18 @@ public class FileInfo { return this; } - /**FileInfo의 경로로 File을 저장한다. + /**OutputStream으로 File의 데이터를 저장한다. + * @param out OutputStream * @return 저장 여부 *
  • 저장됐으면 true
  • *
  • 그렇지 않으면 false
  • *
*/ - public boolean write() { - if (Assert.isEmpty(path)) return false; + public boolean write(OutputStream out) { + if (Assert.isEmpty(path) || out == null) return false; try ( InputStream in = input; - FileOutputStream out = new FileOutputStream(path); ) { FileCopyUtils.copy(in, out); return true; @@ -550,6 +601,20 @@ public class FileInfo { } } + /**FileInfo의 경로로 File을 저장한다. + * @return 저장 여부 + *
  • 저장됐으면 true
  • + *
  • 그렇지 않으면 false
  • + *
+ */ + public boolean write() { + try (FileOutputStream out = new FileOutputStream(path)) { + return write(out); + } catch(Exception e) { + throw Assert.runtimeException(e); + } + } + /**FileInfo의 File을 삭제한다. * @return 삭제 여부 *
  • 삭제됐으면 true
  • diff --git a/src/main/java/cokr/xit/base/file/web/FileController.java b/src/main/java/cokr/xit/base/file/web/FileController.java index 68c1f7f..7ea1534 100644 --- a/src/main/java/cokr/xit/base/file/web/FileController.java +++ b/src/main/java/cokr/xit/base/file/web/FileController.java @@ -51,6 +51,7 @@ public class FileController extends AbstractController { /**업로드한 파일을 주어진 관계 정보의 파일로 등록한다. * @param infoType 관계 정보 유형 * @param infoKey 관계 정보 키 + * @param infoKey 하위 정보 유형 * @param uploads 업로드 파일 * @return ModelAndView *
    {
    @@ -62,9 +63,13 @@ public class FileController extends AbstractController {
     	public ModelAndView create(
     		String infoType,
     		String infoKey,
    +		String subType,
     		MultipartFile[] uploads
     	) {
    -		List files = new FileInfoFactory().makeFileInfos(infoType, infoKey, uploads);
    +		List files = new FileInfoFactory().makeFileInfos(
    +			new FileInfo.Relation().setInfoType(infoType).setInfoKey(infoKey).setSubType(subType),
    +			uploads
    +		);
     		int affected = fileService.create(files);
     		return new ModelAndView("jsonView")
     			.addObject("affected", affected)
    diff --git a/src/main/java/cokr/xit/base/file/web/FileInfoFactory.java b/src/main/java/cokr/xit/base/file/web/FileInfoFactory.java
    index 76a2f3f..d86e5b1 100644
    --- a/src/main/java/cokr/xit/base/file/web/FileInfoFactory.java
    +++ b/src/main/java/cokr/xit/base/file/web/FileInfoFactory.java
    @@ -14,12 +14,11 @@ import cokr.xit.base.file.FileInfo;
      */
     public class FileInfoFactory extends FileInfo.Factory {
     	/**주어진 관계 정보 유형과 키, 그리고 업로드 파일로 FileInfo 목록을 생성한다.
    -	 * @param infoType 관계 정보 유형
    -	 * @param infoKey 관계 정보 키
    +	 * @param relation 관계 정보
     	 * @param multipartFiles 업로드 파일
     	 * @return FileInfo 목록
     	 */
    -	public List makeFileInfos(String infoType, String infoKey, Iterable multipartFiles) {
    +	public List makeFileInfos(FileInfo.Relation relation, Iterable multipartFiles) {
     		if (isEmpty(multipartFiles))
     			return Collections.emptyList();
     
    @@ -35,8 +34,7 @@ public class FileInfoFactory extends FileInfo.Factory {
     				info.setSize(file.getSize());
     				info.setInputStream(file.getInputStream());
     				info.setSortOrder(result.size());
    -				info.setInfoType(infoType);
    -				info.setInfoKey(infoKey);
    +				relation.setInfo(info);
     				result.add(info);
     			} catch (Exception e) {
     				throw runtimeException(e);
    @@ -45,23 +43,21 @@ public class FileInfoFactory extends FileInfo.Factory {
     	}
     
     	/**주어진 관계 정보 유형과 키, 그리고 업로드 파일로 FileInfo 목록을 생성한다.
    -	 * @param infoType 관계 정보 유형
    -	 * @param infoKey 관계 정보 키
    +	 * @param relation 관계 정보
     	 * @param multipartFiles 업로드 파일
     	 * @return FileInfo 목록
     	 */
    -	public List makeFileInfos(String infoType, String infoKey, MultipartFile... multipartFiles) {
    -		return makeFileInfos(infoType, infoKey, Arrays.asList(multipartFiles));
    +	public List makeFileInfos(FileInfo.Relation relation, MultipartFile... multipartFiles) {
    +		return makeFileInfos(relation, Arrays.asList(multipartFiles));
     	}
     
     	/**주어진 관계 정보 유형과 키, 그리고 업로드 파일로 FileInfo을 생성한다.
    -	 * @param infoType 관계 정보 유형
    -	 * @param infoKey 관계 정보 키
    +	 * @param relation 관계 정보
     	 * @param multipartFile 업로드 파일
     	 * @return FileInfo
     	 */
    -	public FileInfo make(String infoType, String infoKey, MultipartFile multipartFile) {
    -		List files = makeFileInfos(infoType, infoKey, multipartFile);
    +	public FileInfo make(FileInfo.Relation relation, MultipartFile multipartFile) {
    +		List files = makeFileInfos(relation, multipartFile);
     		return !files.isEmpty() ? files.get(0) : null;
     	}
     }
    \ No newline at end of file
    diff --git a/src/test/java/cokr/xit/base/file/service/FileServiceTest.java b/src/test/java/cokr/xit/base/file/service/FileServiceTest.java
    index ef56e57..c568e32 100644
    --- a/src/test/java/cokr/xit/base/file/service/FileServiceTest.java
    +++ b/src/test/java/cokr/xit/base/file/service/FileServiceTest.java
    @@ -27,8 +27,9 @@ public class FileServiceTest extends TestSupport {
     		String infoType = "00";
     		String infoKey = "info-key-00";
     		FileQuery req = new FileQuery().setInfoType(infoType);
    +		FileInfo.Relation relation = new FileInfo.Relation().setInfoType(infoType).setInfoKey(infoKey);
     
    -		List fileInfos = new FileInfo.Factory().createFileInfos(infoType, infoKey, files);
    +		List fileInfos = new FileInfo.Factory().createFileInfos(relation, files);
     		Assertions.assertTrue(service.create(fileInfos) > 0);
     		fileInfos.forEach(System.out::println);
     
    diff --git a/src/test/resources/sql/mapper/base/file-mapper.xml b/src/test/resources/sql/mapper/base/file-mapper.xml
    index b81ec97..111be64 100644
    --- a/src/test/resources/sql/mapper/base/file-mapper.xml
    +++ b/src/test/resources/sql/mapper/base/file-mapper.xml
    @@ -20,7 +20,7 @@
     
     
     SELECT INF_TYPE
    -     , CONCAT('D://workspace/xit/base/files/', DIR, TO_CHAR(CURRENT_DATE, 'YYYY/MM/DD/')) DIR
    +     , CONCAT('C://workspace/xit/base/files/', DIR, TO_CHAR(CURRENT_DATE, 'YYYY/MM/DD/')) DIR
       FROM (
     	   SELECT '00' INF_TYPE, 'attachment/' DIR UNION
     	   SELECT '01' INF_TYPE, 'document/' DIR UNION
    @@ -29,12 +29,12 @@
     
     
     
    -SELECT A.*, REPLACE(FILE_PATH, 'D://workspace/xit/base', '') URL
    +SELECT A.*, REPLACE(FILE_PATH, 'C://workspace/xit/base', '') URL
       FROM TBL_FILE A
      WHERE FILE_ID IN (#{fileID})
      ORDER BY FILE_ID
     
    -SELECT A.*, REPLACE(FILE_PATH, 'D://workspace/xit/base', '') URL
    +SELECT A.*, REPLACE(FILE_PATH, 'C://workspace/xit/base', '') URL
       FROM TBL_FILE A
     
       AND A.INF_TYPE = #{infoType}