|
|
@@ -1,329 +0,0 @@
|
|
|
-package com.uas.report.service.impl;
|
|
|
-
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileOutputStream;
|
|
|
-import java.io.IOException;
|
|
|
-import java.io.InputStream;
|
|
|
-import java.net.URI;
|
|
|
-import java.net.URISyntaxException;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Date;
|
|
|
-import java.util.List;
|
|
|
-
|
|
|
-import org.apache.commons.io.IOUtils;
|
|
|
-import org.apache.http.HttpResponse;
|
|
|
-import org.apache.http.NameValuePair;
|
|
|
-import org.apache.http.client.ClientProtocolException;
|
|
|
-import org.apache.http.client.HttpClient;
|
|
|
-import org.apache.http.client.methods.HttpGet;
|
|
|
-import org.apache.http.client.methods.HttpRequestBase;
|
|
|
-import org.apache.http.client.utils.URIBuilder;
|
|
|
-import org.apache.http.impl.client.HttpClients;
|
|
|
-import org.apache.http.message.BasicNameValuePair;
|
|
|
-import org.slf4j.Logger;
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
-
|
|
|
-import com.alibaba.fastjson.JSONObject;
|
|
|
-import com.uas.report.JasperserverRestAPIProperties;
|
|
|
-import com.uas.report.SpecialProperties;
|
|
|
-import com.uas.report.model.Resource;
|
|
|
-import com.uas.report.service.FileService;
|
|
|
-import com.uas.report.service.ResourceService;
|
|
|
-import com.uas.report.util.CollectionUtils;
|
|
|
-
|
|
|
-/**
|
|
|
- * 管理报表模板、图片等资源
|
|
|
- *
|
|
|
- * @author sunyj
|
|
|
- * @since 2016年9月23日 下午5:23:42
|
|
|
- */
|
|
|
-@Service
|
|
|
-public class ResourceServiceImpl implements ResourceService {
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private JasperserverRestAPIProperties jsRestAPIProperties;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private SpecialProperties specialProperties;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private FileService fileService;
|
|
|
-
|
|
|
- private Logger logger = LoggerFactory.getLogger(getClass());
|
|
|
-
|
|
|
- // 是否为windows系统
|
|
|
- private boolean isWindowsPlatform = System.getProperty("os.name").toLowerCase().startsWith("win");
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<Resource> syncResources(String userName)
|
|
|
- throws ClientProtocolException, URISyntaxException, IOException {
|
|
|
- // logger.info("Synchronizing resources...");
|
|
|
- List<Resource> synchronizingResources = getSynchronizingResources(userName);
|
|
|
- if (!CollectionUtils.isEmpty(synchronizingResources)) {
|
|
|
- for (Resource synchronizingResource : synchronizingResources) {
|
|
|
- downloadFile(synchronizingResource);
|
|
|
- }
|
|
|
- }
|
|
|
- // logger.info("Synchronized");
|
|
|
- return synchronizingResources;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 与本地进行比较,返回需要同步的资源
|
|
|
- *
|
|
|
- * @param resources
|
|
|
- * 用于比较的资源
|
|
|
- * @param userName
|
|
|
- * 账套名
|
|
|
- * @return 需要进行同步的资源
|
|
|
- * @throws IOException
|
|
|
- * @throws URISyntaxException
|
|
|
- * @throws ClientProtocolException
|
|
|
- */
|
|
|
- private List<Resource> getSynchronizingResources(String userName)
|
|
|
- throws ClientProtocolException, URISyntaxException, IOException {
|
|
|
- List<Resource> synchronizingResources = new ArrayList<>();
|
|
|
- List<Resource> remoteResources = getRemoteResources("/" + userName);
|
|
|
- if (CollectionUtils.isEmpty(remoteResources)) {
|
|
|
- return synchronizingResources;
|
|
|
- }
|
|
|
-
|
|
|
- List<Resource> localResources = getLocalResources(userName);
|
|
|
- for (Resource remoteResource : remoteResources) {
|
|
|
- if (needSynchronized(remoteResource, localResources)) {
|
|
|
- synchronizingResources.add(remoteResource);
|
|
|
- }
|
|
|
- }
|
|
|
- return synchronizingResources;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 比较远程资源是否需要同步
|
|
|
- *
|
|
|
- * @param remoteResource
|
|
|
- * jasperserver库里的资源
|
|
|
- * @param localResources
|
|
|
- * 本地路径下的资源列表
|
|
|
- * @return 远程资源是否需要同步
|
|
|
- */
|
|
|
- private boolean needSynchronized(Resource remoteResource, List<Resource> localResources) {
|
|
|
- // 如果资源不是文件夹,并且不含"."(无后缀名),不进行比较,直接认为不需要同步
|
|
|
- if (!remoteResource.isFolder() && !remoteResource.getUri().contains(".")) {
|
|
|
- logger.error("Resource is invalid: " + remoteResource + "\n");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- for (Resource localResource : localResources) {
|
|
|
- // windows平台并不区分文件名的大小写,即使将该资源视为需要同步,也无法创建相应文件
|
|
|
- // 1.若路径完全相同
|
|
|
- // 2.或者为windows平台并且忽略大小写后路径相同
|
|
|
- if (remoteResource.getUri().equals(localResource.getUri())
|
|
|
- || (isWindowsPlatform && remoteResource.getUri().equalsIgnoreCase(localResource.getUri()))) {
|
|
|
- // 如果远程资源比本地资源更新
|
|
|
- if (remoteResource.getUpdateDate().after(localResource.getUpdateDate())) {
|
|
|
- return true;
|
|
|
- } else {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- // 本地并没有该资源
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取本地指定账套下的所有资源
|
|
|
- *
|
|
|
- * @param userName
|
|
|
- * @return 资源列表
|
|
|
- */
|
|
|
- private List<Resource> getLocalResources(String userName) {
|
|
|
- return getLocalResources(new File(fileService.getMasterPath(userName)));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取本地指定路径下的所有资源
|
|
|
- *
|
|
|
- * @param dir
|
|
|
- * 指定的路径,可能是文件夹或文件
|
|
|
- * @return 资源列表
|
|
|
- */
|
|
|
- private List<Resource> getLocalResources(File dir) {
|
|
|
- List<Resource> resources = new ArrayList<>();
|
|
|
- if (dir == null || !dir.exists()) {
|
|
|
- return resources;
|
|
|
- }
|
|
|
- resources.add(convertToResource(dir));
|
|
|
- if (dir.isDirectory()) {
|
|
|
- // 递归获取所有资源
|
|
|
- File[] files = dir.listFiles();
|
|
|
- for (File file : files) {
|
|
|
- resources.addAll(getLocalResources(file));
|
|
|
- }
|
|
|
- }
|
|
|
- return resources;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 将本地文件(夹)转为Resource对象
|
|
|
- *
|
|
|
- * @param file
|
|
|
- * 本地文件(夹)
|
|
|
- * @return 转换的资源
|
|
|
- */
|
|
|
- private Resource convertToResource(File file) {
|
|
|
- Resource resource = new Resource();
|
|
|
- resource.setLabel(file.getName());
|
|
|
- resource.setUpdateDate(new Date(file.lastModified()));
|
|
|
- // 替换"\"为"/"
|
|
|
- String absolutePath = file.getAbsolutePath().replace("\\", "/");
|
|
|
- // 去除文件绝对路径中前半部分,只保留自账套开始的路径
|
|
|
- resource.setUri(absolutePath.replace(specialProperties.getLocalBaseDir(), ""));
|
|
|
- return resource;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<Resource> getRemoteResources(String folderPath)
|
|
|
- throws ClientProtocolException, URISyntaxException, IOException {
|
|
|
- HttpGet httpGet = new HttpGet();
|
|
|
- // 返回json类型数据
|
|
|
- httpGet.setHeader("Accept", "application/json");
|
|
|
- List<NameValuePair> parameters = new ArrayList<>();
|
|
|
- // 设置连接参数
|
|
|
- parameters.add(new BasicNameValuePair("folderUri", folderPath));
|
|
|
- HttpResponse response = sendRequest(httpGet, null, parameters);
|
|
|
- InputStream inputStream = response.getEntity().getContent();
|
|
|
- String jsonStr = IOUtils.toString(inputStream);
|
|
|
- // 将返回的json数据格式化为Resource列表
|
|
|
- List<Resource> resources = JSONObject.parseArray(JSONObject.parseObject(jsonStr).getString("resourceLookup"),
|
|
|
- Resource.class);
|
|
|
- inputStream.close();
|
|
|
- return resources;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 根据资源的信息下载相应文件
|
|
|
- *
|
|
|
- * @param resource
|
|
|
- * 资源信息
|
|
|
- * @throws ClientProtocolException
|
|
|
- * @throws URISyntaxException
|
|
|
- * @throws IOException
|
|
|
- */
|
|
|
- private void downloadFile(Resource resource) throws ClientProtocolException, URISyntaxException, IOException {
|
|
|
- // 如果资源是文件夹,在本地创建
|
|
|
- if (resource.isFolder()) {
|
|
|
- File folder = new File(specialProperties.getLocalBaseDir() + resource.getUri());
|
|
|
- if (!folder.exists()) {
|
|
|
- folder.mkdirs();
|
|
|
- logger.info("Mkdirs " + folder.getPath());
|
|
|
- }
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- String localBaseDir = specialProperties.getLocalBaseDir();
|
|
|
- // 如果本地资源根路径最后以资源分隔符结尾
|
|
|
- if (localBaseDir.endsWith(File.separator)) {
|
|
|
- localBaseDir = localBaseDir.substring(0, localBaseDir.length() - 1);
|
|
|
- }
|
|
|
- String uri = resource.getUri();
|
|
|
- // 从资源的uri中获取账套名(如"/UAS/jrxml/Purchase.jrxml",第一个"UAS"就是账套)
|
|
|
- String userName = uri.split("/")[1];
|
|
|
- // 从uri中获取资源的名称(不能使用label,其只用于方便用户查看,并不能用于标识)
|
|
|
- String resourceName = uri.substring(uri.lastIndexOf("/"));
|
|
|
-
|
|
|
- StringBuilder stringBuilder = new StringBuilder();
|
|
|
- stringBuilder.append(localBaseDir).append("/").append(userName);
|
|
|
-
|
|
|
- // 下载jrxml文件(即使该远程资源并不在jrxml根路径下,比如在嵌套文件夹下),放在localBaseDir+userName+localJrxmlDir下
|
|
|
- if (uri.endsWith(Resource.JRXML_RESOURCE_TYPE)) {
|
|
|
- stringBuilder.append(specialProperties.getLocalJrxmlDir()).append(resourceName);
|
|
|
- downloadFile(uri, Resource.JRXML_MIME_TYPE, stringBuilder.toString());
|
|
|
- }
|
|
|
- // 除jrxml之外的资源视为图片,放在localBaseDir+userName+localImagesDir下
|
|
|
- else {
|
|
|
- stringBuilder.append(specialProperties.getLocalImagesDir()).append(resourceName);
|
|
|
- downloadFile(uri, Resource.IMAGE_MIME_TYPE, stringBuilder.toString());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void downloadFile(String filePath, String mimeType, String exportPath)
|
|
|
- throws ClientProtocolException, URISyntaxException, IOException {
|
|
|
- HttpGet httpGet = new HttpGet();
|
|
|
- // 设置MIME类型
|
|
|
- httpGet.setHeader("MIME", mimeType);
|
|
|
- HttpResponse response = sendRequest(httpGet, filePath, null);
|
|
|
- // 获取文件二进制数据
|
|
|
- byte[] data = IOUtils.toByteArray(response.getEntity().getContent());
|
|
|
- File exportFile = new File(exportPath);
|
|
|
- // 该文件所在的路径不存在,创建
|
|
|
- if (!exportFile.getParentFile().exists()) {
|
|
|
- exportFile.getParentFile().mkdirs();
|
|
|
- logger.info("Mkdirs " + exportFile.getParent());
|
|
|
- }
|
|
|
- FileOutputStream fos = new FileOutputStream(exportFile);
|
|
|
- fos.write(data);
|
|
|
- fos.flush();
|
|
|
- fos.close();
|
|
|
- logger.info("Download resource to " + exportPath + "\n");
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 发送Http请求,获得结果
|
|
|
- *
|
|
|
- * @param request
|
|
|
- * Http请求
|
|
|
- * @param path
|
|
|
- * 资源路径
|
|
|
- * @param parameters
|
|
|
- * 参数
|
|
|
- * @return 服务器的响应结果
|
|
|
- * @throws URISyntaxException
|
|
|
- * @throws ClientProtocolException
|
|
|
- * @throws IOException
|
|
|
- */
|
|
|
- private HttpResponse sendRequest(HttpRequestBase request, String path, List<NameValuePair> parameters)
|
|
|
- throws URISyntaxException, ClientProtocolException, IOException {
|
|
|
- HttpClient httpClient = HttpClients.createDefault();
|
|
|
- request.setURI(createURI(path, parameters));
|
|
|
- // 采用HTTP Basic验证
|
|
|
- request.setHeader("Authorization", "Basic " + jsRestAPIProperties.getAuthorization());
|
|
|
- HttpResponse response = httpClient.execute(request);
|
|
|
- // logger.info(request.getMethod() + " " + request.getURI() + " " +
|
|
|
- // response.getStatusLine());
|
|
|
- return response;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 创建URI
|
|
|
- *
|
|
|
- * @param path
|
|
|
- * 资源路径
|
|
|
- * @param parameters
|
|
|
- * 参数
|
|
|
- * @return URI对象
|
|
|
- * @throws URISyntaxException
|
|
|
- */
|
|
|
- private URI createURI(String path, List<NameValuePair> parameters) throws URISyntaxException {
|
|
|
- StringBuilder stringBuilder = new StringBuilder();
|
|
|
- // 拼接资源全路径
|
|
|
- stringBuilder.append("/").append(jsRestAPIProperties.getContextRoot()).append("/")
|
|
|
- .append(jsRestAPIProperties.getRest()).append("/").append(jsRestAPIProperties.getResources());
|
|
|
- if (path != null) {
|
|
|
- stringBuilder.append(path);
|
|
|
- }
|
|
|
- URIBuilder uriBuilder = new URIBuilder();
|
|
|
- // 协议、主机名、端口号、资源全路径
|
|
|
- uriBuilder.setScheme(jsRestAPIProperties.getSchema()).setHost(jsRestAPIProperties.getHost())
|
|
|
- .setPort(jsRestAPIProperties.getPort()).setPath(stringBuilder.toString());
|
|
|
- // 设置参数
|
|
|
- if (parameters != null) {
|
|
|
- uriBuilder.setParameters(parameters);
|
|
|
- }
|
|
|
- return uriBuilder.build();
|
|
|
- }
|
|
|
-
|
|
|
-}
|