package hycom.dao; import hycom.service.TableNameParser; import hycom.service.XMLSerialize; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * Klasa mapująca dane na XML oraz obsługująca zapytania do bazy danych */ @Component public class MapperSubmitDao extends BaseMapperDao { /** * Parsuje uzupełniony formularz na XML. * @param formXML uzupełniony formularz przychodzący w formie String * @param appName nazwa Aplikacji formularza * @param formName nazwa Formy formularza * @param userLogin login użytkownika wysyłającego formularz * @throws ParserConfigurationException Wyjątek wyrzucany, w przypadku próby parsowania nie odpowiedniego pliku. * @throws IOException Wyjątek wyrzucany, w przypadku odczytywania z zamkniętego strumienia danych. * @throws SAXException Wyjątek wyrzucany, w przypadku nieudanego budowania pliku dokumentu. */ public void parseXML(String formXML, String appName, String formName, String userLogin) throws ParserConfigurationException, IOException, SAXException { StringBuilder stringBuilder = new StringBuilder(); new BufferedReader(new StringReader(formXML)).lines().forEach( (line) -> { if (StringUtils.isNotBlank(line)) stringBuilder.append(line); }); Document document = XMLSerialize.parseStringToXML(stringBuilder.toString()); String tableName = TableNameParser.convertTableName(appName, formName); if (checkTable(tableName)) getValueFromXML(document, tableName, userLogin); } private void getValueFromXML(Document document, String tablePrefix, String login) { String section = null; String control = null; String grid = null; String controlGrid = null; document.getDocumentElement().normalize(); NodeList nodeList = document.getDocumentElement().getChildNodes(); List controlData = new ArrayList<>(); List controlColumns = new ArrayList<>(); List gridData = new ArrayList<>(); List gridColumns = new ArrayList<>(); List gridTable = new ArrayList<>(); for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); NodeList sectionNodeList = node.getChildNodes(); if (node.getNodeName().contains("section")) { section = node.getNodeName().replace("-","_"); for (int j = 0; j < sectionNodeList.getLength(); j++) { Node sectionNode = sectionNodeList.item(j); if (sectionNode.getNodeName().contains("control")) { control = sectionNode.getNodeName().replace("-","_"); controlColumns.add(section + "_" + control); controlData.add(sectionNode.getTextContent()); updateColumns(tablePrefix, section + "_" + control); } else if (sectionNode.getNodeName().contains("grid")) { grid = sectionNode.getNodeName().replace("-","_"); if (sectionNode.getChildNodes().getLength() > 0) for (int k = 0; k < sectionNode.getChildNodes().getLength(); k++) { controlGrid = sectionNode.getChildNodes().item(k).getNodeName() .replace("-", "_"); if (!controlGrid.contains("#text")) gridColumns.add(controlGrid); if (!controlGrid.contains("#text")) gridData.add(sectionNode.getChildNodes().item(k).getTextContent()); if (!controlGrid.contains("#text")) gridTable.add(tablePrefix + "_" + section + "_" + grid); if (!checkTable(tablePrefix + "_" + section + "_" + grid)) createGridTableAndColumns(tablePrefix + "_" + section + "_" + grid, controlGrid, tablePrefix); else updateGridColumns(tablePrefix + "_" + section + "_" + grid, controlGrid); } } } } } if (!controlData.isEmpty()) { insertControlDataToDatabase(tablePrefix, controlColumns, controlData, login); if (!gridData.isEmpty()) insertGridData(gridTable, gridData, gridColumns, tablePrefix); } } private void insertGridData(List tablePrefix, List textContent, List controlGrid, String originalTable) { StringBuilder sqlInsertGrid = new StringBuilder(); List addedData = new ArrayList<>(); String checkTable = tablePrefix.get(0); Boolean flag = false; if (tablePrefix.size() == textContent.size() && tablePrefix.size() == controlGrid.size()) { for (int i = 0; i < tablePrefix.size(); i++) { sqlInsertGrid.setLength(0); if (!checkTable.equals(tablePrefix.get(i))) { checkTable = tablePrefix.get(i); flag = !flag; } if (flag.equals(false) || addedData.contains(controlGrid.get(i))) { sqlInsertGrid.append("INSERT INTO " + checkTable + " (" + " id_" + originalTable + ", " + controlGrid.get(i) + " ) \n" + "VALUES (" + " (SELECT id from " + originalTable + " order by id desc limit 1 ), '" + textContent.get(i) + "' );"); flag = true; addedData.add(controlGrid.get(i)); } else { sqlInsertGrid .append("UPDATE " + checkTable + " \n" + "SET " + controlGrid.get(i) + " = '" + textContent.get(i) + "' \n WHERE id = " + "(SELECT id from " + checkTable + " ORDER BY id desc limit 1);"); } jdbcTemplate.update(sqlInsertGrid.toString()); } } } private void updateColumns(String tableName, String columnName) { if (checkColumn(tableName, columnName)) jdbcTemplate.update("ALTER TABLE " + tableName + "\n" + "ADD COLUMN " + columnName + " TEXT;"); } private void updateGridColumns(String tableName, String columnName) { String column = null; if (columnName.contains("control")) column = columnName; if (column !=null) if (checkColumn(tableName, columnName)) jdbcTemplate.update("ALTER TABLE " + tableName + "\n" + "ADD COLUMN " + column + " TEXT;"); } private void createGridTableAndColumns(String tableName, String columnName, String originalTable) { String column = null; if (columnName.contains("control")) column = columnName; if (column !=null) jdbcTemplate.update("CREATE TABLE " + tableName + "\n ( id BIGSERIAL, " + "id_" + originalTable + " INTEGER REFERENCES " + originalTable + "(id), \n" + column + " TEXT, \n" + "PRIMARY KEY (id, id_" + originalTable + ") );"); } private void insertControlDataToDatabase(String tablePrefix, List controlColumns, List controlData, String login) { Date date = new Date(); StringBuilder sqlInsert = new StringBuilder(); sqlInsert.setLength(0); sqlInsert .append("INSERT INTO " + tablePrefix + " ("); sqlInsert .append("SEND_DATA, LOGIN,"); Iterator iteratorColumns = controlColumns.iterator(); while (iteratorColumns.hasNext() && controlColumns.size() == controlData.size()) { sqlInsert .append(" " + iteratorColumns.next() + ","); } sqlInsert .deleteCharAt(sqlInsert.length() - 1); sqlInsert .append(" ) \n VALUES ( '" + date + "' , '" + login + "',"); for (int i = 0; i < controlData.size(); i++) { if (controlData.get(i).contains("'")) sqlInsert .append(" '" + controlData.get(i).replace("'", "") + "',"); else sqlInsert .append(" '" + controlData.get(i) + "',"); } sqlInsert .deleteCharAt(sqlInsert.length() - 1); sqlInsert .append(" );"); jdbcTemplate.update(sqlInsert.toString()); } private boolean checkTable(String tableName) { String sqlCheckTable = ("SELECT COUNT(*) FROM information_schema.tables " + "WHERE table_schema='public' AND table_name = '" + tableName + "'"); int exist = jdbcTemplate.queryForObject(sqlCheckTable, Integer.class); if (exist > 0) return true; else return false; } private boolean checkColumn(String tableName, String columnName) { String sqlCheckColumns = ("SELECT COUNT(*) FROM information_schema.columns " + "WHERE table_name='" + tableName + "' AND column_name = '" + columnName + "'"); int exist = jdbcTemplate.queryForObject(sqlCheckColumns, Integer.class); if (exist > 0) return false; else return true; } }