|
@@ -1,221 +0,0 @@
|
|
|
-package in.ocsf.app;/* kpmy 05.03.2017 */
|
|
|
-
|
|
|
-import com.sun.xml.xsom.XSElementDecl;
|
|
|
-import com.sun.xml.xsom.XSSchemaSet;
|
|
|
-import com.sun.xml.xsom.parser.XSOMParser;
|
|
|
-import org.apache.commons.io.ByteOrderMark;
|
|
|
-import org.apache.commons.io.input.BOMInputStream;
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
-import org.apache.log4j.Logger;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.beans.factory.annotation.Value;
|
|
|
-import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
-import org.springframework.scheduling.annotation.Async;
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
-import org.xml.sax.Attributes;
|
|
|
-import org.xml.sax.InputSource;
|
|
|
-import org.xml.sax.SAXException;
|
|
|
-import org.xml.sax.helpers.DefaultHandler;
|
|
|
-
|
|
|
-import javax.sql.DataSource;
|
|
|
-import javax.xml.parsers.SAXParser;
|
|
|
-import javax.xml.parsers.SAXParserFactory;
|
|
|
-import java.io.FileInputStream;
|
|
|
-import java.io.InputStream;
|
|
|
-import java.io.InputStreamReader;
|
|
|
-import java.io.Reader;
|
|
|
-import java.nio.file.Files;
|
|
|
-import java.nio.file.Path;
|
|
|
-import java.nio.file.Paths;
|
|
|
-import java.util.*;
|
|
|
-
|
|
|
-@Service
|
|
|
-public class FiasSyncService {
|
|
|
-
|
|
|
- private final Logger log = Logger.getLogger(getClass());
|
|
|
-
|
|
|
- @Value("${fias.path}")
|
|
|
- private String fiasPath;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private DataSource dataSource;
|
|
|
-
|
|
|
- private void fillTable(List<String> name, Map<String, String> cols){
|
|
|
- try {
|
|
|
- Files.walk(Paths.get(fiasPath))
|
|
|
- .filter(Files::isRegularFile)
|
|
|
- .filter(p -> p.toString().toLowerCase().endsWith(".xml"))
|
|
|
- .filter(p -> {
|
|
|
- List<String> nameList = new ArrayList<>();
|
|
|
- for (String part : Arrays.asList(p.getFileName().toString().split("_", -1))) {
|
|
|
- if (StringUtils.isNumeric(part)) break;
|
|
|
- nameList.add(part);
|
|
|
- }
|
|
|
- return StringUtils.join(name, '_').equals(StringUtils.join(nameList, '_'));
|
|
|
- }).findAny().ifPresent(p -> {
|
|
|
- try {
|
|
|
- SAXParserFactory factory = SAXParserFactory.newInstance();
|
|
|
- SAXParser saxParser = factory.newSAXParser();
|
|
|
- InputStream inputStream= new FileInputStream(p.toFile());
|
|
|
- inputStream = new BOMInputStream(inputStream, ByteOrderMark.UTF_8);
|
|
|
- Reader reader = new InputStreamReader(inputStream,"UTF-8");
|
|
|
- InputSource is = new InputSource(reader);
|
|
|
- is.setEncoding("UTF-8");
|
|
|
- saxParser.parse(is, new MyHandler(StringUtils.join(name, '_'), cols));
|
|
|
- } catch (Exception e){
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- });
|
|
|
- } catch (Exception e) {
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void createTable(String name, Map<String, String> cols){
|
|
|
- new JdbcTemplate(dataSource).execute("DROP TABLE IF EXISTS FIAS." + name);
|
|
|
- String sql = "CREATE TABLE IF NOT EXISTS FIAS." + name;
|
|
|
- List<String> colsList = new ArrayList<>();
|
|
|
- cols.forEach((n, t) -> colsList.add(n + " " + t));
|
|
|
- sql = sql + "("+ StringUtils.join(colsList, ',') +")";
|
|
|
- new JdbcTemplate(dataSource).execute(sql);
|
|
|
- }
|
|
|
-
|
|
|
- private void useBase(List<String> name, XSElementDecl base){
|
|
|
- Map<String, String> cols = new LinkedHashMap<>();
|
|
|
- base.getType().asComplexType().iterateAttributeUses().forEachRemaining(a -> {
|
|
|
- String type;
|
|
|
- String typeName = a.getDecl().getType().getPrimitiveType().getName();
|
|
|
- switch (typeName){
|
|
|
- case "integer":
|
|
|
- case "decimal":
|
|
|
- type = "LONG";
|
|
|
- break;
|
|
|
- case "string":
|
|
|
- type = "VARCHAR(1024)";
|
|
|
- break;
|
|
|
- case "date":
|
|
|
- type = "DATE";
|
|
|
- break;
|
|
|
- default:
|
|
|
- throw new RuntimeException("unknown type " + typeName);
|
|
|
- }
|
|
|
- if(type == null) throw new RuntimeException("unknown type");
|
|
|
- cols.put(a.getDecl().getName(), type);
|
|
|
- });
|
|
|
- createTable(StringUtils.join(name, '_'), cols);
|
|
|
- fillTable(name, cols);
|
|
|
- }
|
|
|
-
|
|
|
- private void useSchema(Path path) throws Exception{
|
|
|
- log.info(path.toString() + " start");
|
|
|
- SAXParserFactory parserFactory = SAXParserFactory.newInstance();
|
|
|
- parserFactory.setNamespaceAware(true);
|
|
|
- XSOMParser xsomParser = new XSOMParser(parserFactory);
|
|
|
- xsomParser.parse(path.toFile());
|
|
|
- XSSchemaSet xsd = xsomParser.getResult();
|
|
|
- xsd.iterateSchema().forEachRemaining(s -> {
|
|
|
- s.iterateElementDecls().forEachRemaining(elem -> {
|
|
|
- try {
|
|
|
- XSElementDecl child = elem.getType().asComplexType().getContentType().asParticle().getTerm().asModelGroup().getChildren()[0].getTerm().asElementDecl();
|
|
|
- List<String> nameList = new ArrayList<>();
|
|
|
- for(String part : Arrays.asList(path.getFileName().toString().split("_", -1))){
|
|
|
- if(StringUtils.isNumeric(part)) break;
|
|
|
- nameList.add(part);
|
|
|
- }
|
|
|
- useBase(nameList, child);
|
|
|
- } catch (Exception e){
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
- log.info(path.toString() + " done");
|
|
|
- }
|
|
|
-
|
|
|
- @Async
|
|
|
- public void sync(){
|
|
|
- try {
|
|
|
- Files.walk(Paths.get(fiasPath))
|
|
|
- .filter(Files::isRegularFile)
|
|
|
- .filter(p -> p.toString().toLowerCase().endsWith(".xsd"))
|
|
|
- .forEach(p -> {
|
|
|
- try {
|
|
|
- useSchema(p);
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- });
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private class MyHandler extends DefaultHandler {
|
|
|
- private long limit = 9999;
|
|
|
- private long count = 0;
|
|
|
- private long total = 0;
|
|
|
- private String tableName;
|
|
|
- private Map<String, String> cols;
|
|
|
- private Map<String, List<Object[]>> cache = new HashMap<>();
|
|
|
-
|
|
|
- private MyHandler() {
|
|
|
- }
|
|
|
-
|
|
|
- MyHandler(String tableName, Map<String, String> cols) {
|
|
|
- this.tableName = tableName;
|
|
|
- this.cols = cols;
|
|
|
- }
|
|
|
-
|
|
|
- private void flush(boolean end) {
|
|
|
- if ((count > limit) || end) {
|
|
|
- for (String sql : cache.keySet())
|
|
|
- new JdbcTemplate(dataSource).batchUpdate(sql, cache.get(sql));
|
|
|
-
|
|
|
- log.info("flush " + end + ", total " + total);
|
|
|
- count = 0;
|
|
|
- cache.clear();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void insert(Attributes attributes) {
|
|
|
- String[] names = new String[attributes.getLength()];
|
|
|
- String[] values = new String[attributes.getLength()];
|
|
|
- String[] wildcards = new String[attributes.getLength()];
|
|
|
- for (int i = 0; i < attributes.getLength(); i++) {
|
|
|
- names[i] = attributes.getLocalName(i);
|
|
|
- values[i] = attributes.getValue(i);
|
|
|
- wildcards[i] = "?";
|
|
|
- }
|
|
|
- String sql = "INSERT INTO FIAS." + tableName + "(" + StringUtils.join(names, ',') + ")" + "VALUES (" + StringUtils.join(wildcards, ',') + ")";
|
|
|
- try {
|
|
|
- //new JdbcTemplate(dataSource).update(sql, values);
|
|
|
- if (!cache.containsKey(sql)) cache.put(sql, new ArrayList<>());
|
|
|
- cache.get(sql).add(values);
|
|
|
- count++;
|
|
|
- total++;
|
|
|
- flush(false);
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- throw new RuntimeException(e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
|
|
- if (attributes.getLength() > 0) {
|
|
|
- if (cols.containsKey(attributes.getLocalName(0)))
|
|
|
- insert(attributes);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void startDocument() throws SAXException {
|
|
|
- new JdbcTemplate(dataSource).execute("START TRANSACTION");
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void endDocument() throws SAXException {
|
|
|
- flush(true);
|
|
|
- new JdbcTemplate(dataSource).execute("COMMIT");
|
|
|
- }
|
|
|
- }
|
|
|
-}
|