<JavaScript>
그리드 복사 행 붙여넣기 : extension.module.js
/**
* 붙여넣기
* @param {cpr.core.AppInstance} app
* @param {common.AppKit} appKit
* @param {#grid} psGridId
*/
"7" : function(app, appKit, psGridId){
/** @type cpr.controls.Grid */
var vcGrid = app.lookup(psGridId);
var Index = appKit.Grid.getIndex(app, vcGrid.id);
/** @type String */
var vsInfo = vcGrid.dataSet.info;
//pk컬럼 배열
var vaPkColumns = [];
if(!ValueUtil.isNull(vsInfo)){
vaPkColumns = vsInfo.split(",");
}
/** @type Array */
var vaPasteRows = [];
if(!ValueUtil.isNull(vcGrid._copyRowData)){
/** @type cpr.data.RowConfigInfo */
var vaCopyRowData = vcGrid._copyRowData;
vaCopyRowData.forEach(function(/* cpr.data.RowConfigInfo */rowData, i){
vaPkColumns.forEach(function(/* String */psColumn){
//PK컬럼을 rowData 객체에서 제거
delete rowData[psColumn];
});
// sylee 추가(프로그램관리, 광고소재, 운행소재에서 붙여넣기 시)
if(vcGrid.id == "BS_PGM_INPUT_G10" || vcGrid.id == "BS_CM_MTRL_INPUT_G01" || vcGrid.id == "BS_PLAY_MTRL_INPUT_G01"){
rowData.clipYn = "";
rowData.clipYn1 = "";
rowData.clipYn2 = "";
rowData.clipYn3 = "";
rowData.arcYn = "";
}
var voRow = vcGrid.dataSet.getRow(Index+i);
if(!ValueUtil.isNull(voRow)){
voRow.setRowData(rowData);
vaPasteRows.push(voRow);
}else{
var voInsertRow = vcGrid.dataSet.insertRowData(Index+i, true, rowData);
vaPasteRows.push(voInsertRow);
}
});
}
var voOption = {
"gridId" : vcGrid.id,
"pasteRows" : vaPasteRows
}
//붙여넣기 이벤트 디스패치
app.dispatchEvent(new cpr.events.CUIEvent("gridKitRowPaste", voOption));
}
EOM 시간 계산 : common.module.js
/**
* 시작시각, 운행길이로 종료시각을 가져온다
* @param {string} psBroadHour 방송시
* @param {string} psBroadMin 방송분
* @param {string} psBroadSec 방송초
* @param {string} psBroadFrm 방송프레임
* @param {string} psBroadRunHour 운행시
* @param {string} psBroadRunMin 운행분
* @param {string} psBroadRunSec 운행초
* @param {string} psBroadRunFrm 운행프레임
* @return {string} 종료시각
* @since 2020-05-06
* @author sylee
*/
AppKit.prototype.calcEom = function(psBroadHour, psBroadMin, psBroadSec, psBroadFrm, psBroadRunHour, psBroadRunMin, psBroadRunSec, psBroadRunFrm, psFrameRate) {
var vnBroadHour = Number(psBroadHour) + Number(psBroadRunHour);
var vnBroadMin = Number(psBroadMin) + Number(psBroadRunMin);
var vnBroadSec = Number(psBroadSec) + Number(psBroadRunSec);
var vnBroadFrm = Number(psBroadFrm) + Number(psBroadRunFrm);
vnBroadHour = vnBroadHour + Math.floor(vnBroadMin / 60);
vnBroadMin = (vnBroadMin % 60) + Math.floor(vnBroadSec / 60);
// 2020.09.10 프레임 크기에 따른 시간 계산 구분 추가
if (psFrameRate == "60") {
vnBroadSec = (vnBroadSec % 60) + Math.floor(vnBroadFrm / 60);
vnBroadFrm = (vnBroadFrm % 60);
} else {
vnBroadSec = (vnBroadSec % 60) + Math.floor(vnBroadFrm / 30);
vnBroadFrm = (vnBroadFrm % 30);
}
if(vnBroadSec >= 60) {
vnBroadSec = (vnBroadSec % 60);
vnBroadMin++;
}
if(vnBroadMin >= 60) {
vnBroadMin = (vnBroadMin % 60);
vnBroadHour++;
}
var vsResult = "";
if(vnBroadHour < 10) {
vsResult += "0" + vnBroadHour;
} else {
vsResult += String(vnBroadHour);
}
if(vnBroadMin < 10) {
vsResult += "0" + vnBroadMin;
} else {
vsResult += String(vnBroadMin);
}
if(vnBroadSec < 10) {
vsResult += "0" + vnBroadSec;
} else {
vsResult += String(vnBroadSec);
}
if(vnBroadFrm < 10) {
vsResult += "0" + vnBroadFrm;
} else {
vsResult += String(vnBroadFrm);
}
return vsResult;
}
<Java>
EOM 시간 계산 : CommonUtil.java
public static String calPlayTime(String vs24Yn, String vsType, String vsPlayTime, String vsDuration) throws Exception {
int iHH1, iHH2, iMM1, iMM2, iSS1, iSS2, iFF1, iFF2;
Long iCalFrame1, iCalFrame2, iRevFrame, iCalFrame;
int iHH = 0, iMM = 0, iSS = 0, iFF = 0;
String rtnPlayTime = "";
if (vsPlayTime == null || "".equals(vsPlayTime)) {
vsPlayTime = "00000000";
}
if (vsDuration == null || "".equals(vsDuration)) {
vsDuration = "00000000";
}
if (vsType != null && "DF".equals(vsType)) {
iHH1 = Integer.parseInt(vsPlayTime.substring(0, 2));
iMM1 = Integer.parseInt(vsPlayTime.substring(2, 4)) + (iHH1 * 60);
iSS1 = Integer.parseInt(vsPlayTime.substring(4, 6));
iFF1 = Integer.parseInt(vsPlayTime.substring(6, 8));
iHH2 = Integer.parseInt(vsDuration.substring(0, 2));
iMM2 = Integer.parseInt(vsDuration.substring(2, 4)) + (iHH2 * 60);
iSS2 = Integer.parseInt(vsDuration.substring(4, 6));
iFF2 = Integer.parseInt(vsDuration.substring(6, 8));
iCalFrame1 = (long)(iMM1 * 1798 + ((int)(iMM1 / 10) * 2) + (iSS1 * 30) + iFF1 + 1);
iCalFrame2 = (long) (iMM2 * 1798 + ((int)(iMM2 / 10) * 2) + (iSS2 * 30) + iFF2 + 1);
iCalFrame = iCalFrame1 + iCalFrame2 - 1;
iMM = (int) (iCalFrame / 1798);
iRevFrame = (long) ((int)(iMM / 10) * 2);
if (((iCalFrame % 1798) - iRevFrame - 1) < 0) {
iRevFrame = (long) ((int)(iMM / 10) * 2);
iCalFrame = (iCalFrame % 1798) + 1798 - iRevFrame - 1;
} else {
iCalFrame = (iCalFrame % 1798) - iRevFrame - 1;
}
iHH = (int)(iMM / 60);
iMM = iMM % 60;
iSS = (int)(iCalFrame / 30);
iFF = (int) (iCalFrame % 30);
rtnPlayTime = setLPad(Integer.toString(iHH), 2, "0") + setLPad(Integer.toString(iMM), 2, "0") + setLPad(Integer.toString(iSS), 2, "0") + setLPad(Integer.toString(iFF), 2, "0");
} else {
iHH1 = Integer.parseInt(vsPlayTime.substring(0, 2));
iMM1 = Integer.parseInt(vsPlayTime.substring(2, 4));
iSS1 = Integer.parseInt(vsPlayTime.substring(4, 6));
iHH2 = Integer.parseInt(vsDuration.substring(0, 2));
iMM2 = Integer.parseInt(vsDuration.substring(2, 4));
iSS2 = Integer.parseInt(vsDuration.substring(4, 6));
if ("FF".equals(vsType) || "NF".equals(vsType)) {
iFF1 = Integer.parseInt(vsPlayTime.substring(6, 8));
iFF2 = Integer.parseInt(vsDuration.substring(6, 8));
iSS = (int)((iFF1 + iFF2) / 30);
iFF = (iFF1 + iFF2) % 30;
}
iMM = (int)((iSS + iSS1 + iSS2) / 60);
iSS = (iSS + iSS1 + iSS2) % 60;
iHH = (int)((iMM + iMM1 + iMM2) / 60);
iMM = (iMM + iMM1 + iMM2) % 60;
iHH = iHH + iHH1 + iHH2;
if ("N".equals(vs24Yn) && iHH >= 24) {
iHH -= 24;
}
rtnPlayTime = setLPad(Integer.toString(iHH), 2, "0") + setLPad(Integer.toString(iMM), 2, "0") + setLPad(Integer.toString(iSS), 2, "0");
if ("FF".equals(vsType) || "NF".equals(vsType)) {
rtnPlayTime += setLPad(Integer.toString(iFF), 2, "0");
}
}
return rtnPlayTime;
}
public static String setLPad(String strContext, int iLen, String strChar) {
String strResult = "";
StringBuilder sbAddChar = new StringBuilder();
for(int i = strContext.length(); i < iLen; i++) {
// iLen길이 만큼 strChar문자로 채운다.
sbAddChar.append( strChar );
}
strResult = sbAddChar + strContext; // LPAD이므로, 채울문자열 + 원래문자열로 Concate
return strResult;
}
SFTP 방식 파일 업로드
commons-net-3.8.0.jar 추가 (C:\~\workspaceCis\build\lib\XBLib\commons-net-3.8.0.jar)
cis-web 우클릭 Properties > Java Build Path > XBLib > Edit > User Libraries > Add JARs > build\lib\XBLib\commons-net-3.8.0.jar 선택 > OK > Finish > Apply (cis-app에서 우클릭 했더니 적용 안됐었는데 확인 필요)
FtpClient 추가 (C:\~\workspaceCis\cis-core\src\org\tmt\core\util\FtpClient.java)
RestApiUtil 코드 추가 (C:\~\workspaceCis\cis-core\src\org\tmt\core\util\RestApiUtil.java)
FileUploadService 코드 추가
jsch-0.1.49.jar 추가 (C:\~\workspaceCis\build\lib\XBLib\jsch-0.1.49.jar) (commons-net 에서는 SFTP 를 지원 안함 => jsch 라이브러리 이용해서 SFTP 사용)
cis-web 우클릭 Properties > Java Build Path 적용
JschWrapper 추가 (C:\~\workspaceCis\cis-core\src\org\tmt\core\util\JschWrapper.java)
1. FileUploadController.java
package org.cis.com.controller;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.cis.com.service.FileUploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.View;
import org.tmt.core.auth.Authentication;
import org.tmt.core.model.RequestData;
import org.tmt.core.vo.DataMap;
@Controller
@RequestMapping("/FileUpload")
public class FileUploadController {
@Autowired
private FileUploadService fileUploadService;
@RequestMapping(value="/upload.do")
@ResponseBody
public View upload(@RequestParam(required = false) Map<String, Object> param,
HttpServletRequest request, HttpServletResponse response,
ModelMap modelMap, RequestData requestData, Authentication authentication) throws Exception {
// List<DataMap> fileInfo = fileUploadService.uploadFile(requestData, authentication); // 기존 방식 : 31, 32 운영 서버의 공유 폴더에 업로드가 되지 않아 FTP 방식으로 변경 -> commons-net-3.8.0.jar가 SFTP를 지원하지 않는 관계로 SFTP 방식으로 변경
List<DataMap> fileInfo = fileUploadService.sftpUploadFile(request, requestData, authentication); // 2022.03.30 sylee SFTP 방식의 파일 업로드
requestData.setResponse("dsUpload", fileInfo);
return requestData.getDefaultView();
}
}
2. FileUploadService.java
public List<DataMap> sftpUploadFile(HttpServletRequest request, RequestData requestData, Authentication authentication) throws Exception {
List<DataMap> fileList = new ArrayList<DataMap>();
DataMap paramMap = new DataMap();
String strGlobalFileStorePath = "";
String strFileStorePath = "";
String strFtpIp = "";
int iFtpPort = 0;
String strFtpId = "";
String strFtpPw = "";
String strFtpDir = "";
String strTempFilePath = "";
String strMenuId = requestData.getString("_AUTH_MENU_KEY");
strGlobalFileStorePath = AppWorkProperties.getProperty("Globals.fileStorePath"); // appworks.properties > Globals.fileStorePath=/FILE 추가
if (strMenuId.contains("AR_BOARD")) {
strFileStorePath = "/AR_BOARD";
} else {
strFileStorePath = AppWorkProperties.getProperty(strMenuId + ".fileStorePath"); // appworks.properties > NOTICE.fileStorePath=/NOTICE 추가
}
DataMap data = commonService.selectSysDate();
paramMap.put("userId", authentication.getUserId());
if("".equals(StringUtil.fixNull(strFileStorePath))){
//첨부파일을 저장할 저장소 경로가 존재하지 않습니다.
throw new AppWorksException("첨부파일을 저장할 저장소 경로가 존재하지 않습니다.", Alert.ERROR);
}
int iFileCnt = 0;
Map<String, UploadFile[]> uploadFiles = requestData.getUploadFiles();
if(uploadFiles != null && uploadFiles.size() > 0) {
Set<Entry<String, UploadFile[]>> entries = uploadFiles.entrySet();
for(Entry<String, UploadFile[]> entry : entries) {
DataMap fileInfo = new DataMap();
UploadFile[] uFiles = entry.getValue();
DataMap KeyNmData = commonService.selectAttachFileKeyNm(paramMap); // 업로드되는 파일이 중복되지 않도록 key값 생성
for(UploadFile uFile : uFiles){
File file = uFile.getFile();
String strFileName = uFile.getFileName(); //파일명.jpg
String[] arr = strFileName.split("\\."); // [파일명, .jpg]
String strFileSize = Long.toString(file.length()); //파일 사이즈
String strFileExt = FileUtil.getFileExtNm(strFileName);
String strTempPath = file.getPath(); // 임시 파일 업로드 경로 C:\Users\champ\AppData\Local\Temp\파일명.jpg.tmp
String strKeyNm = "(" + KeyNmData.getString("fileKeyNm") + ")." + arr[arr.length - 1]; // (key값).jpg
strKeyNm = arr[arr.length - 2] + strKeyNm; // 파일명(key값).jpg
// 보안에 위배되는 파일 확장자 유형인 경우
if(!SecurityWebUtil.securedFileType(strKeyNm)){
// {0} 확장자는 업로드 할 수 없습니다.
throw new AppWorksException("SYS.CMMN@CMMN011", Alert.ERROR, FileUtil.getFileExtNm(strKeyNm));
}
strFtpIp = "000.00.00.00";
iFtpPort = 22;
strFtpId = "root";
strFtpPw = "root";
strFtpDir = strGlobalFileStorePath+strFileStorePath+"/"; // 업로드할 경로 "/BIS_Storage/BS_PD_REQUEST_MST/";
strTempFilePath = strTempPath;
boolean result = sftpSendFile(strKeyNm, strFtpIp, iFtpPort, strFtpId, strFtpPw, strFtpDir, strTempFilePath);
fileInfo.put("fileNm", strFileName);
fileInfo.put("upLoadPath", strGlobalFileStorePath+strFileStorePath+"/");
fileInfo.put("fileSize", strFileSize);
fileInfo.put("fileExt", strFileExt);
fileInfo.put("saveFileNm", strKeyNm);
}
fileList.add(fileInfo);
iFileCnt++;
}
}
return fileList;
}
public boolean sftpSendFile(String strFileNm, String strFtpIp, int iFtpPort, String strFtpId, String strFtpPw, String strFtpDir, String strTempFilePath) throws Exception{
boolean result = false;
JschWrapper jw = null;
try {
// JschWrapper 생성 (주소, 포트번호, 사용자아이디, 패스워드)
jw = new JschWrapper(strFtpIp, iFtpPort, strFtpId, strFtpPw);
// SFTP 접속하기 (주소, 포트번호, 사용자아이디, 패스워드)
jw.connectSFTP(strFtpIp, iFtpPort, strFtpId, strFtpPw);
// 파일 업로드 (임시 파일 경로, 업로드할 경로, 확장자명 포함한 파일명)
jw.uploadFile(strTempFilePath, strFtpDir, strFileNm);
result = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
// SFTP 접속해제
jw.disconnectSFTP();
}
return result;
}
3. JschWrapper.java
package org.tmt.core.util;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
public class JschWrapper { // sylee 추가
private Session jschSession = null;
private Channel channel = null;
private ChannelSftp channelSftp = null;
// sylee 추가
private String serverIp;
private int serverPort;
private String user;
private String password;
// sylee 추가
public JschWrapper(String serverIp, int serverPort, String user, String password) {
this.serverIp = serverIp;
this.serverPort = serverPort;
this.user = user;
this.password = password;
}
/**
* 파일 업로드 uploadFile sylee 코드 수정
*
* @param strTempFilePath // sylee 추가
* @param strFtpDir
* @param fileName
* @throws Exception
*/
public boolean uploadFile(String strTempFilePath, String strFtpDir, String fileName) throws Exception {
boolean isSuccess = false;
FileInputStream fis = null;
try {
// FTP 방식 mkdir
File fileDir = new File(strFtpDir);
if(!fileDir.exists()){
// fileDir.mkdir(); // 만들고자 하는 Folder의 상위 Folder가 존재하지 않을 경우 생성 불가
fileDir.mkdirs(); // 만들고자 하는 Folder의 상위 Folder가 존재하지 않을 경우 상위 Folder까지 모두 생성
}
// SFTP 방식 mkdir => 공유폴더 mkdir 안됨
// File fileDir = new File(strFtpDir);
//
// if(!fileDir.exists()){
// String[] pathArray = strFtpDir.split("/");
//
// for (int i = 1; i < pathArray.length; i++) {
//
// try {
// channelSftp.mkdir(pathArray[i]);
// channelSftp.cd(pathArray[i]);
// } catch(Exception e) {
// channelSftp.cd(pathArray[i]);
// }
// }
// }
// 대상폴더 이동
channelSftp.cd(strFtpDir);
File file = new File(strTempFilePath);
fis = new FileInputStream(file);
// String sourceFolder = file.getParent();
// String sourceFileName = file.getName();
// 파일 업로드
// channelSftp.put(fis, file.getName());
channelSftp.put(fis, fileName);
isSuccess = true;
System.out.println("File uploaded : " + file.getAbsolutePath() + " => " + strFtpDir + "/" + fileName);
} catch (Exception e) {
throw e;
} finally {
close(fis);
}
return isSuccess;
}
/**
* 파일 다운로드
*
* @param remoteFilePath
* @param localDirPath
* @param overwrite
* @return
* @throws Exception
*/
public boolean downloadFile(String remoteFilePath, String localDirPath, boolean overwrite) throws Exception {
if (remoteFilePath == null || remoteFilePath.length() == 0) {
return false;
}
boolean isSuccess = false;
byte[] buffer = new byte[1024];
BufferedInputStream bis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
if (remoteFilePath.indexOf("\\") > -1) {
remoteFilePath = remoteFilePath.replace("\\", "/");
}
String remoteFileName = "";
// 대상폴더 이동
int lastSlashIndex = remoteFilePath.lastIndexOf("/");
if (lastSlashIndex > -1) {
String cdDir = remoteFilePath.substring(0, lastSlashIndex);
remoteFileName = remoteFilePath.substring(lastSlashIndex + 1);
channelSftp.cd(cdDir);
} else {
remoteFileName = remoteFilePath;
channelSftp.cd("/");
}
File destFile = new File(localDirPath + File.separator + remoteFileName);
if (destFile.exists()) {
if (overwrite) {
destFile.delete();
} else {
System.out.println("File Download canceled. File already exists : " + destFile.getAbsolutePath());
return false;
}
}
// 파일 다운로드
bis = new BufferedInputStream(channelSftp.get(remoteFileName));
fos = new FileOutputStream(destFile);
bos = new BufferedOutputStream(fos);
int readCount = 0;
while ((readCount = bis.read(buffer)) > 0) {
bos.write(buffer, 0, readCount);
}
isSuccess = true;
System.out.println("File downloaded : " + remoteFilePath + " => " + destFile.getAbsolutePath());
} catch (Exception e) {
throw e;
} finally {
close(bos);
close(fos);
close(bis);
}
return isSuccess;
}
/**
* 폴더 생성
*
* @param dirPath
* @param dirName
* @throws Exception
*/
public boolean mkdir(String dirPath, String dirName) throws Exception {
boolean isSuccess = false;
String destDirPath = dirPath + "/" + dirName;
boolean destDirExists = false;
try {
channelSftp.cd(destDirPath);
destDirExists = true;
} catch (Exception e) {
destDirExists = false;
}
if (destDirExists) {
System.out.println("Folder Creation canceled. Folder already exists : " + destDirPath);
return false;
}
// 대상폴더 이동
channelSftp.cd(dirPath);
// 폴더 생성
channelSftp.mkdir(dirName);
isSuccess = true;
System.out.println("Folder created : " + destDirPath);
return isSuccess;
}
/**
* SFTP 접속하기
*
* @return
* @throws JSchException
* @throws Exception
*/
public void connectSFTP(String host, int port, String userName, String password) throws Exception {
// JSch 객체를 생성
JSch jsch = new JSch();
// JSch 세션 객체를 생성 (사용자 이름, 접속할 호스트, 포트 전달)
jschSession = jsch.getSession(userName, host, port);
// 패스워드 설정
jschSession.setPassword(password);
// 기타설정 적용
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
jschSession.setConfig(config);
// 접속
jschSession.connect();
// sftp 채널 열기
channel = jschSession.openChannel("sftp");
// sftp 채널 연결
channelSftp = (ChannelSftp) channel;
channelSftp.connect();
}
/**
* SFTP 접속해제
*/
public void disconnectSFTP() {
try {
if (channelSftp != null && channelSftp.isConnected()) {
channelSftp.disconnect();
}
} catch (Exception e) {
} finally {
channelSftp = null;
}
try {
if (channel != null && channel.isConnected()) {
channel.disconnect();
}
} catch (Exception e) {
} finally {
channel = null;
}
try {
if (jschSession != null && jschSession.isConnected()) {
jschSession.disconnect();
}
} catch (Exception e) {
} finally {
jschSession = null;
}
}
/**
* FileInputStream 객체 닫기
*
* @param fis
*/
private void close(FileInputStream fis) {
try {
if (fis != null) {
fis.close();
}
} catch (Exception e) {
} finally {
fis = null;
}
}
/**
* BufferedInputStream 객체 닫기
*
* @param bis
*/
private void close(BufferedInputStream bis) {
try {
if (bis != null) {
bis.close();
}
} catch (Exception e) {
} finally {
bis = null;
}
}
/**
* FileOutputStream 객체 닫기
*
* @param fos
*/
private void close(FileOutputStream fos) {
try {
if (fos != null) {
fos.flush();
}
} catch (Exception e) {
}
try {
if (fos != null) {
fos.close();
}
} catch (Exception e) {
} finally {
fos = null;
}
}
/**
* BufferedOutputStream 객체 닫기
*
* @param bos
*/
private void close(BufferedOutputStream bos) {
try {
if (bos != null) {
bos.flush();
}
} catch (Exception e) {
}
try {
if (bos != null) {
bos.close();
}
} catch (Exception e) {
} finally {
bos = null;
}
}
}