Commit 84852be4 authored by Alina Habibulina's avatar Alina Habibulina

[#1] Version 1

parent 34d25663
Pipeline #182 canceled with stages
in 0 seconds
......@@ -18,5 +18,16 @@ dependencies {
providedCompile(group: 'org.codehaus.jackson', name: 'jackson-mapper-asl', version: '1.9.2', transitive: false)
compile 'org.apache.httpcomponents:httpclient:4.5.1'
providedCompile(group: 'org.jboss.resteasy', name: 'resteasy-jaxrs', version: '2.3.3.Final', transitive: false)
// https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-multipart-provider
compile group: 'org.jboss.resteasy', name: 'resteasy-multipart-provider', version: '2.3.3.Final'
// https://mvnrepository.com/artifact/commons-io/commons-io
compile group: 'commons-io', name: 'commons-io', version: '2.6'
providedCompile 'org.jboss.spec:jboss-javaee-6.0:3.0.3.Final'
// https://mvnrepository.com/artifact/org.apache.poi/poi
providedCompile group: 'org.jboss.spec.javax.ejb', name: 'jboss-ejb-api_3.2_spec', version: '1.0.1.Final'
compile group: 'org.apache.poi', name: 'poi', version: '3.9'
// https://mvnrepository.com/artifact/com.google.code.gson/gson
compile group: 'com.google.code.gson', name: 'gson', version: '2.7'
// https://mvnrepository.com/artifact/joda-time/joda-time
compile group: 'joda-time', name: 'joda-time', version: '2.3'
}
\ No newline at end of file
rootProject.name = 'synergy-api-proxy'
rootProject.name = 'registry-import'
......@@ -7,12 +7,10 @@ import org.slf4j.LoggerFactory;
import javax.naming.NamingException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Created by val
* Date: 04.10.2015
* Time: 12:49
*
* Пример класса для работы с СУБД
* использует соединение, указанное в @{@link ConnectionPool}
......@@ -41,4 +39,26 @@ public class ClientManager {
ConnectionPool.close(con);
}
}
}
public static String getFormDefinition(String registryCode) {
Connection con = null;
try {
con = ConnectionPool.getConnection();
PreparedStatement ps = con.prepareStatement("SELECT asf_definition.definition FROM asf_definition JOIN registries ON registries.formid = asf_definition.uuid WHERE registries.code = ? ");
ps.setString(1, registryCode);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
return "{" + rs.getString("asf_definition.definition") + "}";
}
} catch (SQLException | NamingException e) {
LOGGER.error("", e);
} finally {
ConnectionPool.close(con);
}
return null;
}
}
\ No newline at end of file
......@@ -3,11 +3,6 @@ package kz.arta.ext.sap.service;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
/**
* Created by val
* Date: 04.10.2015
* Time: 11:18
*/
@ApplicationPath("proxy")
@ApplicationPath("import")
public class Activator extends Application {
}
......@@ -16,9 +16,6 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.ext.Provider;
/**
* Created by val
* Date: 17.04.2014
* Time: 18:51
*
* Обработчик доступа к методам REST API
*/
......
package kz.arta.ext.sap.service;
import kz.arta.ext.sap.util.Config;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import kz.arta.ext.sap.util.ImportBean;
import org.apache.commons.io.IOUtils;
import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
import org.jboss.resteasy.util.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
/**
* Created by val
* Date: 04.10.2015
* Time: 11:27
*
* REST сервис с методами, которые не требуют авторизации
*/
@Path("/unsecured")
@Path("/registry")
@RequestScoped
public class UnsecuredProxyService {
......@@ -43,59 +41,95 @@ public class UnsecuredProxyService {
}
/**
* Обертка над методом /rest/api/storage/file/get
* Не требует авторизации.
* Обращение к REST API Synergy осуществляется от имени пользователя,
* указанного в настройках (параметры synergy.user.login и synergy.user.password)
*
* @param identifier идентификатор файла в хранилище
* @return inline изображение. Если запрошенный файл не является изображением, то вернется ошибка.
* Импорт записей в реестр
* @param req
* @param input
* @param formcode - код формы реестра, по которому будет проводиться импорт,
* @param registryCode - код реестра, в который импортируются записи,
* @param isActivate - нужно ли активировать импортированные записи
* @param action - что делать с ссылкой на реестр, если найденно несколько записей реестра с таким значением: "0" - ставить дефолтную запись, "1" - оставлять пустым, "2" - брать первую найденную
* @param defaultValue - значение по умолчанию для action "0". В формате field_id1:documentID, field_id2:documentID, для всех значений кроме 0 передавать none
* @param searchString - значение для поиска для ссылок на реестр в формате field_id1:registry_search_field, field_id2:registry_search_field, field_id3:registry_search_field
* @return
*/
@GET
@Path("/image")
public Response getImage(@QueryParam("identifier") String identifier) {
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/import_file")
@Produces(MediaType.APPLICATION_JSON + "; charset=utf-8")
public Response importToRegistry(@Context HttpServletRequest req, MultipartFormDataInput input, @QueryParam("formcode") String formcode,
@QueryParam("registrycode") String registryCode, @QueryParam("activate") Boolean isActivate,
@QueryParam("action") int action, @QueryParam("defaultValue") String defaultValue, @QueryParam("searchString") String searchString){
String fileName = "";
String result = "";
try {
String auth = Config.getProperty("synergy.user.login", "1") + ":" + Config.getProperty("synergy.user.password", "1");
byte[] encodedAuth = Base64.encodeBase64(
auth.getBytes(Charset.forName("UTF-8")));
String authHeader = "Basic " + new String(encodedAuth);
String auth = req.getHeader("Authorization");
auth = auth.replace("Basic ", "");
String decoded = new String(Base64.decode(auth));
String[] authAr = decoded.split(":");
String login = authAr[0];
String password = authAr[1];
Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
List<InputPart> inputParts = uploadForm.get("file");
for(InputPart inputPart : inputParts) {
MultivaluedMap<String, String> header = inputPart.getHeaders();
fileName = getFileName(header);
InputStream inputStream = inputPart.getBody(InputStream.class, null);
byte[] bytes = IOUtils.toByteArray(inputStream);
fileName = "/tmp/crm-import/" + fileName;
CloseableHttpClient client = HttpClientBuilder.create().build();
writeFile(bytes, fileName);
HttpGet request = new HttpGet(Config.getProperty("synergy.url", "http://127.0.0.1:8080/Synergy") +
"/rest/api/storage/file/get?inline=true&identifier=" + identifier);
request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
LOGGER.info("File " + fileName + "was written!");
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
result = ImportBean.parseFile(fileName, formcode, registryCode, isActivate, login, password, action, defaultValue, searchString);
}
} catch (Exception e){
LOGGER.error(e.getMessage());
return Response.status(500).entity(e.getMessage()).build();
}
int responseCode = response.getStatusLine().getStatusCode();
return Response.status(200).entity(result).build();
LOGGER.info("Request Url: " + request.getURI());
LOGGER.info("Response Code: " + responseCode);
LOGGER.info("Content-Type: " + entity.getContentType().getValue());
}
if (entity.getContentType().getValue().toLowerCase().startsWith("image/")) {
Response.ResponseBuilder builder = Response.ok();
builder.entity(entity.getContent());
private String getFileName(MultivaluedMap<String, String> header){
String[] contentDisposition = header.getFirst("Content-Disposition").split(";");
for (Header header : response.getAllHeaders()) {
builder.header(header.getName(), header.getValue());
}
for (String filename : contentDisposition) {
if ((filename.trim().startsWith("filename"))) {
return builder.build();
} else {
return Response.status(Response.Status.BAD_REQUEST).entity("Not an image").build();
String[] name = filename.split("=");
String finalFileName = name[1].trim().replaceAll("\"", "");
return finalFileName;
}
}
return "unknown";
}
//save to the path
private void writeFile(byte[] content, String filename) throws IOException {
} catch (IOException e) {
LOGGER.error("", e);
return Response.serverError().build();
File file = new File(filename);
if(!file.exists()){
file.createNewFile();
}
FileOutputStream fop = new FileOutputStream(file);
fop.write(content);
fop.flush();
fop.close();
}
}
......@@ -11,10 +11,6 @@ import java.net.URL;
import java.util.*;
/**
* Created by val
* Date: 24.05.2015
* Time: 17:02
*
* Класс для чтения параметров .properties файла
* Указанный кофигурационный файл ищется в папке jboss/standalone/configuration
*/
......
......@@ -10,10 +10,6 @@ import java.sql.Connection;
import java.sql.SQLException;
/**
* Created by val
* Date: 04.10.2015
* Time: 11:13
*
* Пример класса, который отвечает за работу с пулом соединений
*/
public class ConnectionPool {
......@@ -22,7 +18,7 @@ public class ConnectionPool {
public static Connection getConnection() throws SQLException, NamingException {
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:jboss/datasources/DefineDS");
DataSource ds = (DataSource) ctx.lookup("java:jboss/datasources/");
return ds.getConnection();
}
......
package kz.arta.ext.sap.util;
import org.apache.http.annotation.ThreadSafe;
import java.util.Date;
@ThreadSafe
public interface DateFormat {
Date parse(String text) throws Exception;
Date parseStrict(String text) throws Exception;
String format(Date date);
String format(long time);
String getPattern();
}
package kz.arta.ext.sap.util;
public class DateFormatFactory {
public static final DateFormatFactory instance = new DateFormatFactory();
private DateFormatFactory() {
}
public DateFormat get(String format) {
return new JodaDateFormat(format);
}
}
package kz.arta.ext.sap.util;
public enum DateFormatParts {
yyyy,
yy,
mm,
m,
month,
month_short,
monthed,
monthec,
dd,
d,
hh,
h,
HH,
H,
MM,
M,
SS,
S,
;
public static DateFormatParts getOrNull(String name) {
try{
return DateFormatParts.valueOf(name);
} catch (Exception ignored){
return null;
}
}
}
package kz.arta.ext.sap.util;
public class DateFormats {
public static final DateFormat DATE_DASHED_REVERSED_TIME = makeFormat("yyyy-MM-dd HH:mm");
public static final DateFormat TIMESTAMP = makeFormat("yyyy-MM-dd HH:mm:ss");
public static final DateFormat TIMESTAMP_MS = makeFormat("yyyy-MM-dd HH:mm:ss.SSS");
public static final DateFormat TIMESTAMP_MERGED = makeFormat("yyyyMMddHHmmss");
public static final DateFormat TIMESTAMP_NO_SECONDS = makeFormat("yyyy-MM-dd HH:mm:00");
public static final DateFormat DATE_DOTTED_FULL_TIME = makeFormat("dd.MM.yyyy HH:mm:ss");
public static final DateFormat DATE_DOTTED_FULL_TIME_DOTTED = makeFormat("dd.MM.yyyy HH.mm.ss");
public static final DateFormat DATE_DOTTED_REVERSED_FULL_TIME = makeFormat("yyyy.MM.dd HH:mm:ss");
public static final DateFormat TIME_SECONDS_DATE_DOTTED = makeFormat("HH:mm:ss dd.MM.yyyy");
public static final DateFormat TIME_DATE_DOTTED = makeFormat("HH:mm dd.MM.yyyy");
public static final DateFormat TIME_DATE_DOTTED_YEAR_SHORT = makeFormat("HH:mm dd.MM.yy");
/**
* Формат даты/времени подписи
*/
public static final DateFormat SIGN = makeFormat("HH:mm:ss dd.MM.yy");
public static final DateFormat MSPF = makeFormat("yyyy-MM-dd'T'HH:mm:ss");
public static final DateFormat DATE_DASHED_TIME = makeFormat("dd-MM-yyyy HH:mm");
public static final DateFormat DATE_DOTTED_YEAR_SHORT_TIME = makeFormat("dd.MM.yy HH:mm");
public static final DateFormat DATE_DASHED_TIME_DOTTED = makeFormat("dd-MM-yyyy HH.mm");
public static final DateFormat REPOSITORY_VERSION = TIME_DATE_DOTTED;
public static final DateFormat DATE_DASHED_REVERSED = makeFormat("yyyy-MM-dd");
public static final DateFormat DATE_DASHED_REVERSED_Z = makeFormat("yyyy-MM-dd Z");
public static final DateFormat DATE_DOTTED = makeFormat("dd.MM.yyyy");
public static final DateFormat DATE_DOTTED_REVERSED = makeFormat("yyyy.MM.dd");
public static final DateFormat DATE_DOTTED_NO_YEAR = makeFormat("dd.MM");
public static final DateFormat DATE_DOTTED_YEAR_SHORT = makeFormat("dd.MM.yy");
public static final DateFormat DATE_DASHED = makeFormat("dd-MM-yyyy");
public static final DateFormat DATE_DASHED_YEAR_SHORT = makeFormat("dd-MM-yy");
public static final DateFormat DATE_MERGED_REVERSED = makeFormat("yyyyMMdd");
public static final DateFormat DATE_MERGED = makeFormat("ddMMyyyy");
public static final DateFormat TIME_SECONDS = makeFormat("HH:mm:ss");
public static final DateFormat TIME_DASHED = makeFormat("HH-mm");
public static final DateFormat TIME = makeFormat("HH:mm");
public static final DateFormat TIME_DOTTED = makeFormat("HH.mm");
private DateFormats() {
//utils
}
private static DateFormat makeFormat(String f) {
return DateFormatFactory.instance.get(f);
}
}
package kz.arta.ext.sap.util;
public enum EntitySearchActions {
GET_DEFAULT(0),
SET_EMPTY(1),
TAKE_FIRST(2);
public final int value;
EntitySearchActions(int value){
this.value = value;
}
}
package kz.arta.ext.sap.util;
import java.util.List;
import java.util.Map;
public class FormField {
private String code;
private String type;
private String value;
private String key;
//для чекбокса
private List<String> values;
private List<String> keys;
//для справочных значений
private Map<String, String> elements;
//для даты
private String dateFormat;
//для entity
private String entityType;
//для reglink
private String registryID;
private Boolean isRequired = false;
private Boolean isDate = false;
private Boolean isDinTable = false;
private Boolean isDictionary = false;
private Boolean isRegLink = false;
private Boolean isEntity = false;
public FormField() {}
public FormField(FormField ff) {
this.code = ff.getCode();
this.type = ff.getType();
this.elements = ff.getElements();
this.dateFormat = ff.getDateFormat();
this.entityType = ff.getEntityType();
this.registryID = ff.getRegistryID();
this.isRequired = ff.isRequired();
this.isDate = ff.isDate();
this.isDinTable = ff.isDinTable();
this.isDictionary = ff.isDictionary();
this.isRegLink = ff.isRegLink();
this.isEntity = ff.isEntity();
}
public FormField(String code, String type, String value, String key) {
this.code = code;
this.type = type;
this.value = value;
this.key = key;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Boolean isRequired() {
return isRequired;
}
public void setRequired(Boolean required) {
isRequired = required;
}
public Boolean isDinTable() {
return isDinTable;
}
public void setDinTable(Boolean dinTable) {
isDinTable = dinTable;
}
public Boolean isDictionary() {
return isDictionary;
}
public void setDictionary(Boolean dictionary) {
isDictionary = dictionary;
}
public Boolean isRegLink() {
return isRegLink;
}
public void setRegLink(Boolean regLink) {
isRegLink = regLink;
}
public Map<String, String> getElements() {
return elements;
}
public void setElements(Map<String, String> elements) {
this.elements = elements;
}
public String getDateFormat() {
return dateFormat;
}
public void setDateFormat(String dateFormat) {
this.dateFormat = dateFormat;
}
public String getEntityType() {
return entityType;
}
public void setEntityType(String entityType) {
this.entityType = entityType;
}
public String getRegistryID() {
return registryID;
}
public void setRegistryID(String registryID) {
this.registryID = registryID;
}
public Boolean isDate() {
return isDate;
}
public void setDate(Boolean date) {
isDate = date;
}
public Boolean isEntity() {
return isEntity;
}
public void setEntity(Boolean entity) {
isEntity = entity;
}
public List<String> getValues() {
return values;
}
public void setValues(List<String> values) {
this.values = values;
}
public List<String> getKeys() {
return keys;
}
public void setKeys(List<String> keys) {
this.keys = keys;
}
}
package kz.arta.ext.sap.util;
public enum FormFieldType {
CHECKBOX("check"),
LABEL("label"),
TEXTBOX("textbox"),
NUMERICINPUT("numericinput"),
TEXTAREA("textarea"),
DATE("date"),
RADIO("radio"),
ENTITY("entity"),
REGLINK("reglink"),
LISTBOX("listbox"),
TABLE("table");
public final String value;
FormFieldType(String value){
this.value = value;
}
}
package kz.arta.ext.sap.util;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class HTTPRequestUtils {
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public static String sendGet(String url, String login, String password) throws Exception {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
String usernameColonPassword = login + ":" + password;
String basicAuthPayload = "Basic " + Base64.encode(usernameColonPassword.getBytes("UTF-8"));
request.addHeader("Authorization", basicAuthPayload);
HttpResponse response = client.execute(request);
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
return result.toString();
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public static String sendPost(String url, String json, String login, String password) throws Exception {
PostMethod postMethod = new PostMethod(url);
org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient();
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(login, password);
client.getParams().setAuthenticationPreemptive(true);
client.getState().setCredentials(org.apache.commons.httpclient.auth.AuthScope.ANY, creds);
postMethod.setRequestHeader("Content-type", "application/json; charset=utf-8");
postMethod.setRequestBody(json);
client.executeMethod(postMethod);
String answer = postMethod.getResponseBodyAsString();
postMethod.releaseConnection();
return answer;
}
}
package kz.arta.ext.sap.util;
import com.google.gson.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PreDestroy;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import java.io.FileInputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ImportBean {
private static final ExecutorService executor;
static {
executor = Executors.newFixedThreadPool(15);
}
private static final Logger LOGGER = LoggerFactory.getLogger(ImportBean.class);
private static final String BASE_URL = "http://127.0.0.1:8080/Synergy/";
private static final String NO = "no";
private static Map<String, String> defaultValues = new HashMap<>();
private static Map<String, String> searchValues = new HashMap<>();
private static List<Row> errors = new ArrayList<>();
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void getFormFieldForRowAsync(final Row row, final FormulaEvaluator evaluator, final Map<String, FormField> formDefinitionMap, final String registryCode, final Boolean isActivate, final String login, final String password, final int action) {
executor.submit(new Runnable() {
@Override
public void run() {
getFormFieldForRow(row, evaluator, formDefinitionMap, registryCode, login, password, isActivate, action);
}
});
}
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public static String parseFile(String filename, String formcode, String registryCode, Boolean isActivate, String login, String password, int action, String defaultValue, String searchString) throws Exception {
errors = new ArrayList<>();
LOGGER.info("Start pasrsing file: " + filename);
//рид файл
if(defaultValue != null && !defaultValue.equals("none")){
String[] defValues = defaultValue.split(", ");
for(int i = 0; i < defValues.length; i++){
String[] val = defValues[i].split(":");
defaultValues.put(val[0], val[1]);
}
}
if(searchString != null && !searchString.equals("none")){
String[] ss = searchString.split(", ");
for(int i = 0; i < ss.length; i++){
String[] val = ss[i].split(":");
searchValues.put(val[0], val[1]);
}
}
//получаем formDefinition
String formDefinition = getFormDefinition(formcode, login, password);
JsonParser parser = new JsonParser();
JsonElement jsonTree = parser.parse(formDefinition);
if(jsonTree.isJsonObject()){
JsonObject formJson = jsonTree.getAsJsonObject();
Map<String, FormField> formDefinitionMap = getFormDefinitionMap(formJson, login, password);
HSSFWorkbook importedFileWB = new HSSFWorkbook(new FileInputStream(filename));
FormulaEvaluator evaluator = importedFileWB.getCreationHelper().createFormulaEvaluator();
for(int i = 0; i < importedFileWB.getNumberOfSheets(); i++){
Sheet importedFileSheet = importedFileWB.getSheetAt(i);
List<Row> sheetRows = getAllSheetRows(importedFileSheet);
for(Row row : sheetRows){
try {
ImportBean iu = new ImportBean();
iu.getFormFieldForRowAsync(row, evaluator, formDefinitionMap, registryCode, isActivate, login, password, action);
} catch (Exception e){
errors.add(row);
LOGGER.error(e.getMessage());
}
}
}
} else {
throw new Exception("Wrong form definition! " + jsonTree.getAsString());
}
return "Начат импорт записей реестра, его процесс и результаты пишутся в логи Synergy!";
}
private static String formateRequestData(List<FormField> data, String registryCode){
String jsonData = "[";
int i = 0;
for(FormField ff : data){
//добавляем поля в json
//ПОКА ЧТО Я НЕ РЕАЛИЗОВАЛА ИХ ПАРСИНГ И ФОРМАТИРОВАНИЕ
jsonData += "{ \"id\": \"" + ff.getCode() + "\", \"type\": \"" + ff.getType() + "\"";
//jsonData += "{ \"id\": \"" + ff.getCode() + "\", \"type\": \"" + ff.getType() + "\", \"value\": \"" + ff.getValue() + "\"";
//если это словарь и не чек бокс, нужно просто задать ему значение key
if(ff.getType().equals(FormFieldType.LISTBOX.value)){
jsonData += ", \"key\": \"" + ff.getKey() + "\", \"value\": \"" + ff.getValue() + "\"";
} else if(ff.getType().equals(FormFieldType.RADIO.value)){
jsonData += ", \"key\": \"" + ff.getValue() + "\", \"value\": \"" + ff.getKey() + "\"";
} else if(ff.getType().equals(FormFieldType.CHECKBOX.value)){
jsonData += ", \"values\": [";
for(String key : ff.getKeys()){
jsonData += "\"" + key + "\"";
if(key != ff.getKeys().get(ff.getKeys().size() - 1)){
jsonData += ", ";
}
}
jsonData += "], \"keys\": [";
for(String val : ff.getValues()){
jsonData += "\"" + val + "\"";
if(val != ff.getValues().get(ff.getValues().size() - 1)){
jsonData += ", ";
}
}
jsonData += "]";
} else if(ff.getType().equals(FormFieldType.NUMERICINPUT.value)){
jsonData += ", \"key\": \"" + ff.getValue() + "\", \"value\": \"" + ff.getValue() + "\"";
} else if(ff.getType().equals(FormFieldType.REGLINK.value)){
if(ff.getKey() != null) {
jsonData += ", \"key\": \"" + ff.getKey() + "\", \"value\": \"" + ff.getValue() + "\", \"valueID\": \"" + ff.getKey() + "\"";
}
} else if(ff.getType().equals(FormFieldType.ENTITY.value)){
jsonData += ", \"value\": \"" + ff.getValue() + "\"";
} else if(ff.getType().equals(FormFieldType.DATE.value)){
String value = formatDate(ff.getDateFormat(), ff.getKey());
jsonData += ", \"key\": \"" + ff.getKey() + "\", \"value\": \"" + value + "\"";
} else { //если текстовое поле
jsonData += ", \"value\": \"" + ff.getValue() + "\"";
}
jsonData += "}";
if(i != data.size() -1){ jsonData += ","; }
i++;
}
if(("" + jsonData.charAt(jsonData.length() - 1)).equals(",")){
jsonData = jsonData.substring(0, jsonData.length() - 1);
}
jsonData += "]";
String mainjson = "{ \"registryCode\": \"" + registryCode + "\", \"data\": " + jsonData + "}";
return mainjson;
}
private static List<Row> getAllSheetRows(Sheet importedFileSheet ){
List<Row> rows = new ArrayList<>();
Iterator<Row> rowIt = importedFileSheet.rowIterator();
rowIt.next(); //пропускаем первый ряд с заголовками
while (rowIt.hasNext()){
Row row = rowIt.next();
rows.add(row);
}
return rows;
}
private static String getFormDefinition(String formCode, String login, String password) throws Exception {
if(formCode == null || formCode.equals("")) return null;
String answer = HTTPRequestUtils.sendGet(BASE_URL + "rest/api/asforms/form_ext?formCode=" + formCode, login, password);
return answer;
}
/**
*
* @param row
* @param formFields key - код поля формы, value - FormField c его данными из определения формы
* @return
*/
private static void getFormFieldForRow(Row row, FormulaEvaluator evaluator, Map<String, FormField> formFields, String registryCode, String login, String password, Boolean isActivate, int action){
try {
List<FormField> rowFF = new ArrayList<>();
Iterator<Cell> iter = row.cellIterator();
while (iter.hasNext()) {
Cell cell = iter.next();
CellValue cellValue = evaluator.evaluate(cell);
//получили заголовок ячейки
String header = cell.getSheet().getRow(0).getCell(cell.getColumnIndex()).getRichStringCellValue().toString();
if (header.equals(NO)) {
continue;
}
FormField defField = formFields.get(header);
if (defField == null) {
errors.add(row);
LOGGER.error("Import error in line :" + (row.getRowNum() + 1));
}
FormField valueFF = new FormField(defField);
if(cellValue == null) continue;
switch (cellValue.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
if (defField.getType().equals(FormFieldType.DATE.value)) {
if (cell.getDateCellValue() == null) {
continue;
}
// "key": "2019-08-29 11:07:00"
Date date = cell.getDateCellValue();
valueFF.setKey((date.getYear() + 1900) + "-" + ((date.getMonth() + 1) < 10 ? "0" + (date.getMonth() + 1) : (date.getMonth() + 1)) + "-" +
( date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + " " +
( date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":" +
( date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + ":" +
( date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds()));
} else {
valueFF.setValue(cellValue.getNumberValue() + "");
}
break;
case Cell.CELL_TYPE_STRING:
if (cellValue.getStringValue() == null || cellValue.getStringValue().equals("")) {
continue;
}
String value = cellValue.getStringValue().replaceAll("\"","\\\\\"");
valueFF.setValue(value);
break;
case Cell.CELL_TYPE_BLANK:
continue;
case Cell.CELL_TYPE_BOOLEAN:
valueFF.setValue(cellValue.getBooleanValue() + "");
break;
}
if (valueFF.isDictionary()) {
//из карты со значениями словаря берем список элементов и ложим его значение в key
if (valueFF.getType().equals(FormFieldType.CHECKBOX.value)) {
String[] values = valueFF.getValue().split("; ");
ArrayList<String> arlvals = new ArrayList<>();
ArrayList<String> keys = new ArrayList<>();
for (int i = 0; i < values.length; i++) {
arlvals.add(values[i]);
if (valueFF.getElements().get(values[i]) == null) {
errors.add(row);
LOGGER.error("Import error in line :" + (row.getRowNum() + 1));
return;
} else {
keys.add(valueFF.getElements().get(values[i]));
}
}
valueFF.setValues(arlvals);
valueFF.setKeys(keys);
} else {
valueFF.setKey(valueFF.getElements().get(valueFF.getValue()));
}
} else if (valueFF.isEntity()) {
//TODO: найти эту сущность, взять ее id и вставить его, если ее не находит, вставить только value
} else if (valueFF.isDinTable()) {
//TODO: распилить все ячейки по одной дин таблице хз как
} else if (valueFF.isRegLink()) {
String documentID = getRegLinkObject(valueFF.getRegistryID(), valueFF.getCode(), valueFF.getValue(), action, login, password);
if(documentID != null) valueFF.setKey(documentID);
}
rowFF.add(valueFF);
}
if (rowFF != null && !rowFF.isEmpty()) {
String data = formateRequestData(rowFF, registryCode);
String answer = HTTPRequestUtils.sendPost(BASE_URL + "rest/api/registry/create_doc_rcc", data, login, password);
JsonParser answrPars = new JsonParser();
JsonElement jsonAnswr = answrPars.parse(answer);
String errorCode = jsonAnswr.getAsJsonObject().get("errorCode").getAsString();
if(!errorCode.equals("0")){
errors.add(row);
LOGGER.error("CREATE DOC RCC error in line :" + (row.getRowNum() + 1));
} else {
if (isActivate) {
String dataUUID = jsonAnswr.getAsJsonObject().get("dataID").getAsString();
HTTPRequestUtils.sendGet(BASE_URL + "rest/api/registry/activate_doc?dataUUID=" + dataUUID, login, password);
}
}
} else {
errors.add(row);
LOGGER.error("Import error in line :" + (row.getRowNum() + 1));
return;
}
} catch (Exception e){
errors.add(row);
LOGGER.error("Import error in line :" + (row.getRowNum() + 1), e.getMessage());
}
}
/**
* Метод преобразует поля формы из form definition в Map<Код компонента формы, FormField>
* @param formDefinition
* @return
*/
private static Map<String, FormField> getFormDefinitionMap(JsonObject formDefinition, String login, String password) throws Exception {
Map<String, FormField> mapFormDefinition = new HashMap<>();
//properties
JsonArray properties = formDefinition.get("properties").getAsJsonArray();
if (properties != null) {
for (int i = 0; i < properties.size(); i++) {
JsonObject formField = properties.get(i).getAsJsonObject();
FormField ff = new FormField();
ff.setCode(formField.get("id").getAsString());
ff.setType(formField.get("type").getAsString());
ff.setRequired(formField.get("required").getAsBoolean());
if(ff.getType().equals(FormFieldType.CHECKBOX.value) || ff.getType().equals(FormFieldType.RADIO.value) ||
ff.getType().equals(FormFieldType.LISTBOX.value)){
//Забиваем элементы справочника для этих полей в поле ff.elements
Map<String, String> elements = new HashMap<>();
if(formField.get("elements") != null) {
JsonArray elementsArray = formField.get("elements").getAsJsonArray();
if (elementsArray != null) {
for (int j = 0; j < elementsArray.size(); j++) {
elements.put(elementsArray.get(j).getAsJsonObject().get("label").getAsString(), elementsArray.get(j).getAsJsonObject().get("value").getAsString());
}
ff.setElements(elements);
}
} else if(formField.get("dataSource") != null){
JsonObject dataSource = formField.get("dataSource").getAsJsonObject();
ff.setElements(getDictionary(dataSource.get("dict").getAsString(), dataSource.get("key").getAsString(), dataSource.get("value").getAsString(), login, password));
}
ff.setDictionary(true);
} else if(ff.getType().equals(FormFieldType.DATE.value)){
//Заполняем формат даты, если это поле типа дата
String dateFormat = formField.get("config").getAsJsonObject().get("dateFormat").getAsString();
ff.setDate(true);
ff.setDateFormat(dateFormat);
} else if(ff.getType().equals(FormFieldType.ENTITY.value)){
//заполняем тип сущности, если это поле типа сущности
ff.setEntity(true);
ff.setEntityType(formField.get("config").getAsJsonObject().get("entity").getAsString());
} else if(ff.getType().equals(FormFieldType.REGLINK.value)){
//заполняем код реестра если это ссылка на реестр
ff.setRegLink(true);
ff.setRegistryID(formField.get("config").getAsJsonObject().get("dateFormat").getAsString());
} else if(ff.getType().equals(FormFieldType.TABLE.value)){
mapFormDefinition.putAll(getFormDefinitionMap(formField, login, password));
}
if(!ff.getType().equals(FormFieldType.TABLE.value)){
mapFormDefinition.put(ff.getCode(), ff);
}
}
}
return mapFormDefinition;
}
private static Map<String, String> getDictionary(String dictCode, String columnName, String columnValue, String login, String password) throws Exception {
String dictionary = HTTPRequestUtils.sendGet(BASE_URL + "rest/api/dictionary/get_by_code?dictionaryCode=" + dictCode, login, password);
JsonParser parser = new JsonParser();
JsonElement jsonTree = parser.parse(dictionary);
Map<String, String> elements = new HashMap<>();
if(jsonTree.isJsonObject()){
JsonArray ja = jsonTree.getAsJsonObject().get("columns").getAsJsonArray();
Map<String, String> columnIDsAndCodes = new HashMap<>();
for(int i = 0; i < ja.size(); i++){
if(ja.get(i).getAsJsonObject().get("code").getAsString().equals(columnName) || ja.get(i).getAsJsonObject().get("code").getAsString().equals(columnValue)) {
columnIDsAndCodes.put(ja.get(i).getAsJsonObject().get("code").getAsString(), ja.get(i).getAsJsonObject().get("columnID").getAsString());
}
}
JsonArray dictItems = jsonTree.getAsJsonObject().get("items").getAsJsonArray();
for(int i = 0; i < dictItems.size(); i++) {
JsonArray valuesArray = dictItems.get(i).getAsJsonObject().get("values").getAsJsonArray();
String val = "", key = "";
for (int j = 0; j < valuesArray.size(); j++) {
String columnID = valuesArray.get(j).getAsJsonObject().get("columnID").getAsString();
if (columnID.equals(columnIDsAndCodes.get(columnName))) {
val = valuesArray.get(j).getAsJsonObject().get("value").getAsString();
} else if (columnID.equals(columnIDsAndCodes.get(columnValue))) {
key = valuesArray.get(j).getAsJsonObject().get("value").getAsString();
}
}
elements.put(val, key);
}
}
return elements;
}
//<value, docID>
//action = EntitySearchActions.class
private static String getRegLinkObject(String regID, String fieldCode, String value, int action, String login, String password) throws Exception {
String searchField = searchValues.get(fieldCode);
String answer = HTTPRequestUtils.sendGet(BASE_URL + "rest/api/registry/data_ext?registryID=" + regID + "&field=" + searchField
+ "&condition=TEXT_EQUALS&value=" + URLEncoder.encode(value.replaceAll("\\\\\"", "\""), StandardCharsets.UTF_8.toString()), login, password);
//парсим json, находим нужный объект и записываем его данные в систему
JsonParser jp = new JsonParser();
JsonElement jsonTree = jp.parse(answer);
if(jsonTree.isJsonObject()){
JsonArray find = jsonTree.getAsJsonObject().get("result").getAsJsonArray();
if(find.size() > 1){
String docID = "";
switch(action){
case 0: // EntitySearchActions.GET_DEFAULT
return defaultValues.get(fieldCode);
case 1: // EntitySearchActions.SET_EMPTY
return null;
case 2: // EntitySearchActions.TAKE_FIRST
docID = find.get(0).getAsJsonObject().get("documentID").getAsString();
break;
}
return docID;
} else if(find.size() == 0){
return null;
} else {
if(find.get(0) != null) {
String docID = find.get(0).getAsJsonObject().get("documentID").getAsString();
return docID;
}
}
}
return null;
}
public static String formatDate(String format, String date) {
try {
Date d = DateFormats.TIMESTAMP.parse(date);
Matcher matcher = Pattern.compile("(\\$\\{.[^\\}\\{\\$]*\\})").matcher(format);
Pattern partPattern = Pattern.compile("\\$\\{(.+)\\}");
Calendar calendar = Calendar.getInstance();
calendar.setTime(d);
String result = format;
while (matcher.find()) {
String part = matcher.group(0);
Matcher m = partPattern.matcher(part);
if (!m.find()) {
continue;
}
String partName = m.group(1);
result = result.replace(part, getDatePart(calendar, partName));
}
return result;
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
return "";
}
}
private static String getDatePart(Calendar calendar, String part) throws Exception {
DateFormatParts formatPart = DateFormatParts.getOrNull(part);
if (formatPart != null) {
switch (formatPart) {
case yyyy: {
return new SimpleDateFormat("yyyy").format(calendar.getTime());
}
case yy: {
return new SimpleDateFormat("yy").format(calendar.getTime());
}
case mm: {
return new SimpleDateFormat("MM").format(calendar.getTime());
}
case m: {
return new SimpleDateFormat("M").format(calendar.getTime());
}
case dd: {
return new SimpleDateFormat("dd").format(calendar.getTime());
}
case d: {
return new SimpleDateFormat("d").format(calendar.getTime());
}
case hh: {
return new SimpleDateFormat("hh").format(calendar.getTime());
}
case h: {
int hour = calendar.get(Calendar.HOUR_OF_DAY);
if (hour == 0) {
return String.valueOf(12);
}
if (hour > 12) {
return String.valueOf(hour - 12);
} else {
return String.valueOf(hour);
}
}
case HH: {
return new SimpleDateFormat("HH").format(calendar.getTime());
}
case H: {
return new SimpleDateFormat("H").format(calendar.getTime());
}
case MM: {
return new SimpleDateFormat("mm").format(calendar.getTime());
}
case M: {
return new SimpleDateFormat("m").format(calendar.getTime());
}
case SS: {
return new SimpleDateFormat("ss").format(calendar.getTime());
}
case S: {
return new SimpleDateFormat("s").format(calendar.getTime());
}
}
}
return "${" + part + "}";
}
@PreDestroy
public void destroy() {
executor.shutdown();
}
}
package kz.arta.ext.sap.util;
import org.joda.time.DateTime;
import org.joda.time.format.*;
import java.util.Date;
public class JodaDateFormat implements DateFormat {
private String pattern;
private final DateTimeFormatter formatter;
private final DateTimeFormatter strictFormatter;
public JodaDateFormat(String pattern) {
this.pattern = pattern;
formatter = new DateTimeFormatterBuilder().appendPattern(pattern).append(new JodaDateTimeConsumeAll()).toFormatter();
strictFormatter = DateTimeFormat.forPattern(pattern);
}
@Override
public Date parse(String text) throws Exception {
return doParse(formatter, text);
}
@Override
public Date parseStrict(String text) throws Exception {
return doParse(strictFormatter, text);
}
private Date doParse(DateTimeFormatter formatter, String text) throws Exception {
DateTime dateTime = formatter.parseDateTime(text);
return dateTime.toDate();
}
@Override
public String format(Date date) {
return formatter.print(date.getTime());
}
@Override
public String format(long time) {
return formatter.print(time);
}
@Override
public String getPattern() {
return pattern;
}
public class JodaDateTimeConsumeAll implements DateTimeParser{
@Override
public int estimateParsedLength() {
return 100;
}
@Override
public int parseInto(DateTimeParserBucket bucket, String text, int position) {
return text.length(); //consume the whole thing
}
}
}
package kz.arta.ext.sap.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ServerDateFormat implements DateFormat {
private String pattern;
public ServerDateFormat(String pattern) {
super();
this.pattern = pattern;
}
@Override
public Date parse(String text) throws Exception {
return parse(text, true);
}
@Override
public Date parseStrict(String text) throws Exception {
return parse(text, false);
}
private Date parse(String text, boolean lenient) throws Exception {
try {
SimpleDateFormat format = getFormat();
format.setLenient(lenient);
return format.parse(text);
} catch (ParseException e) {
throw new Exception(e);
}
}
@Override
public String format(Date date) {
return getFormat().format(date);
}
@Override
public String format(long time) {
return getFormat().format(new Date(time));
}
private SimpleDateFormat getFormat() {
return new SimpleDateFormat(pattern);
}
@Override
public String getPattern() {
return pattern;
}
}
<jboss-web>
<context-root>sap</context-root>
<context-root>import</context-root>
</jboss-web>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Импорт записей в реестры</title>
<!-- UIkit CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.0/css/uikit.min.css" />
<!-- UIkit JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.0/js/uikit.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.0/js/uikit-icons.min.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script src="./index.js"></script>
<style type="text/css">
.settings {
display: flex;
flex-direction: column;
align-items: flex-start;
}
#formCode, #registryCode, #login, #password {
width: 30%;
margin: 15px 0;
}
button {
margin: 20px;
}
.def-hide {
display: none;
}
.def-show{
display: block;
}
#spin {
position: fixed;
left: calc(50% - 67px);
top: calc(50% - 67px);
}
* {
margin: 10px;
}
</style>
</head>
<body>
<body>
<h1>Импорт файлов</h1>
</body>
<div class="settings">
<input type="text" id="formCode" placeholder="Код формы" class="uk-input" required>
<input type="text" id="registryCode" placeholder="Код ресстра" class="uk-input" required>
<input type="text" id="login" class="uk-input" placeholder="Логин" required>
<input type="password" id="password" class="uk-input" placeholder="Пароль" required>
<label><input id="activate" class="uk-checkbox" type="checkbox"> Активировать импортированные записи</label>
<div class="uk-margin">
<label for="search-value">По какому полю в реестре производить поиск (написать для каждой ссылки на реестр : field_id1:registry_search_field, field_id2:registry_search_field, field_id3:registry_search_field</label>
<input type="text" id="search-value" class="uk-input">
<div class="uk-form-label">При импорте ссылок на реестр и объектов Synergy производится поиск по значениям столбца в соответсвующем реестре. Какие действия следует предпринять при нахождении несокльких записей реестра для одного значения?</div>
<div class="uk-form-controls">
<label><input value="2" class="uk-radio" type="radio" name="radio1" checked> Выбрать первое из результатов поисков</label><br>
<label><input value="1" class="uk-radio" type="radio" name="radio1"> Оставить поле пустым </label><br>
<label><input value="0" class="uk-radio" type="radio" name="radio1"> Выбрать значение по умолчанию</label>
</div>
<label class="def-hide" for="default-value">Введите documentID значения в формате(если несколько поле, отделить их запятой с пробелом): field_id1:documentID, field_id2:documentID, field_id3:documentID</label>
<input type="text" id="default-value" class="uk-input def-hide">
</div>
<div>Файл xls/xlsx для импорта записей реестра :</div>
<div div class="js-upload" uk-form-custom>
<input id="fileinpt" class="uk-input uk-form-width-medium" type="file" name="uploadedFile" required>
<button class="uk-button uk-button-default" type="button" tabindex="-1">Выбрать файл</button>
</div>
<button id="start_import" class="uk-button uk-button-default">Импортировать</button>
<span id="spin" uk-spinner="ratio: 4.5"></span>
</div>
<div class="instructions">
</div>
</body>
</html>
\ No newline at end of file
$(document).ready(function(){
$("#spin").hide();
$('input[name=radio1]').change(function (){
if($(this).val() == "0"){
$(".def-hide").each(function(){
$(this).removeClass("def-hide");
$(this).addClass("def-show");
})
} else {
$(".def-show").each(function(){
$(this).removeClass("def-show");
$(this).addClass("def-hide");
})
};
});
$("#start_import").click(function(){
$("#spin").show();
var formCode = $("#formCode").val();
var regCode = $("#registryCode").val();
var log = $("#login").val();
var pass = $("#password").val();
var action = $('input[name=radio1]:checked').val();
var defaultValue = $('#default-value').val();
var searchString = $('#search-value').val();
if(!defaultValue){
defaultValue = "none";
}
if(!searchString){
searchString = "none";
}
var isActivate = $("#activate").is(':checked');
var file = $("#fileinpt");
var fd = new FormData;
fd.append('file', file.prop('files')[0]);
$.ajax({
url: window.location.origin + "/import/import/registry/import_file?formcode=" + formCode + "&registrycode=" + regCode
+ "&activate=" + isActivate + "&action=" + action + "&defaultValue=" + defaultValue + "&searchString=" + searchString,
data: fd,
beforeSend: function (xhr) {
xhr.setRequestHeader ("Authorization", "Basic " + btoa(log + ":" + pass));
},
processData: false,
contentType: false,
type: 'POST',
success: function (data) {
$("#spin").hide();
alert(data.toString());
},
error: function (error) {
$("#spin").hide();
alert(error.responseText);
}
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment