Merge remote-tracking branch 'origin/master'

This commit is contained in:
wangchengjun
2022-04-12 19:18:33 +08:00
25 changed files with 2458 additions and 32 deletions
@@ -72,6 +72,8 @@ public class ShiroConfig {
// 配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/sys/cas/client/validateLogin", "anon"); //cas验证登录
filterChainDefinitionMap.put("/ocr/OcrRestful/ocrHandleResult", "anon"); //ocr回调接口
filterChainDefinitionMap.put("/ocr/ocrCheck/downFile", "anon"); //ocr校核下载文件
filterChainDefinitionMap.put("/ocr/ocrCheck/saveFile", "anon"); //ocr校核回调
filterChainDefinitionMap.put("/sys/randomImage/**", "anon"); //登录验证码接口排除
filterChainDefinitionMap.put("/sys/checkCaptcha", "anon"); //登录验证码接口排除
filterChainDefinitionMap.put("/sys/getRSAPublicKey", "anon"); //获取RSA公钥接口排除
@@ -17,7 +17,7 @@ public interface IOSSFileService extends IService<OSSFile> {
* @param bizPath 自定义路径
* @return
*/
public OSSFile uploadLocal(MultipartFile mf, String bizPath,String state);
public OSSFile uploadLocal(MultipartFile mf, String bizPath,String state,String cut);
public List<OSSFile> getFileInfos(String id);
@@ -2,6 +2,7 @@ package com.jero.modules.oss.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jero.common.constant.enums.CutEnum;
import com.jero.common.exception.JeroBootException;
import com.jero.common.system.vo.LoginUser;
import com.jero.common.util.CommonUtils;
@@ -58,13 +59,17 @@ public class OSSFileServiceImpl extends ServiceImpl<OSSFileMapper, OSSFile> impl
* @return
*/
@Override
public OSSFile uploadLocal(MultipartFile mf, String bizPath,String state) {
public OSSFile uploadLocal(MultipartFile mf, String bizPath,String state,String cut) {
//处理文件大小,大于100M抛出异常
long fileSize = mf.getSize() / 1024 / 1024;
String originalFilename = mf.getOriginalFilename();
if (fileSize >= 100) {
throw new JeroBootException(originalFilename + "文件大小超出100MB限制, 请压缩或降低文件质量!");
if(cut.equals(CutEnum.CN.getValue())){
throw new JeroBootException(originalFilename + "文件大小超出100MB, 请压缩或降低文件质量!");
}else{
throw new JeroBootException(originalFilename + "File size out 100MB, Please compress or reduce file quality!");
}
}
OSSFile oSSFile = new OSSFile();
@@ -90,11 +95,19 @@ public class OSSFileServiceImpl extends ServiceImpl<OSSFileMapper, OSSFile> impl
if("1".equals(state)){
//固定文件
if(!fileTypeStr.contains(fileType)){
throw new JeroBootException("只能够上传pdf,word,excel类型的文件。请重新选择文件!");
if(cut.equals(CutEnum.CN.getValue())){
throw new JeroBootException("只能够上传pdf,word,excel类型的文件。请重新选择文件!");
}else{
throw new JeroBootException("Only upload pdf,word,excel type of file Please select the file again");
}
}
}else{
if (CommonUtils.limitFileSuffix(orgName, fileSuffixLimits)) {
throw new JeroBootException("不能上传"+StringUtils.join(fileSuffixLimits, ",")+"类型的文件。请重新选择文件!");
if(cut.equals(CutEnum.CN.getValue())){
throw new JeroBootException("不能上传"+StringUtils.join(fileSuffixLimits, ",")+"类型的文件。请重新选择文件!");
}else{
throw new JeroBootException("Can't upload"+StringUtils.join(fileSuffixLimits, ",")+"type of file Please select the file again");
}
}
}
@@ -110,9 +123,12 @@ public class OSSFileServiceImpl extends ServiceImpl<OSSFileMapper, OSSFile> impl
}
}
if (flag) {
throw new JeroBootException("只能够上传pdf/word/excel/csv/ppt/txt/zip/rar/静态图片类型的文件。请重新选择文件!");
if(cut.equals(CutEnum.CN.getValue())){
throw new JeroBootException("只能够上传pdf/word/excel/csv/ppt/txt/zip/rar/静态图片类型的文件。请重新选择文件!");
}else{
throw new JeroBootException("Only upload pdf/word/excel/csv/ppt/txt/zip/rar/静态图片类型的文件。请重新选择文件!");
}
}
}
String savePath = file.getPath() + File.separator + fileName;
@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jero.common.api.vo.Result;
import com.jero.common.constant.CommonConstant;
import com.jero.common.constant.enums.CutEnum;
import com.jero.common.exception.JeroBootException;
import com.jero.common.system.api.ISysBaseAPI;
import com.jero.common.util.RestUtil;
@@ -150,7 +151,8 @@ public class CommonController {
@ApiOperation(value="文件上传统一方法", notes="文件上传统一方法")
@PostMapping(value = "/upload")
public Result<?> upload(HttpServletRequest request, HttpServletResponse response,
@RequestParam(value = "state",required = false) String state) {
@RequestParam(value = "state",required = false) String state,
@RequestParam(value = "cut",required = false) String cut) {
Result<OSSFile> result = new Result<>();
String bizPath = request.getParameter("biz");
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
@@ -163,12 +165,16 @@ public class CommonController {
bizPath = "";
}
}
OSSFile oSSFile = ossFileService.uploadLocal(file, bizPath,state);
OSSFile oSSFile = ossFileService.uploadLocal(file, bizPath,state,cut);
if (oConvertUtils.isNotEmpty(oSSFile)) {
result.setResult(oSSFile);
result.setSuccess(true);
} else {
result.setMessage("上传失败!");
if("cut".equals(CutEnum.CN.getValue())){
result.setMessage("上传失败!");
}else{
result.setMessage("fail to upload");
}
result.setSuccess(false);
}
return result;
+11
View File
@@ -150,6 +150,17 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.inversoft</groupId>
<artifactId>prime-jwt</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
</project>
@@ -3274,38 +3274,74 @@ public class BussDocumentLibraryEOServiceImpl extends ServiceImpl<BussDocumentLi
//第二行
StringBuilder sbTwo = new StringBuilder();
sbTwo.append("填写说明\n" + "1.导入数据从第三行开始,第一行为表头,第二行为填写说明,第三行是正式数据\n" + "2.所有带*号的字段必须填写\n");
if(CutEnum.CN.getValue().equals(cut)){
sbTwo.append("填写说明\n" + "1.导入数据从第三行开始,第一行为表头,第二行为填写说明,第三行是正式数据\n" + "2.所有带*号的字段必须填写\n");
}else{
sbTwo.append("Filling explanation\n"
+ "1.Import data starts at the third line, the first line is the header, the second line is the description, and the third line is the official data\n"
+ "2.All fields marked with * must be filled in\n");
}
int count = 3;
if (pullSingleList.size() != 0) {
//单选
String pullSingle = StringUtils.join(pullSingleList, ",") + "字段是单选属性,必须和系统中的对应字段选项相匹配\n";
sbTwo.append(count++ + "." + pullSingle);
if(CutEnum.CN.getValue().equals(cut)){
String pullSingle = StringUtils.join(pullSingleList, ",") + "字段是单选属性,必须和系统中的对应字段选项相匹配\n";
sbTwo.append(count++ + "." + pullSingle);
}else{
String pullSingle = StringUtils.join(pullSingleList, ",") + " Fields are radio attributes,Must match the corresponding field option in the system\n";
sbTwo.append(count++ + "." + pullSingle);
}
}
if (pullMoreList.size() != 0) {
//多选
String pullMore = StringUtils.join(pullMoreList, ",") + "字段是多选属性,必须和系统中的对应字段选项相匹配,填写多个时采用英文或中文逗号分割\n";
sbTwo.append(count++ + "." + pullMore);
if(CutEnum.CN.getValue().equals(cut)){
String pullMore = StringUtils.join(pullMoreList, ",") + "字段是多选属性,必须和系统中的对应字段选项相匹配,填写多个时采用英文或中文逗号分割\n";
sbTwo.append(count++ + "." + pullMore);
}else{
String pullMore = StringUtils.join(pullMoreList, ",") + " A field is a multi-select attribute and must match the corresponding field in the system. If multiple fields are filled in, separate them by commas (,)\n";
sbTwo.append(count++ + "." + pullMore);
}
}
if (dateSingleList.size() != 0) {
//单选日期
String dateSingle = StringUtils.join(dateSingleList, ",") + "字段为日期,必须精确到日\n";
sbTwo.append(count++ + "." + dateSingle);
if(CutEnum.CN.getValue().equals(cut)){
String dateSingle = StringUtils.join(dateSingleList, ",") + "字段为日期,必须精确到日\n";
sbTwo.append(count++ + "." + dateSingle);
}else{
String dateSingle = StringUtils.join(dateSingleList, ",") + " The field is the date and must be exact to the day\n";
sbTwo.append(count++ + "." + dateSingle);
}
}
if (textStringList.size() != 0) {
//输入框
String textString = StringUtils.join(textStringList, ",") + "字段为文本,填写文本内容\n";
sbTwo.append(count++ + "." + textString);
if(CutEnum.CN.getValue().equals(cut)){
String textString = StringUtils.join(textStringList, ",") + "字段为文本,填写文本内容\n";
sbTwo.append(count++ + "." + textString);
}else{
String textString = StringUtils.join(textStringList, ",") + " Field is text. Enter the text content\n";
sbTwo.append(count++ + "." + textString);
}
}
if (standardList.size() != 0) {
//标准选择
String standard = StringUtils.join(standardList, ",") + "字段为标准号,填写多个时采用英文或中文逗号分割\n";
sbTwo.append(count++ + "." + standard);
if(CutEnum.CN.getValue().equals(cut)){
String standard = StringUtils.join(standardList, ",") + "字段为标准号,填写多个时采用英文或中文逗号分割\n";
sbTwo.append(count++ + "." + standard);
}else{
String standard = StringUtils.join(standardList, ",") + " The field is a standard number. If you fill in more than one field, separate it with English or Chinese commas\n";
sbTwo.append(count++ + "." + standard);
}
}
if (fileList.size() != 0) {
//文件
String file = StringUtils.join(fileList, ",") + "字段为文件属性,填写时需要在本文件同级目录下以标准号为名称建立文件夹,并在文件夹下放置文件,假设在AAA标准号下放置了B.pdf,则应填写AAA/B.pdf\n";
sbTwo.append(count++ + "." + file);
if(CutEnum.CN.getValue().equals(cut)){
String file = StringUtils.join(fileList, ",") + "字段为文件属性,填写时需要在本文件同级目录下以标准号为名称建立文件夹,并在文件夹下放置文件,假设在AAA标准号下放置了B.pdf,则应填写AAA/B.pdf\n";
sbTwo.append(count++ + "." + file);
}else{
String file = StringUtils.join(fileList, ",") + " When filling in the field, you need to create a folder in the directory of the same level as the file with the name of the standard number and place the file in the folder. Assume that the file is saved in the AAA standard numberB.pdf,Should fill inAAA/B.pdf\n";
sbTwo.append(count++ + "." + file);
}
}
List<String> list = new LinkedList<>();
list.add(title);
@@ -4030,7 +4066,7 @@ public class BussDocumentLibraryEOServiceImpl extends ServiceImpl<BussDocumentLi
MultipartFile multipartFile =
new MockMultipartFile(nowFileList.get(0).getName(), nowFileList.get(0).getName(), "text/plain", input);
//文件存入文件表
OSSFile ossFile = iOSSFileService.uploadLocal(multipartFile, "", null);
OSSFile ossFile = iOSSFileService.uploadLocal(multipartFile, "", null,null);
if (ObjectUtils.isNotEmpty(ossFile)) {
sb.append(ossFile.getId() + ",");
}
@@ -0,0 +1,229 @@
package com.jero.modules.ocr.controller;
import com.jero.common.exception.JeroBootException;
import com.jero.common.system.vo.LoginUser;
import com.jero.modules.ocr.helpers.ConfigManager;
import com.jero.modules.ocr.helpers.DocumentManager;
import com.jero.modules.ocr.helpers.FileUtility;
import com.jero.modules.ocr.helpers.ServiceConverter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.shiro.SecurityUtils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
/**
* @Author: liyawei
* @Description:
* @Date: Created in 10:51 2022/4/11
*/
@Api(tags="OCR识别在线校核")
@RestController
@RequestMapping("/ocr/ocrCheck")
@Slf4j
public class OcrCheckController {
@Value("${OCR.ocrDownPath}")
private String ocrDownPath;
@Value("${OCR.ocrSavePath}")
private String ocrSavePath;
@Value("${OCR.serverUrl}")
private String serverUrl;
@Value("${OCR.ocrPath}")
private String ocrPath;
@ApiOperation(value = "下载word文件")
@GetMapping("/downFile")
public void downFile(String fileName, HttpServletResponse response, HttpServletRequest request) throws Exception {
InputStream is = null;
OutputStream os = null;
response.reset();
try {
String downFileName = fileName.substring(fileName.indexOf("_") + 1);
response.setHeader("Content-Disposition", "attachment; filename=" + downFileName);
response.setContentType("application/octet-stream");
String fullPath = ocrPath + fileName;
is = new FileInputStream(fullPath);
os = response.getOutputStream();
IOUtils.copy(is, os);
os.flush();
} catch (FileNotFoundException var4) {
throw new JeroBootException("文件[" + ocrPath + fileName + "]不存在");
} catch (IOException e) {
log.error(e.getMessage(), e);
} finally {
is.close();
os.close();
}
}
@ApiOperation(value = "编辑文件")
@RequestMapping("/editorFile")
public ModelAndView index(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
String fileName = "";
if (request.getParameterMap().containsKey("fileName")) {
fileName = request.getParameter("fileName");
}
// String fileExt = null;
// if (request.getParameterMap().containsKey("fileExt")) {
// fileExt = request.getParameter("fileExt");
// }
// if (fileExt != null) {
// try {
// DocumentManager.Init(request, response);
// fileName = DocumentManager.CreateDemo(fileExt);
// } catch (Exception ex) {
// return new ModelAndView(new FastJsonJsonView(),"Error: " + ex.getMessage(), ex) ;
// }
// }
// String mode = "";
// if (request.getParameterMap().containsKey("mode"))
// {
// mode = request.getParameter("mode");
// }
// Boolean desktopMode = !"embedded".equals(mode);
// FileModel file = new FileModel();
// file.SetTypeDesktop(desktopMode);
// file.SetFileName(fileName);
log.info("==========EditorFile==========");
DocumentManager.Init(request, response);
//要编辑的文件名
model.addAttribute("fileName", fileName) ;
//要编辑的文件类型
model.addAttribute("fileType", FileUtility.GetFileExtension(fileName).replace(".", "")) ;
//要编辑的文档类型
model.addAttribute("documentType",FileUtility.GetFileType(fileName).toString().toLowerCase()) ;
//要编辑的文档访问url
// model.addAttribute("fileUri",DocumentManager.GetFileUri(fileName, true)) ;
// model.addAttribute("callbackUrl", DocumentManager.GetCallback(fileName)) ;
// model.addAttribute("serverUrl", DocumentManager.GetServerUrl(true)) ;
model.addAttribute("fileUri", ocrDownPath + "?fileName=" + fileName) ;
model.addAttribute("callbackUrl", ocrSavePath + "?fileName=" + fileName) ;
model.addAttribute("serverUrl", serverUrl) ;
model.addAttribute("fileKey", ServiceConverter.GenerateRevisionId(DocumentManager.CurUserHostAddress(null) + ocrDownPath + "?fileName=" + fileName)) ;
model.addAttribute("editorMode", DocumentManager.GetEditedExts().contains(FileUtility.GetFileExtension(fileName)) && !"view".equals(request.getAttribute("mode")) ? "edit" : "view") ;
model.addAttribute("editorUserId",DocumentManager.CurUserHostAddress(null)) ;
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
model.addAttribute("editorUserName", loginUser.getUsername()) ;
// model.addAttribute("type", desktopMode ? "desktop" : "embedded");
model.addAttribute("type", true ? "desktop" : "embedded");
model.addAttribute("docserviceApiUrl", ConfigManager.GetProperty("files.docservice.url.api"));
model.addAttribute("docServiceUrlPreloader", ConfigManager.GetProperty("files.docservice.url.preloader")) ;
model.addAttribute("currentYear", "2022") ;
model.addAttribute("convertExts", String.join(",", DocumentManager.GetConvertExts())) ;
model.addAttribute("editedExts", String.join(",", DocumentManager.GetEditedExts())) ;
model.addAttribute("documentCreated", new SimpleDateFormat("MM/dd/yyyy").format(new Date())) ;
model.addAttribute("permissionsEdit", Boolean.toString(DocumentManager.GetEditedExts().contains(FileUtility.GetFileExtension(fileName))).toLowerCase()) ;
return new ModelAndView("editor") ;
}
/**
* 文档编辑服务使用JavaScript API通知callbackUrl,向文档存储服务通知文档编辑的状态。文档编辑服务使用具有正文中的信息的POST请求。
* https://api.onlyoffice.com/editors/callback
* 参数示例:
{
"actions": [{"type": 0, "userid": "78e1e841"}],
"changesurl": "https://documentserver/url-to-changes.zip",
"history": {
"changes": changes,
"serverVersion": serverVersion
},
"key": "Khirz6zTPdfd7",
"status": 2,
"url": "https://documentserver/url-to-edited-document.docx",
"users": ["6d5a81d0"]
}
*/
@ApiOperation(value = "保存文件")
@RequestMapping("/saveFile")
public void saveFile(HttpServletRequest request, HttpServletResponse response) {
String fileName = "";
if (request.getParameterMap().containsKey("fileName")) {
fileName = request.getParameter("fileName");
}
PrintWriter writer = null;
log.info("==========SaveEditedFile==========");
try {
writer = response.getWriter();
Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
String body = scanner.hasNext() ? scanner.next() : "";
JSONObject jsonObj = (JSONObject) new JSONParser().parse(body);
log.info("status:" + jsonObj.get("status"));
/*
0 - no document with the key identifier could be found,
1 - document is being edited,
2 - document is ready for saving,
3 - document saving error has occurred,
4 - document is closed with no changes,
6 - document is being edited, but the current document state is saved,
7 - error has occurred while force saving the document.
* */
if ((long) jsonObj.get("status") == 2) {
/*
* 当我们关闭编辑窗口后,十秒钟左右onlyoffice会将它存储的我们的编辑后的文件,,此时status = 2,通过request发给我们,我们需要做的就是接收到文件然后回写该文件。
* */
/*
* 定义要与文档存储服务保存的编辑文档的链接。当状态值仅等于2或3时,存在链路。
* */
String downloadUri = (String) jsonObj.get("url");
log.info("文档编辑完成,现在开始保存编辑后的文档,其下载地址为:" + downloadUri);
//解析得出文件名
// String fileName = downloadUri.substring(downloadUri.lastIndexOf('/') + 1);
log.info("下载的文件名:" + fileName);
URL url = new URL(downloadUri);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
InputStream stream = connection.getInputStream();
File savedFile = new File(ocrPath + fileName);
try (FileOutputStream out = new FileOutputStream(savedFile)) {
int read;
final byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
}
connection.disconnect();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*
* status = 1,我们给onlyoffice的服务返回{"error":"0"}的信息,这样onlyoffice会认为回调接口是没问题的,这样就可以在线编辑文档了,否则的话会弹出窗口说明
* */
writer.write("{\"error\":0}");
}
}
@@ -0,0 +1,17 @@
package com.jero.modules.ocr.entity;
import java.util.List;
public class CommentGroups {
public List<String> view;
public List<String> edit;
public List<String> remove;
public CommentGroups(){
}
public CommentGroups(List<String> view, List<String> edit, List<String> remove){
this.view = view;
this.edit = edit;
this.remove = remove;
}
}
@@ -0,0 +1,370 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.jero.modules.ocr.entity;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.jero.modules.ocr.helpers.DocumentManager;
import com.jero.modules.ocr.helpers.FileUtility;
import com.jero.modules.ocr.helpers.ServiceConverter;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import java.io.File;
import java.io.FileInputStream;
import java.util.*;
public class FileModel
{
public String type = "desktop";
public String mode = "edit";
public String documentType;
public Document document;
public EditorConfig editorConfig;
public String token;
// create file model
public FileModel(String fileName, String lang, String actionData, User user)
{
if (fileName == null) fileName = "";
fileName = fileName.trim(); // remove extra spaces in the file name
// get file type from the file name (word, cell or slide)
documentType = FileUtility.GetFileType(fileName).toString().toLowerCase();
// set the document parameters
document = new Document();
document.title = fileName;
document.url = DocumentManager.GetDownloadUrl(fileName); // get file url
document.urlUser = DocumentManager.GetFileUri(fileName, false);
document.fileType = FileUtility.GetFileExtension(fileName).replace(".", ""); // get file extension from the file name
// generate document key
document.key = ServiceConverter.GenerateRevisionId(DocumentManager.CurUserHostAddress(null) + "/" + fileName + "/" + Long.toString(new File(DocumentManager.StoragePath(fileName, null)).lastModified()));
document.info = new Info();
document.info.favorite = user.favorite;
String templatesImageUrl = DocumentManager.GetTemplateImageUrl(FileUtility.GetFileType(fileName));
List<Map<String, String>> templates = new ArrayList<>();
String createUrl = DocumentManager.GetCreateUrl(FileUtility.GetFileType(fileName));
// add templates for the "Create New" from menu option
Map<String, String> templateForBlankDocument = new HashMap<>();
templateForBlankDocument.put("image", "");
templateForBlankDocument.put("title", "Blank");
templateForBlankDocument.put("url", createUrl);
templates.add(templateForBlankDocument);
Map<String, String> templateForDocumentWithSampleContent = new HashMap<>();
templateForDocumentWithSampleContent.put("image", templatesImageUrl);
templateForDocumentWithSampleContent.put("title", "With sample content");
templateForDocumentWithSampleContent.put("url", createUrl + "&sample=true");
templates.add(templateForDocumentWithSampleContent);
// set the editor config parameters
editorConfig = new EditorConfig(actionData);
editorConfig.callbackUrl = DocumentManager.GetCallback(fileName); // get callback url
if (lang != null) editorConfig.lang = lang; // write language parameter to the config
editorConfig.createUrl = !user.id.equals("uid-0") ? createUrl : null;
editorConfig.templates = user.templates ? templates : null;
// write user information to the config (id, name and group)
editorConfig.user.id = user.id;
editorConfig.user.name = user.name;
editorConfig.user.group = user.group;
// write the absolute URL to the file location
editorConfig.customization.goback.url = DocumentManager.GetServerUrl(false) + "/IndexServlet";
changeType(mode, type, user);
}
// change the document type
public void changeType(String _mode, String _type, User user)
{
if (_mode != null) mode = _mode;
if (_type != null) type = _type;
// check if the file with such an extension can be edited
String fileExt = FileUtility.GetFileExtension(document.title);
Boolean canEdit = DocumentManager.GetEditedExts().contains(fileExt);
// check if the Submit form button is displayed or not
editorConfig.customization.submitForm = mode.equals("fillForms") && user.id.equals("uid-1") && false;
if ((!canEdit && mode.equals("edit") || mode.equals("fillForms")) && DocumentManager.GetFillExts().contains(fileExt)) {
canEdit = true;
mode = "fillForms";
}
// set the mode parameter: change it to view if the document can't be edited
editorConfig.mode = canEdit && !mode.equals("view") ? "edit" : "view";
// set document permissions
document.permissions = new Permissions(mode, type, canEdit, user);
if (type.equals("embedded")) InitDesktop(); // set parameters for the embedded document
}
public void InitDesktop()
{
editorConfig.InitDesktop(document.urlUser);
}
// generate document token
public void BuildToken()
{
// write all the necessary document parameters to the map
Map<String, Object> map = new HashMap<>();
map.put("type", type);
map.put("documentType", documentType);
map.put("document", document);
map.put("editorConfig", editorConfig);
// and create token from them
token = DocumentManager.CreateToken(map);
}
// get document history
public String[] GetHistory()
{
JSONParser parser = new JSONParser();
String histDir = DocumentManager.HistoryDir(DocumentManager.StoragePath(document.title, null)); // get history directory
if (DocumentManager.GetFileVersion(histDir) > 0) {
Integer curVer = DocumentManager.GetFileVersion(histDir); // get current file version if it is greater than 0
List<Object> hist = new ArrayList<>();
Map<String, Object> histData = new HashMap<String, Object>();
for (Integer i = 1; i <= curVer; i++) { // run through all the file versions
Map<String, Object> obj = new HashMap<String, Object>();
Map<String, Object> dataObj = new HashMap<String, Object>();
String verDir = DocumentManager.VersionDir(histDir, i); // get the path to the given file version
try {
String key = null;
// get document key
key = i == curVer ? document.key : readFileToEnd(new File(verDir + File.separator + "key.txt"));
obj.put("key", key);
obj.put("version", i);
if (i == 1) { // check if the version number is equal to 1
String createdInfo = readFileToEnd(new File(histDir + File.separator + "createdInfo.json")); // get file with meta data
JSONObject json = (JSONObject) parser.parse(createdInfo); // and turn it into json object
// write meta information to the object (user information and creation date)
obj.put("created", json.get("created"));
Map<String, Object> user = new HashMap<String, Object>();
user.put("id", json.get("id"));
user.put("name", json.get("name"));
obj.put("user", user);
}
dataObj.put("key", key);
dataObj.put("url", i == curVer ? document.url : DocumentManager.GetPathUri(verDir + File.separator + "prev" + FileUtility.GetFileExtension(document.title)));
dataObj.put("version", i);
if (i > 1) { //check if the version number is greater than 1
// if so, get the path to the changes.json file
JSONObject changes = (JSONObject) parser.parse(readFileToEnd(new File(DocumentManager.VersionDir(histDir, i - 1) + File.separator + "changes.json")));
JSONObject change = (JSONObject) ((JSONArray) changes.get("changes")).get(0);
// write information about changes to the object
obj.put("changes", !change.isEmpty() ? changes.get("changes") : null);
obj.put("serverVersion", changes.get("serverVersion"));
obj.put("created", !change.isEmpty() ? change.get("created") : null);
obj.put("user", !change.isEmpty() ? change.get("user") : null);
Map<String, Object> prev = (Map<String, Object>) histData.get(Integer.toString(i - 2)); // get the history data from the previous file version
Map<String, Object> prevInfo = new HashMap<String, Object>();
prevInfo.put("key", prev.get("key")); // write key and url information about previous file version
prevInfo.put("url", prev.get("url"));
dataObj.put("previous", prevInfo); // write information about previous file version to the data object
// write the path to the diff.zip archive with differences in this file version
dataObj.put("changesUrl", DocumentManager.GetPathUri(DocumentManager.VersionDir(histDir, i - 1) + File.separator + "diff.zip"));
}
if (DocumentManager.TokenEnabled())
{
dataObj.put("token", DocumentManager.CreateToken(dataObj));
}
hist.add(obj);
histData.put(Integer.toString(i - 1), dataObj);
} catch (Exception ex) { }
}
// write history information about the current file version to the history object
Map<String, Object> histObj = new HashMap<String, Object>();
histObj.put("currentVersion", curVer);
histObj.put("history", hist);
Gson gson = new Gson();
return new String[] { gson.toJson(histObj), gson.toJson(histData) };
}
return new String[] { "", "" };
}
// read a file
private String readFileToEnd(File file) {
String output = "";
try {
try(FileInputStream is = new FileInputStream(file))
{
Scanner scanner = new Scanner(is); // read data from the source
scanner.useDelimiter("\\A");
while (scanner.hasNext()) {
output += scanner.next();
}
scanner.close();
}
} catch (Exception e) { }
return output;
}
// the document parameters
public class Document
{
public String title;
public String url;
public String urlUser;
public String fileType;
public String key;
public Info info;
public Permissions permissions;
}
// the permissions parameters
public class Permissions
{
public Boolean comment;
public Boolean сopy;
public Boolean download;
public Boolean edit;
public Boolean print;
public Boolean fillForms;
public Boolean modifyFilter;
public Boolean modifyContentControl;
public Boolean review;
public List<String> reviewGroups;
public CommentGroups commentGroups;
// defines what can be done with a document
public Permissions(String mode, String type, Boolean canEdit, User user)
{
comment = !mode.equals("view") && !mode.equals("fillForms") && !mode.equals("embedded") && !mode.equals("blockcontent");
сopy = !user.deniedPermissions.contains("сopy");
download = !user.deniedPermissions.contains("download");
edit = canEdit && (mode.equals("edit") || mode.equals("view") || mode.equals("filter") || mode.equals("blockcontent"));
print = !user.deniedPermissions.contains("print");
fillForms = !mode.equals("view") && !mode.equals("comment") && !mode.equals("embedded") && !mode.equals("blockcontent");
modifyFilter = !mode.equals("filter");
modifyContentControl = !mode.equals("blockcontent");
review = canEdit && (mode.equals("edit") || mode.equals("review"));
reviewGroups = user.reviewGroups;
commentGroups = user.commentGroups;
}
}
// the Favorite icon state
public class Info
{
public Boolean favorite;
}
// the editor config parameters
public class EditorConfig
{
public HashMap<String, Object> actionLink = null;
public String mode = "edit";
public String callbackUrl;
public String lang = "en";
public String createUrl;
public List<Map<String, String>> templates;
public User user;
public Customization customization;
public Embedded embedded;
public EditorConfig(String actionData)
{
// get the action in the document that will be scrolled to (bookmark or comment)
if (actionData != null) {
Gson gson = new Gson();
actionLink = gson.fromJson(actionData, new TypeToken<HashMap<String, Object>>() { }.getType());
}
user = new User();
customization = new Customization();
}
// set parameters for the embedded document
public void InitDesktop(String url)
{
embedded = new Embedded();
embedded.saveUrl = url; // the absolute URL that will allow the document to be saved onto the user personal computer
embedded.embedUrl = url; // the absolute URL to the document serving as a source file for the document embedded into the web page
embedded.shareUrl = url; // the absolute URL that will allow other users to share this document
embedded.toolbarDocked = "top"; // the place for the embedded viewer toolbar, can be either top or bottom
}
// default user parameters (id, name and group)
public class User
{
public String id;
public String name;
public String group;
}
// customization parameters
public class Customization
{
public Goback goback;
public Boolean forcesave;
public Boolean submitForm;
public Customization()
{
forcesave = false;
goback = new Goback();
}
public class Goback
{
public String url;
}
}
// parameters for embedded document
public class Embedded
{
public String saveUrl;
public String embedUrl;
public String shareUrl;
public String toolbarDocked;
}
}
// turn java objects into json strings
public static String Serialize(FileModel model)
{
Gson gson = new Gson();
return gson.toJson(model);
}
}
@@ -0,0 +1,26 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.jero.modules.ocr.entity;
public enum FileType
{
Word,
Cell,
Slide
}
@@ -0,0 +1,48 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.jero.modules.ocr.entity;
import java.util.List;
public class User {
public String id;
public String name;
public String email;
public String group;
public List<String> reviewGroups;
public CommentGroups commentGroups;
public Boolean favorite;
public List<String> deniedPermissions;
public List<String> descriptions;
public Boolean templates;
public User(String id, String name, String email, String group, List<String> reviewGroups, CommentGroups commentGroups,
Boolean favorite, List<String> deniedPermissions, List<String> descriptions, Boolean templates) {
this.id = id;
this.name = name;
this.email = email;
this.group = group;
this.reviewGroups = reviewGroups;
this.commentGroups = commentGroups;
this.favorite = favorite;
this.deniedPermissions = deniedPermissions;
this.descriptions = descriptions;
this.templates = templates;
}
}
@@ -0,0 +1,61 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.jero.modules.ocr.helpers;
import java.io.InputStream;
import java.util.Properties;
public class ConfigManager
{
private static Properties properties;
static
{
Init();
}
private static void Init()
{
try
{
// get stream from the settings.properties resource and load it
properties = new Properties();
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("settings.properties");
properties.load(stream);
}
catch (Exception ex)
{
properties = null;
}
}
// get name from the settings.properties file
public static String GetProperty(String name)
{
if (properties == null)
{
return "";
}
// get property by its name
String property = properties.getProperty(name);
return property == null ? "" : property;
}
}
@@ -0,0 +1,45 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.jero.modules.ocr.helpers;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
public class CookieManager {
private HashMap<String, String> cookiesMap;
public CookieManager(HttpServletRequest request) throws UnsupportedEncodingException {
cookiesMap = new HashMap<String, String>();
Cookie[] cookies = request.getCookies(); // get all the cookies from the request
if (cookies != null) {
for (Cookie cookie : cookies) { // run through all the cookies
cookiesMap.putIfAbsent(cookie.getName(), URLDecoder.decode(cookie.getValue(), "UTF-8")); // add cookie to the cookies map if its name isn't in the map yet
}
}
}
// get cookie by its name
public String getCookie(String name) {
return cookiesMap.get(name);
}
}
@@ -0,0 +1,519 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.jero.modules.ocr.helpers;
import com.jero.modules.ocr.entity.FileType;
import com.jero.modules.ocr.entity.User;
import org.json.simple.JSONObject;
import org.primeframework.jwt.Signer;
import org.primeframework.jwt.Verifier;
import org.primeframework.jwt.domain.JWT;
import org.primeframework.jwt.hmac.HMACSigner;
import org.primeframework.jwt.hmac.HMACVerifier;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.InetAddress;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;
public class DocumentManager
{
private static HttpServletRequest request;
public static void Init(HttpServletRequest req, HttpServletResponse resp)
{
request = req;
}
// get max file size
public static long GetMaxFileSize()
{
long size;
try
{
size = Long.parseLong(ConfigManager.GetProperty("filesize-max"));
}
catch (Exception ex)
{
size = 0;
}
return size > 0 ? size : 5 * 1024 * 1024;
}
// get all the supported file extensions
public static List<String> GetFileExts()
{
List<String> res = new ArrayList<>();
res.addAll(GetViewedExts());
res.addAll(GetEditedExts());
res.addAll(GetConvertExts());
res.addAll(GetFillExts());
return res;
}
public static List<String> GetFillExts() {
String exts = ConfigManager.GetProperty("files.docservice.fill-docs");
return Arrays.asList(exts.split("\\|"));
}
// get file extensions that can be viewed
public static List<String> GetViewedExts()
{
String exts = ConfigManager.GetProperty("files.docservice.viewed-docs");
return Arrays.asList(exts.split("\\|"));
}
// get file extensions that can be edited
public static List<String> GetEditedExts()
{
String exts = ConfigManager.GetProperty("files.docservice.edited-docs");
return Arrays.asList(exts.split("\\|"));
}
// get file extensions that can be converted
public static List<String> GetConvertExts()
{
String exts = ConfigManager.GetProperty("files.docservice.convert-docs");
return Arrays.asList(exts.split("\\|"));
}
// get current user host address
public static String CurUserHostAddress(String userAddress)
{
if(userAddress == null)
{
try
{
// use InetAddress class to get the user address if it wasn't passed to the function
userAddress = InetAddress.getLocalHost().getHostAddress();
}
catch (Exception ex)
{
userAddress = "";
}
}
return userAddress.replaceAll("[^0-9a-zA-Z.=]", "_");
}
// get the root directory of the user host
public static String FilesRootPath(String userAddress)
{
String hostAddress = CurUserHostAddress(userAddress); // get current user host address
String serverPath = request.getSession().getServletContext().getRealPath(""); // get the server url
String storagePath = ConfigManager.GetProperty("storage-folder"); // get the storage directory
String directory = serverPath + storagePath + File.separator + hostAddress + File.separator;
File file = new File(directory);
// if the root directory doesn't exist
if (!file.exists())
{
// create it
file.mkdirs();
}
return directory;
}
// get the storage path of the file
public static String StoragePath(String fileName, String userAddress)
{
String directory = FilesRootPath(userAddress);
return directory + FileUtility.GetFileName(fileName);
}
// get the path to the forcesaved file version
public static String ForcesavePath(String fileName, String userAddress, Boolean create)
{
String hostAddress = CurUserHostAddress(userAddress);
String serverPath = request.getSession().getServletContext().getRealPath("");
String storagePath = ConfigManager.GetProperty("storage-folder");
// create the directory to this file version
String directory = serverPath + storagePath + File.separator + hostAddress + File.separator;
File file = new File(directory);
if (!file.exists()) return "";
// create the directory to the history of this file version
directory = directory + fileName + "-hist" + File.separator;
file = new File(directory);
if (!create && !file.exists()) return "";
file.mkdirs();
directory = directory + fileName;
file = new File(directory);
if (!create && !file.exists()) {
return "";
}
return directory;
}
// get the history directory
public static String HistoryDir(String storagePath)
{
return storagePath += "-hist";
}
// get the path to the file version by the history path and file version
public static String VersionDir(String histPath, Integer version)
{
return histPath + File.separator + Integer.toString(version);
}
// get the path to the file version by the file name, user address and file version
public static String VersionDir(String fileName, String userAddress, Integer version)
{
return VersionDir(HistoryDir(StoragePath(fileName, userAddress)), version);
}
// get the file version by the history path
public static Integer GetFileVersion(String historyPath)
{
File dir = new File(historyPath);
if (!dir.exists()) return 1; // if the history path doesn't exist, then the file version is 1
File[] dirs = dir.listFiles(new FileFilter() { // take only directories from the history folder
@Override
public boolean accept(File pathname) {
return pathname.isDirectory();
}
});
return dirs.length + 1; // count the directories
}
// get the file version by the file name and user address
public static int GetFileVersion(String fileName, String userAddress)
{
return GetFileVersion(HistoryDir(StoragePath(fileName, userAddress)));
}
// get a file name with an index if the file with such a name already exists
public static String GetCorrectName(String fileName, String userAddress)
{
String baseName = FileUtility.GetFileNameWithoutExtension(fileName);
String ext = FileUtility.GetFileExtension(fileName);
String name = baseName + ext;
File file = new File(StoragePath(name, userAddress));
for (int i = 1; file.exists(); i++) // run through all the files with such a name in the storage directory
{
name = baseName + " (" + i + ")" + ext; // and add an index to the base name
file = new File(StoragePath(name, userAddress));
}
return name;
}
// create meta information
public static void CreateMeta(String fileName, String uid, String uname, String userAddress) throws Exception
{
String histDir = HistoryDir(StoragePath(fileName, userAddress));
File dir = new File(histDir); // create history directory
dir.mkdir();
// create json object and put there file information (creation time, user id and name)
JSONObject json = new JSONObject();
json.put("created", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
json.put("id", uid);
json.put("name", uname);
// create createdInfo.json file with meta information in the history directory
File meta = new File(histDir + File.separator + "createdInfo.json");
try (FileWriter writer = new FileWriter(meta)) {
json.writeJSONString(writer); // write information from the json object into this file
}
}
// get all the stored files from the user host address
public static File[] GetStoredFiles(String userAddress)
{
String directory = FilesRootPath(userAddress);
File file = new File(directory);
return file.listFiles(new FileFilter() { // take only files from the root directory
@Override
public boolean accept(File pathname) {
return pathname.isFile();
}
});
}
// create demo document
public static String CreateDemo(String fileExt, Boolean sample, User user) throws Exception
{
String demoName = (sample ? "sample." : "new.") + fileExt; // create sample or new template file with the necessary extension
String demoPath = "assets" + File.separator + (sample ? "sample" : "new") + File.separator; // get the path to the sample document
String fileName = GetCorrectName(demoName, null); // get a file name with an index if the file with such a name already exists
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(demoPath + demoName); // get the input file stream
CreateFile(Paths.get(StoragePath(fileName, null)), stream);
// create meta information of the demo file
CreateMeta(fileName, user.id, user.name, null);
return fileName;
}
public static boolean CreateFile(Path path, InputStream stream) {
if (Files.exists(path)){
return true;
}
try {
File file = Files.createFile(path).toFile();
try (FileOutputStream out = new FileOutputStream(file))
{
int read;
final byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1)
{
out.write(bytes, 0, read);
}
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
// get file url
public static String GetFileUri(String fileName, Boolean forDocumentServer)
{
try
{
String serverPath = GetServerUrl(forDocumentServer);
String storagePath = ConfigManager.GetProperty("storage-folder");
String hostAddress = CurUserHostAddress(null);
String filePath = serverPath + "/" + storagePath + "/" + hostAddress + "/" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()).replace("+", "%20");
// String filePath = serverPath + "?fileName=" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()).replace("+", "%20") + "&useraddress=" + hostAddress;
return filePath;
}
catch (UnsupportedEncodingException e)
{
return "";
}
}
// get file information
public static ArrayList<Map<String, Object>> GetFilesInfo(){
ArrayList<Map<String, Object>> files = new ArrayList<>();
// run through all the stored files
for(File file : GetStoredFiles(null)){
Map<String, Object> map = new LinkedHashMap<>(); // write all the parameters to the map
map.put("version", GetFileVersion(file.getName(), null));
map.put("id", ServiceConverter.GenerateRevisionId(CurUserHostAddress(null) + "/" + file.getName() + "/" + Long.toString(new File(StoragePath(file.getName(), null)).lastModified())));
map.put("contentLength", new BigDecimal(String.valueOf((file.length()/1024.0))).setScale(2, RoundingMode.HALF_UP) + " KB");
map.put("pureContentLength", file.length());
map.put("title", file.getName());
map.put("updated", String.valueOf(new Date(file.lastModified())));
files.add(map);
}
return files;
}
// get file information by its id
public static ArrayList<Map<String, Object>> GetFilesInfo(String fileId){
ArrayList<Map<String, Object>> file = new ArrayList<>();
for (Map<String, Object> map : GetFilesInfo()){
if (map.get("id").equals(fileId)){
file.add(map);
break;
}
}
return file;
}
// get the path url
public static String GetPathUri(String path)
{
String serverPath = GetServerUrl(true);
String storagePath = ConfigManager.GetProperty("storage-folder");
String hostAddress = CurUserHostAddress(null);
String filePath = serverPath + "/" + storagePath + "/" + hostAddress + "/" + path.replace(File.separator, "/").substring(FilesRootPath(null).length()).replace(" ", "%20");
return filePath;
}
// get the server url
public static String GetServerUrl(Boolean forDocumentServer) {
if (forDocumentServer && !ConfigManager.GetProperty("files.docservice.url.example").equals("")) {
return ConfigManager.GetProperty("files.docservice.url.example");
} else {
return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
}
}
// get the callback url
public static String GetCallback(String fileName)
{
String serverPath = GetServerUrl(true);
String hostAddress = CurUserHostAddress(null);
try
{
String query = "?type=track&fileName=" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()) + "&userAddress=" + URLEncoder.encode(hostAddress, java.nio.charset.StandardCharsets.UTF_8.toString());
return serverPath + "/IndexServlet" + query;
}
catch (UnsupportedEncodingException e)
{
return "";
}
}
// get url to the created file
public static String GetCreateUrl (FileType fileType) {
String serverPath = GetServerUrl(false);
String fileExt = GetInternalExtension(fileType).replace(".", "");
String query = "?fileExt=" + fileExt;
return serverPath + "/EditorServlet" + query;
}
// get url to download a file
public static String GetDownloadUrl(String fileName) {
String serverPath = GetServerUrl(true);
String hostAddress = CurUserHostAddress(null);
try
{
String query = "?type=download&fileName=" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()) + "&userAddress=" + URLEncoder.encode(hostAddress, java.nio.charset.StandardCharsets.UTF_8.toString());
return serverPath + "/IndexServlet" + query;
}
catch (UnsupportedEncodingException e)
{
return "";
}
}
// get an editor internal extension
public static String GetInternalExtension(FileType fileType)
{
// .docx for word file type
if (fileType.equals(FileType.Word))
return ".docx";
// .xlsx for cell file type
if (fileType.equals(FileType.Cell))
return ".xlsx";
// .pptx for slide file type
if (fileType.equals(FileType.Slide))
return ".pptx";
// the default file type is .docx
return ".docx";
}
// get image url for templates
public static String GetTemplateImageUrl(FileType fileType)
{
String path = GetServerUrl(true) + "/css/img/";
// for word file type
if (fileType.equals(FileType.Word))
return path + "file_docx.svg";
// .xlsx for cell file type
if (fileType.equals(FileType.Cell))
return path + "file_xlsx.svg";
// .pptx for slide file type
if (fileType.equals(FileType.Slide))
return path + "file_pptx.svg";
// the default file type
return path + "file_docx.svg";
}
// create document token
public static String CreateToken(Map<String, Object> payloadClaims)
{
try
{
// build a HMAC signer using a SHA-256 hash
Signer signer = HMACSigner.newSHA256Signer(GetTokenSecret());
JWT jwt = new JWT();
for (String key : payloadClaims.keySet()) // run through all the keys from the payload
{
jwt.addClaim(key, payloadClaims.get(key)); // and write each claim to the jwt
}
return JWT.getEncoder().encode(jwt, signer); // sign and encode the JWT to a JSON string representation
}
catch (Exception e)
{
return "";
}
}
// read document token
public static JWT ReadToken(String token)
{
try
{
// build a HMAC verifier using the token secret
Verifier verifier = HMACVerifier.newVerifier(GetTokenSecret());
return JWT.getDecoder().decode(token, verifier); // verify and decode the encoded string JWT to a rich object
}
catch (Exception exception)
{
return null;
}
}
// check if the token is enabled
public static Boolean TokenEnabled()
{
String secret = GetTokenSecret();
return secret != null && !secret.isEmpty();
}
// get token secret from the config parameters
public static String GetTokenSecret()
{
return ConfigManager.GetProperty("files.docservice.secret");
}
}
@@ -0,0 +1,132 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.jero.modules.ocr.helpers;
import com.jero.modules.ocr.entity.FileType;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class FileUtility
{
static {}
// get file type
public static FileType GetFileType(String fileName)
{
String ext = GetFileExtension(fileName).toLowerCase();
// word type for document extensions
if (ExtsDocument.contains(ext))
return FileType.Word;
// cell type for spreadsheet extensions
if (ExtsSpreadsheet.contains(ext))
return FileType.Cell;
// slide type for presentation extensions
if (ExtsPresentation.contains(ext))
return FileType.Slide;
// default file type is word
return FileType.Word;
}
// document extensions
public static List<String> ExtsDocument = Arrays.asList
(
".doc", ".docx", ".docm",
".dot", ".dotx", ".dotm",
".odt", ".fodt", ".ott", ".rtf", ".txt",
".html", ".htm", ".mht", ".xml",
".pdf", ".djvu", ".fb2", ".epub", ".xps", ".oxps", ".oform"
);
// spreadsheet extensions
public static List<String> ExtsSpreadsheet = Arrays.asList
(
".xls", ".xlsx", ".xlsm",
".xlt", ".xltx", ".xltm",
".ods", ".fods", ".ots", ".csv"
);
// presentation extensions
public static List<String> ExtsPresentation = Arrays.asList
(
".pps", ".ppsx", ".ppsm",
".ppt", ".pptx", ".pptm",
".pot", ".potx", ".potm",
".odp", ".fodp", ".otp"
);
// get file name from the url
public static String GetFileName(String url)
{
if (url == null) return "";
// get file name from the last part of url
String fileName = url.substring(url.lastIndexOf('/') + 1, url.length());
fileName = fileName.split("\\?")[0];
return fileName;
}
// get file name without extension
public static String GetFileNameWithoutExtension(String url)
{
String fileName = GetFileName(url);
if (fileName == null) return null;
String fileNameWithoutExt = fileName.substring(0, fileName.lastIndexOf('.'));
return fileNameWithoutExt;
}
// get file extension from url
public static String GetFileExtension(String url)
{
String fileName = GetFileName(url);
if (fileName == null) return null;
String fileExt = fileName.substring(fileName.lastIndexOf("."));
return fileExt.toLowerCase();
}
// get url parameters
public static Map<String, String> GetUrlParams(String url)
{
try
{
String query = new URL(url).getQuery(); // take all the parameters which are placed after ? sign in the file url
String[] params = query.split("&"); // parameters are separated by & sign
Map<String, String> map = new HashMap<>();
for (String param : params) // write parameters and their values to the map dictionary
{
String name = param.split("=")[0];
String value = param.split("=")[1];
map.put(name, value);
}
return map;
}
catch (Exception ex)
{
return null;
}
}
}
@@ -0,0 +1,269 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.jero.modules.ocr.helpers;
import com.google.gson.Gson;
import com.jero.modules.ocr.util.UUIDUtils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class ServiceConverter
{
private static int ConvertTimeout = 120000;
private static final String DocumentConverterUrl = ConfigManager.GetProperty("files.docservice.url.site") + ConfigManager.GetProperty("files.docservice.url.converter");
private static final String DocumentJwtHeader = ConfigManager.GetProperty("files.docservice.header");
public static class ConvertBody
{
public String region;
public String url;
public String outputtype;
public String filetype;
public String title;
public String key;
public Boolean async;
public String token;
public String password;
}
static
{
try
{
// get timeout value from the settings.properties
int timeout = Integer.parseInt(ConfigManager.GetProperty("files.docservice.timeout"));
if (timeout > 0) // if it's greater than 0
{
ConvertTimeout = timeout; // assign this value to a convert timeout
}
}
catch (Exception ex)
{
}
}
// get the url of the converted file
public static String GetConvertedUri(String documentUri, String fromExtension, String toExtension, String documentRevisionId, String filePass, Boolean isAsync, String lang) throws Exception
{
// check if the fromExtension parameter is defined; if not, get it from the document url
fromExtension = fromExtension == null || fromExtension.isEmpty() ? FileUtility.GetFileExtension(documentUri) : fromExtension;
// check if the file name parameter is defined; if not, get random uuid for this file
String title = FileUtility.GetFileName(documentUri);
title = title == null || title.isEmpty() ? UUID.randomUUID().toString() : title;
documentRevisionId = documentRevisionId == null || documentRevisionId.isEmpty() ? documentUri : documentRevisionId;
documentRevisionId = GenerateRevisionId(documentRevisionId); // create document token
// write all the necessary parameters to the body object
ConvertBody body = new ConvertBody();
body.region = lang;
body.url = documentUri;
body.outputtype = toExtension.replace(".", "");
body.filetype = fromExtension.replace(".", "");
body.title = title;
body.key = documentRevisionId;
body.password = filePass;
if (isAsync)
body.async = true;
String headerToken = "";
if (DocumentManager.TokenEnabled())
{
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("region", lang);
map.put("url", body.url);
map.put("outputtype", body.outputtype);
map.put("filetype", body.filetype);
map.put("title", body.title);
map.put("key", body.key);
map.put("password", body.password);
if (isAsync)
map.put("async", body.async);
// add token to the body if it is enabled
String token = DocumentManager.CreateToken(map);
body.token = token;
Map<String, Object> payloadMap = new HashMap<String, Object>();
payloadMap.put("payload", map); // create payload object
headerToken = DocumentManager.CreateToken(payloadMap); // create header token
}
Gson gson = new Gson();
String bodyString = gson.toJson(body);
byte[] bodyByte = bodyString.getBytes(StandardCharsets.UTF_8);
// specify request parameters
URL url = new URL(DocumentConverterUrl);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setFixedLengthStreamingMode(bodyByte.length);
connection.setRequestProperty("Accept", "application/json");
connection.setConnectTimeout(ConvertTimeout);
// write header token to the request
if (DocumentManager.TokenEnabled())
{
connection.setRequestProperty(DocumentJwtHeader.equals("") ? "Authorization" : DocumentJwtHeader, "Bearer " + headerToken);
}
connection.connect();
try (OutputStream os = connection.getOutputStream()) {
os.write(bodyByte);
}
InputStream stream = connection.getInputStream();
if (stream == null)
throw new Exception("Could not get an answer");
// convert string to json
String jsonString = ConvertStreamToString(stream);
connection.disconnect();
return GetResponseUri(jsonString);
}
// generate document key
public static String GenerateRevisionId(String expectedKey)
{
if (expectedKey.length() > 20) // if the expected key length is greater than 20
expectedKey = Integer.toString(expectedKey.hashCode()); // the expected key is hashed and a fixed length value is stored in the string format
String key = UUIDUtils.randomUUID(2) + expectedKey.replace("[^0-9-.a-zA-Z_=]", "_");
return key.substring(0, Math.min(key.length(), 20)); // the resulting key length is 20 or less
}
// create an error message for an error code
private static void ProcessConvertServiceResponceError(int errorCode) throws Exception
{
String errorMessage = "";
String errorMessageTemplate = "Error occurred in the ConvertService: ";
// add the error message to the error message template depending on the error code
switch (errorCode)
{
case -8:
errorMessage = errorMessageTemplate + "Error document VKey";
break;
case -7:
errorMessage = errorMessageTemplate + "Error document request";
break;
case -6:
errorMessage = errorMessageTemplate + "Error database";
break;
case -5:
errorMessage = errorMessageTemplate + "Incorrect password";
break;
case -4:
errorMessage = errorMessageTemplate + "Error download error";
break;
case -3:
errorMessage = errorMessageTemplate + "Error convertation error";
break;
case -2:
errorMessage = errorMessageTemplate + "Error convertation timeout";
break;
case -1:
errorMessage = errorMessageTemplate + "Error convertation unknown";
break;
case 0: // if the error code is equal to 0, the error message is empty
break;
default:
errorMessage = "ErrorCode = " + errorCode; // default value for the error message
break;
}
throw new Exception(errorMessage);
}
// get the response url
private static String GetResponseUri(String jsonString) throws Exception
{
JSONObject jsonObj = ConvertStringToJSON(jsonString);
Object error = jsonObj.get("error");
if (error != null) // if an error occurs
ProcessConvertServiceResponceError(Math.toIntExact((long)error)); // then get an error message
// check if the conversion is completed and save the result to a variable
Boolean isEndConvert = (Boolean) jsonObj.get("endConvert");
Long resultPercent = 0l;
String responseUri = null;
if (isEndConvert) // if the conversion is completed
{
resultPercent = 100l;
responseUri = (String) jsonObj.get("fileUrl"); // get the file url
}
else // if the conversion isn't completed
{
resultPercent = (Long) jsonObj.get("percent");
resultPercent = resultPercent >= 100l ? 99l : resultPercent; // get the percentage value
}
return resultPercent >= 100l ? responseUri : "";
}
// convert stream to string
public static String ConvertStreamToString(InputStream stream) throws IOException
{
InputStreamReader inputStreamReader = new InputStreamReader(stream); // create an object to get incoming stream
StringBuilder stringBuilder = new StringBuilder(); // create a string builder object
BufferedReader bufferedReader = new BufferedReader(inputStreamReader); // create an object to read incoming streams
String line = bufferedReader.readLine(); // get incoming streams by lines
while (line != null)
{
stringBuilder.append(line); // concatenate strings using the string builder
line = bufferedReader.readLine();
}
String result = stringBuilder.toString();
return result;
}
// convert string to json
public static JSONObject ConvertStringToJSON(String jsonString) throws ParseException
{
JSONParser parser = new JSONParser();
Object obj = parser.parse(jsonString); // parse json string
JSONObject jsonObj = (JSONObject) obj; // and turn it into a json object
return jsonObj;
}
}
@@ -0,0 +1,323 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.jero.modules.ocr.helpers;
import com.google.gson.Gson;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.primeframework.jwt.domain.JWT;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;
public class TrackManager {
private static final String DocumentJwtHeader = ConfigManager.GetProperty("files.docservice.header");
// read request body
public static JSONObject readBody(HttpServletRequest request, PrintWriter writer) throws Exception {
String bodyString = "";
try {
// read request body by streams
Scanner scanner = new Scanner(request.getInputStream());
scanner.useDelimiter("\\A");
bodyString = scanner.hasNext() ? scanner.next() : "";
scanner.close();
}
catch (Exception ex) {
writer.write("get request.getInputStream error:" + ex.getMessage());
throw ex;
}
// error when the bodyString object is empty
if (bodyString.isEmpty()) {
writer.write("empty request.getInputStream");
throw new Exception("empty request.getInputStream");
}
JSONParser parser = new JSONParser();
JSONObject body;
try {
Object obj = parser.parse(bodyString); // parse bodyString object
body = (JSONObject) obj;
} catch (Exception ex) {
writer.write("JSONParser.parse error:" + ex.getMessage());
throw ex;
}
// if the secret key to generate token exists
if (DocumentManager.TokenEnabled()) {
String token = (String) body.get("token"); // get the document token
if (token == null) { // if JSON web token is not received
String header = (String) request.getHeader(DocumentJwtHeader == null || DocumentJwtHeader.isEmpty() ? "Authorization" : DocumentJwtHeader); // get it from the Authorization header
if (header != null && !header.isEmpty()) {
token = header.startsWith("Bearer ") ? header.substring(7) : header; // and save it without Authorization prefix
}
}
if (token == null || token.isEmpty()) { // if the token is not received
writer.write("{\"error\":1,\"message\":\"JWT expected\"}"); // an error occurs
throw new Exception("{\"error\":1,\"message\":\"JWT expected\"}");
}
JWT jwt = DocumentManager.ReadToken(token); // read token
if (jwt == null) {
writer.write("{\"error\":1,\"message\":\"JWT validation failed\"}"); // an error occurs
throw new Exception("{\"error\":1,\"message\":\"JWT validation failed\"}");
}
if (jwt.getObject("payload") != null) { // get the payload object from the request body
try {
@SuppressWarnings("unchecked") LinkedHashMap<String, Object> payload =
(LinkedHashMap<String, Object>)jwt.getObject("payload");
jwt.claims = payload;
} catch (Exception ex) {
writer.write("{\"error\":1,\"message\":\"Wrong payload\"}");
throw ex;
}
}
try {
Gson gson = new Gson();
Object obj = parser.parse(gson.toJson(jwt.claims));
body = (JSONObject) obj;
} catch (Exception ex) {
writer.write("JSONParser.parse error:" + ex.getMessage());
throw ex;
}
}
return body;
}
// file saving process
public static void processSave(JSONObject body, String fileName, String userAddress) throws Exception {
if (body.get("url") == null) {
throw new Exception("DownloadUrl is null");
}
String downloadUri = (String) body.get("url");
String changesUri = (String) body.get("changesurl");
String key = (String) body.get("key");
String newFileName = fileName;
String curExt = FileUtility.GetFileExtension(fileName); // get current file extension
String downloadExt = FileUtility.GetFileExtension(downloadUri); // get the extension of the downloaded file
// convert downloaded file to the file with the current extension if these extensions aren't equal
if (!curExt.equals(downloadExt)) {
try {
String newFileUri = ServiceConverter.GetConvertedUri(downloadUri, downloadExt, curExt, ServiceConverter.GenerateRevisionId(downloadUri), null, false, null); // convert file and get url to a new file
if (newFileUri.isEmpty()) {
newFileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress); // get the correct file name if it already exists
} else {
downloadUri = newFileUri;
}
} catch (Exception e){
newFileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
}
}
String storagePath = DocumentManager.StoragePath(newFileName, userAddress); // get the file path
File histDir = new File(DocumentManager.HistoryDir(storagePath)); // get the path to the history direction
if (!histDir.exists()) histDir.mkdirs(); // if the path doesn't exist, create it
String versionDir = DocumentManager.VersionDir(histDir.getAbsolutePath(), DocumentManager.GetFileVersion(histDir.getAbsolutePath())); // get the path to the file version
File ver = new File(versionDir);
File lastVersion = new File(DocumentManager.StoragePath(fileName, userAddress));
File toSave = new File(storagePath);
if (!ver.exists()) ver.mkdirs();
lastVersion.renameTo(new File(versionDir + File.separator + "prev" + curExt)); // get the path to the previous file version and rename the last file version with it
downloadToFile(downloadUri, toSave); // save file to the storage path
downloadToFile(changesUri, new File(versionDir + File.separator + "diff.zip")); // save file changes to the diff.zip archive
String history = (String) body.get("changeshistory");
if (history == null && body.containsKey("history")) {
history = ((JSONObject) body.get("history")).toJSONString();
}
if (history != null && !history.isEmpty()) {
FileWriter fw = new FileWriter(new File(versionDir + File.separator + "changes.json")); // write the history changes to the changes.json file
fw.write(history);
fw.close();
}
FileWriter fw = new FileWriter(new File(versionDir + File.separator + "key.txt")); // write the key value to the key.txt file
fw.write(key);
fw.close();
String forcesavePath = DocumentManager.ForcesavePath(newFileName, userAddress, false); // get the path to the forcesaved file version
if (!forcesavePath.equals("")) { // if the forcesaved file version exists
File forceSaveFile = new File(forcesavePath);
forceSaveFile.delete(); // remove it
}
}
// file force saving process
public static void processForceSave(JSONObject body, String fileName, String userAddress) throws Exception {
if (body.get("url") == null) {
throw new Exception("DownloadUrl is null");
}
String downloadUri = (String) body.get("url");
String curExt = FileUtility.GetFileExtension(fileName); // get current file extension
String downloadExt = FileUtility.GetFileExtension(downloadUri); // get the extension of the downloaded file
Boolean newFileName = false;
// convert downloaded file to the file with the current extension if these extensions aren't equal
if (!curExt.equals(downloadExt)) {
try {
String newFileUri = ServiceConverter.GetConvertedUri(downloadUri, downloadExt, curExt, ServiceConverter.GenerateRevisionId(downloadUri), null, false, null); // convert file and get url to a new file
if (newFileUri.isEmpty()) {
newFileName = true;
} else {
downloadUri = newFileUri;
}
} catch (Exception e){
newFileName = true;
}
}
String forcesavePath = "";
boolean isSubmitForm = body.get("forcesavetype").toString().equals("3"); // SubmitForm
if (isSubmitForm) { // if the form is submitted
// new file
if (newFileName){
fileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + "-form" + downloadExt, userAddress); // get the correct file name if it already exists
} else {
fileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + "-form" + curExt, userAddress);
}
forcesavePath = DocumentManager.StoragePath(fileName, userAddress);
} else {
if (newFileName){
fileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
}
// create forcesave path if it doesn't exist
forcesavePath = DocumentManager.ForcesavePath(fileName, userAddress, false);
if (forcesavePath == "") {
forcesavePath = DocumentManager.ForcesavePath(fileName, userAddress, true);
}
}
File toSave = new File(forcesavePath);
downloadToFile(downloadUri, toSave);
if (isSubmitForm) {
JSONArray actions = (JSONArray) body.get("actions");
JSONObject action = (JSONObject) actions.get(0);
String user = (String) action.get("userid"); // get the user id
DocumentManager.CreateMeta(fileName, user, "Filling Form", userAddress); // create meta data for forcesaved file
}
}
// save file information from the url to the file specified
private static void downloadToFile(String url, File file) throws Exception {
if (url == null || url.isEmpty()) throw new Exception("argument url"); // url isn't specified
if (file == null) throw new Exception("argument path"); // file isn't specified
URL uri = new URL(url);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
InputStream stream = connection.getInputStream(); // get input stream of the file information from the url
if (stream == null)
{
throw new Exception("Stream is null");
}
try (FileOutputStream out = new FileOutputStream(file))
{
int read;
final byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1)
{
out.write(bytes, 0, read); // write bytes to the output stream
}
// force write data to the output stream that can be cached in the current thread
out.flush();
}
connection.disconnect();
}
// create a command request
public static void commandRequest(String method, String key) throws Exception {
String DocumentCommandUrl = ConfigManager.GetProperty("files.docservice.url.site") + ConfigManager.GetProperty("files.docservice.url.command");
URL url = new URL(DocumentCommandUrl);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("c", method);
params.put("key", key);
String headerToken = "";
if (DocumentManager.TokenEnabled()) // check if a secret key to generate token exists or not
{
Map<String, Object> payloadMap = new HashMap<String, Object>();
payloadMap.put("payload", params);
headerToken = DocumentManager.CreateToken(payloadMap); // encode a payload object into a header token
// add a header Authorization with a header token and Authorization prefix in it
connection.setRequestProperty(DocumentJwtHeader.equals("") ? "Authorization" : DocumentJwtHeader, "Bearer " + headerToken);
String token = DocumentManager.CreateToken(params); // encode a payload object into a body token
params.put("token", token);
}
Gson gson = new Gson();
String bodyString = gson.toJson(params);
byte[] bodyByte = bodyString.getBytes(StandardCharsets.UTF_8);
connection.setRequestMethod("POST"); // set the request method
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); // set the Content-Type header
connection.setDoOutput(true); // set the doOutput field to true
connection.connect();
try (OutputStream os = connection.getOutputStream()) {
os.write(bodyByte); // write bytes to the output stream
}
InputStream stream = connection.getInputStream();; // get input stream
if (stream == null)
throw new Exception("Could not get an answer");
String jsonString = ServiceConverter.ConvertStreamToString(stream); // convert stream to json string
connection.disconnect();
JSONObject response = ServiceConverter.ConvertStringToJSON(jsonString); // convert json string to json object
if (!response.get("error").toString().equals("0")){
throw new Exception(response.toJSONString());
}
}
}
@@ -0,0 +1,110 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.jero.modules.ocr.helpers;
import com.jero.modules.ocr.entity.CommentGroups;
import com.jero.modules.ocr.entity.User;
import java.util.*;
public class Users {
static List<String> descr_user_1 = new ArrayList<String>() {{
add("File author by default");
add("Doesnt belong to any group");
add("Can review all the changes");
add("Can perform all actions with comments");
add("The file favorite state is undefined");
add("Can create files from templates using data from the editor");
}};
static List<String> descr_user_2 = new ArrayList<String>() {{
add("Belongs to Group2");
add("Can review only his own changes or changes made by users with no group");
add("Can view comments, edit his own comments and comments left by users with no group. Can remove his own comments only");
add("This file is marked as favorite");
add("Can create new files from the editor");
}};
static List<String> descr_user_3 = new ArrayList<String>() {{
add("Belongs to Group3");
add("Can review changes made by Group2 users");
add("Can view comments left by Group2 and Group3 users. Can edit comments left by Group2 users");
add("This file isnt marked as favorite");
add("Cant copy data from the file to clipboard");
add("Cant download the file");
add("Cant print the file");
add("Can create new files from the editor");
}};
static List<String> descr_user_0 = new ArrayList<String>() {{
add("The name is requested when the editor is opened");
add("Doesnt belong to any group");
add("Can review all the changes");
add("Can perform all actions with comments");
add("The file favorite state is undefined");
add("Can't mention others in comments");
add("Can't create new files from the editor");
}};
private static List<User> users = new ArrayList<User>() {{
add(new User("uid-1", "John Smith", "smith@example.com",
null, null, new CommentGroups(),
null, new ArrayList<String>(), descr_user_1, true));
add(new User("uid-2", "Mark Pottato", "pottato@example.com",
"group-2", Arrays.asList("group-2", ""), new CommentGroups(null, Arrays.asList("group-2", ""), Arrays.asList("group-2")),
true, new ArrayList<String>(), descr_user_2, false));
add(new User("uid-3", "Hamish Mitchell", "mitchell@example.com",
"group-3", Arrays.asList("group-2"), new CommentGroups(Arrays.asList("group-3", "group-2"), Arrays.asList("group-2"), new ArrayList<String>()),
false, Arrays.asList("copy", "download", "print"), descr_user_3, false));
add(new User("uid-0", null, null,
null, null, new CommentGroups(),
null, new ArrayList<String>(), descr_user_0, false));
}};
// get a user by id specified
public static User getUser (String id) {
for (User user : users) {
if (user.id.equals(id)) {
return user;
}
}
return users.get(0);
}
// get a list of all the users
public static List<User> getAllUsers () {
return users;
}
// get a list of users with their names and emails for mentions
public static List<Map<String, Object>> getUsersForMentions (String id) {
List<Map<String, Object>> usersData = new ArrayList<>();
for (User user : users) {
if (!user.id.equals(id) && user.name != null && user.email != null) {
Map<String, Object> data = new HashMap<>();
data.put("name", user.name);
data.put("email", user.email);
usersData.add(data);
}
}
return usersData;
}
}
@@ -1,11 +1,14 @@
package com.jero.modules.project.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jero.modules.project.entity.ProjectRelatedPersonnel;
import com.jero.modules.project.mapper.ProjectRelatedPersonnelMapper;
import com.jero.modules.project.service.IProjectRelatedPersonnelService;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Date;
import java.util.Map;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
@@ -86,4 +89,9 @@ public class ProjectRelatedPersonnelServiceImpl extends ServiceImpl<ProjectRelat
public List<ProjectRelatedPersonnel> queryList() {
return list();
}
@Override
public IPage<ProjectRelatedPersonnel> queryPageList(Map<String, Object> params) {
return null;
}
}
@@ -1109,7 +1109,7 @@ public class FileSplitItemsEOServiceImpl extends ServiceImpl<FileSplitItemsEOMap
// if (fileTypeStr.contains(fileSuffix)) {
// state = "1";
// }
OSSFile oSSFile = ossFileService.uploadLocal(multipartFile, "",state);
OSSFile oSSFile = ossFileService.uploadLocal(multipartFile, "",state,null);
if(oSSFile!=null){
oSSFile = ossFileService.getById(oSSFile.getId());
isText = false;
@@ -1154,7 +1154,7 @@ public class FileSplitItemsEOServiceImpl extends ServiceImpl<FileSplitItemsEOMap
// if (fileTypeStr.contains(fileSuffix)) {
// state = "1";
// }
OSSFile oSSFile = ossFileService.uploadLocal(multipartFile, "", state);
OSSFile oSSFile = ossFileService.uploadLocal(multipartFile, "", state,null);
oSSFile = ossFileService.getById(oSSFile.getId());
if (oSSFile != null) {
oSSFile = ossFileService.getById(oSSFile.getId());
@@ -1198,7 +1198,7 @@ public class FileSplitItemsEOServiceImpl extends ServiceImpl<FileSplitItemsEOMap
String url = nowfilelist.get(0).getPath();
MultipartFile multipartFile = createMfileByPath(url);
String state = "0";
OSSFile oSSFile = ossFileService.uploadLocal(multipartFile, "", state);
OSSFile oSSFile = ossFileService.uploadLocal(multipartFile, "", state,null);
oSSFile = ossFileService.getById(oSSFile.getId());
if (oSSFile != null) {
isText = false;
@@ -1920,7 +1920,7 @@ public class FileSplitItemsEOServiceImpl extends ServiceImpl<FileSplitItemsEOMap
MultipartFile multipartFile =
new MockMultipartFile(nowFileList.get(0).getName(), nowFileList.get(0).getName(), "text/plain", input);
//文件存入文件表
OSSFile ossFile = ossFileService.uploadLocal(multipartFile, "", null);
OSSFile ossFile = ossFileService.uploadLocal(multipartFile, "", null,null);
if (ObjectUtils.isNotEmpty(ossFile)) {
sb.append(ossFile.getId() + ",");
}
@@ -0,0 +1,44 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
html {
height: 100%;
width: 100%;
}
body {
background: #fff;
color: #333;
font-family: Arial, Tahoma,sans-serif;
font-size: 12px;
font-weight: normal;
height: 100%;
margin: 0;
overflow-y: hidden;
padding: 0;
text-decoration: none;
}
.form {
height: 100%;
}
div {
margin: 0;
padding: 0;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

@@ -0,0 +1,24 @@
version=1.1.0
filesize-max=5242880
storage-folder=D:\\OOFILES
files.docservice.fill-docs=.oform|.docx
files.docservice.viewed-docs=.pdf|.djvu|.xps|.oxps
files.docservice.edited-docs=.docx|.xlsx|.csv|.pptx|.txt|.docxf
files.docservice.convert-docs=.docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.xml|.epub|.fb2
files.docservice.timeout=120000
files.docservice.url.site=http://172.29.96.1:9000/
files.docservice.url.command=http://172.29.96.1:9000/coauthoring/CommandService.ashx
files.docservice.url.converter= http://172.29.96.1:9000/ConvertService.ashx
files.docservice.url.tempstorage= http://172.29.96.1:9000/ResourceService.ashx
files.docservice.url.api= http://172.29.96.1:9000/web-apps/apps/api/documents/api.js
files.docservice.url.preloader= http://172.29.96.1:9000/web-apps/apps/api/documents/cache-scripts.html
files.docservice.url.example= http://172.29.96.1:9000
files.docservice.secret=
files.docservice.header=Authorization
@@ -0,0 +1,127 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ONLYOFFICE</title>
<link rel="icon" href="../asstes/favicon.ico" type="image/x-icon" />
<body>
<script type="text/javascript" th:src="${docserviceApiUrl}"></script>
<script type="text/javascript" language="javascript">
var docEditor;
var fileName = "[[${fileName}]]";
var fileType = "[[${fileType}]]";
var innerAlert = function (message) {
if (console && console.log)
console.log(message);
};
var onReady = function () {
innerAlert("Document editor ready");
};
var onDocumentStateChange = function (event) {
var title = document.title.replace(/\*$/g, "");
document.title = title + (event.data ? "*" : "");
};
var onRequestEditRights = function () {
location.href = location.href.replace(RegExp("action=view\&?", "i"), "");
};
var onError = function (event) {
if (event)
innerAlert(event.data);
};
var onOutdatedVersion = function (event) {
location.reload(true);
};
var сonnectEditor = function () {
docEditor = new DocsAPI.DocEditor("iframeEditor",
{
type: "[[${type}]]",
documentType: "[[${documentType}]]",
document: {
title:"[[${fileName}]]",
url: "[[${fileUri}]]",
fileType: "[[${fileType}]]",
key: "[[${fileKey}]]",
info: {
author: "Me",
created: "[[${documentCreated}]]",
},
permissions: {
edit: "[[${permissionsEdit}]]",
download: true,
}
},
editorConfig: {
mode: "[[${editorMode}]]",
lang: "cn",
callbackUrl: "[[${callbackUrl}]]",
user: {
id: "[[${editorUserId}]]",
name: "[[${editorUserName}]]",
},
embedded: {
saveUrl: "[[${fileUri}]]",
embedUrl: "[[${fileUri}]]",
shareUrl: "[[${fileUri}]]",
toolbarDocked: "top",
},
customization: {
about: true,
feedback: true,
goback: {
url: "[[${serverUrl}]]",
},
},
},
events: {
"onReady": onReady,
"onDocumentStateChange": onDocumentStateChange,
'onRequestEditRights': onRequestEditRights,
"onError": onError,
"onOutdatedVersion": onOutdatedVersion,
}
});
};
if (window.addEventListener) {
window.addEventListener("load", сonnectEditor);
} else if (window.attachEvent) {
window.attachEvent("load", сonnectEditor);
}
function getXmlHttp() {
var xmlhttp;
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (ex) {
xmlhttp = false;
}
}
if (!xmlhttp && typeof XMLHttpRequest !== "undefined") {
xmlhttp = new XMLHttpRequest();
}
return xmlhttp;
}
</script>
</head>
<div class="form" style="height: 900px;">
<div id="iframeEditor" ></div>
</div>
</body>
</html>
@@ -195,7 +195,7 @@ jero :
path :
#文件上传根目录 设置
upload: D://opt//upFiles
img: D://opt//upFiles
img: D://opt//upFiles/
#webapp文件路径
webapp: D://opt//webapp
shiro:
@@ -324,9 +324,12 @@ OCR:
# OCR文件存储路径
ocrPath: D:/APPSOFT/LAWSOCRDEMO/OCRFILE/
#ocrPath: /data/DeploymentPackage/laws-shanqi/APPSOFT/LAWSOCRDEMO/OCRFILE/
# OCR文件下载地址
# ocrDownPath: http://139.9.235.66:9020/downfile/
ocrDownPath: http://127.0.0.1:9020/downfile/
# OCR文件下载地址(onlyoffice专用)
ocrDownPath: http://10.0.1.25:8080/jero-boot/ocr/ocrCheck/downFile
# OCR文件保存地址(onlyoffice专用)
ocrSavePath: http://10.0.1.25:8080/jero-boot/ocr/ocrCheck/saveFile
# OCR文件编辑失败返回列表页(onlyoffice专用)
serverUrl: http://10.0.1.25:3000/docManage/ocr
# OCR接口超时时间
times: 20
# OCR转换类型