Browse Source

Tomcat 10 Test

ak_tomcat10_test2
Andre Knieschewski 4 weeks ago
parent
commit
ca0df12d0b
  1. 153
      src/de/memtext/util/ServletHelper.java
  2. 88
      src/de/superx/bianalysis/ColumnElement.java
  3. 157
      src/de/superx/bianalysis/ColumnElementBuilder.java
  4. 415
      src/de/superx/bianalysis/ExcelSheetBuilder.java
  5. 21
      src/de/superx/bianalysis/FaultyMetadataException.java
  6. 57
      src/de/superx/bianalysis/ReportDefinition.java
  7. 338
      src/de/superx/bianalysis/ReportMetadata.java
  8. 536
      src/de/superx/bianalysis/ResultBuilder.java
  9. 158
      src/de/superx/bianalysis/ResultMerger.java
  10. 82
      src/de/superx/bianalysis/StoredReport.java
  11. 302
      src/de/superx/bianalysis/bin/BiAnalysisCLI.java
  12. 74
      src/de/superx/bianalysis/metadata/Identifier.java
  13. 27
      src/de/superx/bianalysis/metadata/IdentifierSerializer.java
  14. 148
      src/de/superx/bianalysis/metadata/MetaImport.java
  15. 38
      src/de/superx/bianalysis/metadata/MetaImportConformedDimensions.java
  16. 58
      src/de/superx/bianalysis/metadata/MetaJson.java
  17. 593
      src/de/superx/bianalysis/metadata/MetadataImporter.java
  18. 99
      src/de/superx/bianalysis/metadata/UpsertStringBuilder.java
  19. 269
      src/de/superx/bianalysis/metadata/models/json/MetaDimension.java
  20. 179
      src/de/superx/bianalysis/metadata/models/json/MetaDimensionAttribute.java
  21. 77
      src/de/superx/bianalysis/metadata/models/json/MetaFact.java
  22. 82
      src/de/superx/bianalysis/metadata/models/json/MetaMeasure.java
  23. 106
      src/de/superx/bianalysis/metadata/models/json/MetaMeasureFilter.java
  24. 112
      src/de/superx/bianalysis/metadata/models/json/MetaObject.java
  25. 32
      src/de/superx/bianalysis/metadata/models/yml/MetaYml.java
  26. 49
      src/de/superx/bianalysis/metadata/models/yml/MetaYmlModel.java
  27. 52
      src/de/superx/bianalysis/metadata/models/yml/MetaYmlModelColumns.java
  28. 94
      src/de/superx/bianalysis/models/Dimension.java
  29. 276
      src/de/superx/bianalysis/models/DimensionAttribute.java
  30. 71
      src/de/superx/bianalysis/models/FactTable.java
  31. 89
      src/de/superx/bianalysis/models/Filter.java
  32. 89
      src/de/superx/bianalysis/models/Info.java
  33. 19
      src/de/superx/bianalysis/models/InfoItem.java
  34. 130
      src/de/superx/bianalysis/models/Measure.java
  35. 29
      src/de/superx/bianalysis/models/Right.java
  36. 21
      src/de/superx/bianalysis/models/RightParam.java
  37. 42
      src/de/superx/bianalysis/repository/DimensionAttributeRepository.java
  38. 50
      src/de/superx/bianalysis/repository/DimensionRepository.java
  39. 47
      src/de/superx/bianalysis/repository/FactRepository.java
  40. 13
      src/de/superx/bianalysis/repository/MeasureFilterRepository.java
  41. 17
      src/de/superx/bianalysis/repository/MeasureRepository.java
  42. 23
      src/de/superx/bianalysis/repository/StoredReportRepository.java
  43. 74
      src/de/superx/bianalysis/repository/dto/AttributeDto.java
  44. 79
      src/de/superx/bianalysis/repository/dto/DimensionDto.java
  45. 50
      src/de/superx/bianalysis/repository/dto/FactDto.java
  46. 66
      src/de/superx/bianalysis/repository/dto/MeasureDto.java
  47. 61
      src/de/superx/bianalysis/repository/dto/MeasureFilterDto.java
  48. 277
      src/de/superx/bianalysis/rest/BiAnalysisApi.java
  49. 141
      src/de/superx/bianalysis/service/BiAnalysisManager.java
  50. 135
      src/de/superx/bianalysis/service/BiAnalysisRightService.java
  51. 637
      src/de/superx/bianalysis/service/DbMetaAdapter.java
  52. 378
      src/de/superx/bianalysis/sqlgeneration/SQLGenerator.java
  53. 82
      src/de/superx/bianalysis/sqlgeneration/SQLGeneratorTotals.java
  54. 433
      src/de/superx/bin/AbstractWebserviceClient.java
  55. 510
      src/de/superx/bin/ComponentAdminCLI.java
  56. 674
      src/de/superx/bin/DataProfiler.java
  57. 583
      src/de/superx/bin/DelEndChar.java
  58. 147
      src/de/superx/bin/DialectCreator.java
  59. 246
      src/de/superx/bin/DoShutdown.java
  60. 559
      src/de/superx/bin/Doquery.java
  61. 254
      src/de/superx/bin/Doschema.java
  62. 453
      src/de/superx/bin/Dosql.java
  63. 298
      src/de/superx/bin/Dostmt.java
  64. 927
      src/de/superx/bin/EtlFuzzer.java
  65. 11
      src/de/superx/bin/ExcelPdfCreator.java
  66. 203
      src/de/superx/bin/ExecuteMask.java
  67. 476
      src/de/superx/bin/FMParser.java
  68. 745
      src/de/superx/bin/GxstageCSVImport.java
  69. 2
      src/de/superx/bin/Iso.java
  70. 39
      src/de/superx/bin/KettleExecutor.java
  71. 8
      src/de/superx/bin/LdapLockout.java
  72. 102
      src/de/superx/bin/MaskenSqlUpdater.java
  73. 1
      src/de/superx/bin/PasswdUpdater.java
  74. 37
      src/de/superx/bin/Pgcheck.java
  75. 1125
      src/de/superx/bin/PropAdmin.java
  76. 550
      src/de/superx/bin/PropAdminOld.java
  77. 445
      src/de/superx/bin/Psql.java
  78. 232
      src/de/superx/bin/PublicPrivateKeyManager.java
  79. 248
      src/de/superx/bin/RestrictedConnectionManager.java
  80. 418
      src/de/superx/bin/SendMail.java
  81. 25
      src/de/superx/bin/ShowEnv.java
  82. 148
      src/de/superx/bin/SimpleSoapClient.java
  83. 234
      src/de/superx/bin/SimpleTransform.java
  84. 128
      src/de/superx/bin/SpecialUpdater.java
  85. 84
      src/de/superx/bin/SxConnection.java
  86. 497
      src/de/superx/bin/SxDBUtils.java
  87. 692
      src/de/superx/bin/SxExtractor.java
  88. 654
      src/de/superx/bin/SxJasper.java
  89. 2149
      src/de/superx/bin/SxJdbcClient.java
  90. 156
      src/de/superx/bin/SxTestXmlCreator.java
  91. 11
      src/de/superx/bin/SxTransformer.java
  92. 545
      src/de/superx/bin/SxValidate.java
  93. 456
      src/de/superx/bin/SxXmlTester.java
  94. 358
      src/de/superx/bin/UnlFileConverter.java
  95. 250
      src/de/superx/bin/UnloadSqlFromXml.java
  96. 79
      src/de/superx/bin/Upgrade.java
  97. 171
      src/de/superx/bin/UploadRecords.java
  98. 143
      src/de/superx/bin/WebserviceChecker.java
  99. 271
      src/de/superx/bin/WebserviceClient.java
  100. 749
      src/de/superx/bin/WebserviceClientBewegungsdaten.java
  101. Some files were not shown because too many files have changed in this diff Show More

153
src/de/memtext/util/ServletHelper.java

@ -1,78 +1,75 @@
package de.memtext.util; package de.memtext.util;
import java.io.IOException; import java.io.IOException;
import javax.servlet.ServletException; import jakarta.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import javax.xml.transform.ErrorListener; import javax.xml.transform.ErrorListener;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import de.superx.servlet.ServletBasics; import de.superx.servlet.ServletBasics;
/** /**
* Abstrakte Basisklasse für ServletHelper-Objekt, nimmt request und response * Abstrakte Basisklasse für ServletHelper-Objekt, nimmt request und response
* und den Logger auf. Objekte, die erweitern müssen (wie bei Thread) run() * und den Logger auf. Objekte, die erweitern müssen (wie bei Thread) run()
* aufrufen. Dann wird die Authentifizierung geprüft und wenn die OK ist, wird * aufrufen. Dann wird die Authentifizierung geprüft und wenn die OK ist, wird
* die perform()-Methode des eigentlichen Objekts aufgerufen (die z.B. Maske * die perform()-Methode des eigentlichen Objekts aufgerufen (die z.B. Maske
* aufbaut oder Tabelle holt). wenn eine Exception auftritt sorgt run() dafür, * aufbaut oder Tabelle holt). wenn eine Exception auftritt sorgt run() dafür,
* dass der Fehler gemeldet wird. Als Variablen enthält diese Klasse bereits den * dass der Fehler gemeldet wird. Als Variablen enthält diese Klasse bereits den
* StringBuffer returnText mit dem geplanten Rückgabetext. Und userid mit der * StringBuffer returnText mit dem geplanten Rückgabetext. Und userid mit der
* UserId (wenn Authentifizierung OK) * UserId (wenn Authentifizierung OK)
*/ */
public abstract class ServletHelper extends ServletBasics{ public abstract class ServletHelper extends ServletBasics {
public ServletHelper(HttpServletRequest request, public ServletHelper(HttpServletRequest request, HttpServletResponse response, String sessiontype) throws IOException {
HttpServletResponse response, String sessiontype) super(request, response, sessiontype);
throws IOException { }
super(request,response,sessiontype);
} /**
* Prüft falls gewünscht die Authentifizierung (existiert eine
/** * superx-Session) danach wird die abstrakte Methode perform aufgerufen. Die
* Prüft falls gewünscht die Authentifizierung (existiert eine * meisten Exceptions werden also Infomeldung an den User weitergegeben
* superx-Session) danach wird die abstrakte Methode perform aufgerufen. Die *
* meisten Exceptions werden also Infomeldung an den User weitergegeben * @param isAuthentificationCheckWanted
* * @throws IOException
* @param isAuthentificationCheckWanted */
* @throws IOException public void run(boolean isAuthentificationCheckWanted) throws IOException, ServletException {
*/ try {
public void run(boolean isAuthentificationCheckWanted) throws IOException, if (isAuthentificationCheckWanted) {
ServletException { checkSessionType();
try { }
if (isAuthentificationCheckWanted) {
checkSessionType(); perform();
}
} catch (Exception e) {
perform();
}
} catch (Exception e) { }
} abstract protected void perform() throws Exception;
}
class DummyErrorListener implements ErrorListener {
abstract protected void perform() throws Exception;
@Override
class DummyErrorListener implements ErrorListener { public void warning(TransformerException exception) throws TransformerException {
}
public void warning(TransformerException exception)
throws TransformerException { @Override
} public void error(TransformerException exception) throws TransformerException {
}
public void error(TransformerException exception)
throws TransformerException { @Override
} public void fatalError(TransformerException exception) throws TransformerException {
System.out.println(exception);
public void fatalError(TransformerException exception) }
throws TransformerException {
System.out.println(exception); }
} }
} //Created on 30.09.2004 at 08:59:42
}
//Created on 27.02.2006 at 18:50:31
//Created on 30.09.2004 at 08:59:42
//refactored to servletBasis 10.8.2011
//Created on 27.02.2006 at 18:50:31
//refactored to servletBasis 10.8.2011

88
src/de/superx/bianalysis/ColumnElement.java

@ -0,0 +1,88 @@
package de.superx.bianalysis;
import de.superx.bianalysis.models.DimensionAttribute;
import de.superx.bianalysis.models.Measure;
public class ColumnElement {
public String caption;
public String header;
public String dimensionAttributeFilter;
public Measure measure;
public int columnNumber;
public ColumnElement(String caption, String dimensionAttributeFilter) {
this.caption = caption;
this.dimensionAttributeFilter = dimensionAttributeFilter;
}
public ColumnElement(String caption, String dimensionAttributeFilter, Measure measure, int col) {
this.caption = caption;
this.dimensionAttributeFilter = dimensionAttributeFilter;
this.measure = measure;
this.columnNumber = col;
}
public ColumnElement(Measure measure, int index) {
this.caption = "Kennzahl|" + measure.getId().composedId;
this.header = "Kennzahl|" + measure.getCaption();
this.measure = measure;
this.columnNumber = index;
}
public ColumnElement(ColumnElement currentColumnElement) {
this.caption = currentColumnElement.caption;
this.dimensionAttributeFilter = currentColumnElement.dimensionAttributeFilter;
this.measure = currentColumnElement.measure;
}
/**
* Builds the attribute part of a columns's 'field' member.
*
* The attribute part is a crucial component of the column's identifier
* and typically consists of IDs and associated values.
*
* <p>Example of an attribute part:
* <pre>
* "conf:123 : conf:124 |weiblich"
* </pre>
* </p>
*
* <p>In the context of a complete 'field' member, it might appear as:
* <pre>
* "conf:123: conf:124|weiblich || Kennzahl|res:123"
* </pre>
* where the part before "||" is the attribute part, and after is the measure.</p>
*
* The 'field' member serves as a unique identifier for each column.
*
* @see ColumnElementBuilder For the complete column building process
*/
public static String buildField(DimensionAttribute attr, String value) {
// The conformed id takes precedence, so that we can merge reports
String attrId = attr.getAttrConformedId();
if(attrId == null) {
attrId = attr.getStringId();
}
String dimId = attr.getDimConformedId();
if(dimId == null) {
dimId = attr.getDimId();
}
return dimId + ": " + attrId + "|" + value;
}
public static String buildHeader(DimensionAttribute attr, String value) {
return attr.getCaption() + ": " + attr.getCaption() + "|" + value;
}
public static String buildFilter(DimensionAttribute attr, String value) {
return attr.getDimensionTableAlias() + "." + attr.getColumnname() + " = '" + value + "'";
}
public void setHeader(String finalHeader) {
this.header = finalHeader;
}
}

157
src/de/superx/bianalysis/ColumnElementBuilder.java

@ -0,0 +1,157 @@
package de.superx.bianalysis;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
import org.apache.log4j.Logger;
import de.superx.bianalysis.models.DimensionAttribute;
import de.superx.bianalysis.models.Filter;
import de.superx.bianalysis.models.Measure;
import de.superx.common.NotYetImplementedException;
public class ColumnElementBuilder {
private static Logger logger = Logger.getLogger(ColumnElementBuilder.class);
/**
* Lets assume we have the two Dimensions X and Y each with one Attribute. DA for X
* and DB for Y. Both Attributes have two possible values DA1, DA2 and DB1, DB2. There
* also exist two Measures M1, M2.
*
* If the users wants to see all attributes and measures the header of the cross table looks like this:
*
* +-----------------------+----------------------+
* | DA1 | DA2 |
* +-----------+-----------+-----------+----------+
* | DB1 | DB2 | DB1 | DB2 |
* +-----+-----+-----+-----+-----+-----+-----+----+
* | M1 | M2 | M1 | M2 | M1 | M2 | M1 | M2 |
* +=====+=====+=====+=====+=====+=====+=====+====+
* | | | | | | | | |
* +-----+-----+-----+-----+-----+-----+-----+----+
*
* This header would be defined like follows:
*
* "X: DA | DA1 || Y: DB | DB1 || Kennzahl| M1"
* "X: DA | DA1 || Y: DB | DB1 || Kennzahl| M2"
* "X: DA | DA1 || Y: DB | DB2 || Kennzahl| M1"
* "X: DA | DA1 || Y: DB | DB2 || Kennzahl| M2"
* "X: DA | DA2 || Y: DB | DB1 || Kennzahl| M1"
* "X: DA | DA2 || Y: DB | DB1 || Kennzahl| M2"
* "X: DA | DA2 || Y: DB | DB2 || Kennzahl| M1"
* "X: DA | DA2 || Y: DB | DB2 || Kennzahl| M2"
*
* Every single line is represented by one 'ColumnElement'.
* @throws NotYetImplementedException
*/
public static List<ColumnElement> buildColumnElements(ReportMetadata metadata) {
List<Filter> filters = metadata.filters;
List<Measure> measures = metadata.measures;
List<DimensionAttribute> dimensionAttributes = metadata.topDimensionAttributes;
List<ColumnElement> columnElements = new ArrayList<ColumnElement>();
final String HEADER_DIVIDER = " || ";
final String KENNZAHL_IDENTIFIER = "Kennzahl|";
if(measures == null || measures.isEmpty()) {
// edge case 1: no measures were selected, simply return empty columnElements list
return columnElements;
}
// for every column there exists an offset of 'maxbridgelvl' if a hierarchy-attribute was selected
int colStartPoint = metadata.getHierarchyAttributes().size() * metadata.maxBridgeLvl;
if(dimensionAttributes == null || dimensionAttributes.isEmpty()) {
// edge case 2: no dimension attributes were selected, only display the measures
for (Measure measure : measures) {
columnElements.add(new ColumnElement(measure, colStartPoint + columnElements.size()));
}
return columnElements;
}
// for every single column combination (one list of combined attribute values) we build one 'ColumnElement' object
List<List<String>> dimAttrCombinations = cartesianProductOfDimensionAttributeValues(dimensionAttributes, filters);
for (int i = 0; i < dimAttrCombinations.size(); i++) {
StringJoiner captionJoiner = new StringJoiner(HEADER_DIVIDER);
StringJoiner headerJoiner = new StringJoiner(HEADER_DIVIDER);
StringJoiner filterJoiner = new StringJoiner(" AND ");
List<String> comb = dimAttrCombinations.get(i);
for(int j = 0; j < comb.size(); j++) {
DimensionAttribute attr = dimensionAttributes.get(j);
String value = comb.get(j);
captionJoiner.add(ColumnElement.buildField(attr, value));
headerJoiner.add(ColumnElement.buildHeader(attr, value));
filterJoiner.add(ColumnElement.buildFilter(attr, value));
}
String partialCaption = captionJoiner.toString();
String partialHeader = headerJoiner.toString();
String filter = filterJoiner.toString();
for (Measure measure : measures) {
String finalCaption = partialCaption + HEADER_DIVIDER + KENNZAHL_IDENTIFIER + measure.getId().composedId;
String finalHeader = partialHeader + HEADER_DIVIDER + KENNZAHL_IDENTIFIER + measure.getCaption();
ColumnElement colElement = new ColumnElement(finalCaption, filter, measure, colStartPoint + columnElements.size());
colElement.setHeader(finalHeader);
columnElements.add(colElement);
}
}
return columnElements;
}
/**
*
* Computes all possible combination of dimension attribute values.
* Each of the individual combinations is a specific column.
*
* Example
* Input: DimensionAttributes = {DA, DB}, each with two possible values DA1, DA2, DB1, DB2, Filters = { }
* Output: {{DA1, DB1}, {DA1, DB2}, {DA2, DB1}, {DA2, DB2}}
*
* If the user choose the following Filter = {DB2}
* Output: {{DA1, DB2}, {DA2, DB2}}
*
* @param dimensionAttributes The list of choosen dimension attributes.
* @param filters The list of choosen filters.
* @return A list containing the cartesian product of all the possible combination for a set of dimension attributes and filters.
*/
private static List<List<String>> cartesianProductOfDimensionAttributeValues(List<DimensionAttribute> dimensionAttributes, List<Filter> filters){
List<List<String>> allDimAttrVals = new ArrayList<>();
for (DimensionAttribute attr: dimensionAttributes) {
//if(attr.bridge != null) {
// continue;
//}
// did the user choose a filter for this attribute ?
Filter compoundFilter = Filter.findFilterById(filters, attr.getId());
if(compoundFilter != null) {
// if yes only use the filter values
allDimAttrVals.add(compoundFilter.filterValues);
} else {
// if no use all possible attribute values
allDimAttrVals.add(attr.getDimensionAttributeValues());
}
}
// compute and return all possible column combinations
return cartesian(allDimAttrVals);
}
private static List<List<String>> cartesian(List<List<String>> lists) {
List<List<String>> result = new ArrayList<>();
if(lists.size() == 0) {
result.add(new ArrayList<>());
return result;
}
List<String> curr = lists.get(0);
List<List<String>> remainingLists = cartesian(lists.subList(1, lists.size()));
for (String val : curr) {
for (List<String> list : remainingLists) {
List<String> resultList = new ArrayList<>();
resultList.add(val);
resultList.addAll(list);
result.add(resultList);
}
}
return result;
}
}

415
src/de/superx/bianalysis/ExcelSheetBuilder.java

@ -0,0 +1,415 @@
package de.superx.bianalysis;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Footer;
import org.apache.poi.ss.usermodel.Header;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import de.superx.bianalysis.models.InfoItem;
import de.superx.rest.model.Column;
import de.superx.rest.model.ColumnType;
import de.superx.rest.model.Result;
import de.superx.rest.model.ResultType;
public class ExcelSheetBuilder {
private Result result;
private XSSFWorkbook workbook;
private XSSFSheet sheet;
private String reportName;
private String reportDescription;
private String date;
private int leftDimensionAttributes;
private int topDimensionAttributes = 0;
private List<Column> visibleColumns;
private final boolean mergeCells = true;
private final int startingRow = 1;
private static HashMap<String, Integer> defaultStyles = new HashMap<>();
public ExcelSheetBuilder(Result result) {
this.result = result;
this.visibleColumns = getVisibleColumns(result);
this.workbook = new XSSFWorkbook();
initializeDefaultStyles();
leftDimensionAttributes = this.result.info.leftDimensionAttributes.size();
if(this.result.info.topDimensionAttributes != null && this.result.info.topDimensionAttributes.size() > 0) {
topDimensionAttributes = this.result.info.topDimensionAttributes.size();
}
}
public XSSFWorkbook build() {
int rowNum = startingRow;
rowNum = createRowsFromGrid(createReportInfoGrid(), rowNum);
rowNum += 2; // rows between report info and header
int reportInfoEnd = rowNum;
String[][] grid = createHeaderGrid();
rowNum = createRowsFromGrid(grid, rowNum);
rowNum = createDataRows(rowNum);
rowNum = createTotalRow(rowNum);
if(mergeCells) {
mergeHeaderCells(grid, 0, reportInfoEnd);
}
styleHeaderCells(reportInfoEnd, grid);
styleDataCells(reportInfoEnd + grid.length);
styleTotalRowCells(rowNum);
styleReportInfoCells();
Footer footer = sheet.getFooter();
Header header = sheet.getHeader();
header.setLeft(reportName);
header.setRight(this.date);
footer.setRight("Seite &P von &N");
return workbook;
}
private void initializeDefaultStyles() {
//ReportInfoCells
XSSFCellStyle infoStyle = workbook.createCellStyle();
Font infoFont = workbook.createFont();
infoFont.setBold(true);
infoStyle.setFont(infoFont);
defaultStyles.put("info", Integer.valueOf(infoStyle.getIndex()));
//Header
XSSFCellStyle headerStyle = workbook.createCellStyle();
headerStyle.setBorderBottom(BorderStyle.THIN);
headerStyle.setBorderLeft(BorderStyle.THIN);
headerStyle.setBorderRight(BorderStyle.THIN);
headerStyle.setBorderTop(BorderStyle.THIN);
Font headerFont = workbook.createFont();
headerFont.setBold(true);
headerStyle.setFont(headerFont);
defaultStyles.put("header", Integer.valueOf(headerStyle.getIndex()));
//Data
XSSFCellStyle dataStyle = workbook.createCellStyle();
dataStyle.setBorderBottom(BorderStyle.HAIR);
dataStyle.setBorderLeft(BorderStyle.HAIR);
dataStyle.setBorderRight(BorderStyle.HAIR);
dataStyle.setBorderTop(BorderStyle.HAIR);
defaultStyles.put("data", Integer.valueOf(dataStyle.getIndex()));
//Total
XSSFCellStyle totalStyle = workbook.createCellStyle();
totalStyle.setBorderBottom(BorderStyle.THIN);
totalStyle.setBorderLeft(BorderStyle.THIN);
totalStyle.setBorderRight(BorderStyle.THIN);
totalStyle.setBorderTop(BorderStyle.DOUBLE);
Font totalFont = workbook.createFont();
totalFont.setBold(true);
totalStyle.setFont(totalFont);
defaultStyles.put("total", Integer.valueOf(totalStyle.getIndex()));
}
private void styleTotalRowCells(int rowNum) {
int current = rowNum;
Row row = sheet.getRow(--current);
for (int i = 0; i < visibleColumns.size(); i++) {
Cell cell = row.getCell(i);
cell.setCellStyle(getTotalCellStyle(workbook));
}
}
private int createTotalRow(int startFrom) {
de.superx.rest.model.Row totalRow = result.getTotalRow();
int rowNum = startFrom;
Row row = sheet.createRow(rowNum++);
Cell labelCell = row.createCell(0);
labelCell.setCellValue("Gesamt");
for (int i = 1; i < visibleColumns.size(); i++) {
Column col = visibleColumns.get(i);
Cell cell = row.createCell(i);
if(col.type.equals(ColumnType.StringColumn)) {
cell.setCellValue("");
} else {
Object obj = totalRow.cells.get(col.field);
if(obj == null) {
cell.setCellValue("");
continue;
}
Double value = Double.valueOf(String.valueOf(obj));
cell.setCellValue(value.doubleValue());
}
}
return rowNum;
}
private void styleReportInfoCells() {
Row row = sheet.getRow(startingRow);
Cell cell = row.getCell(0);
cell.setCellStyle(workbook.getCellStyleAt(defaultStyles.get("info").intValue()));
}
private String[][] createReportInfoGrid() {
List<List<String>> gridList = new ArrayList<>();
gridList.add(List.of("Informationen zur BI-Analyse", ""));
gridList.add(List.of("Name:", this.reportName));
gridList.add(List.of("Beschreibung:", this.reportDescription));
String sachgebiet = this.result.info.sachgebiete.stream().collect(Collectors.joining(", "));
String theme = getInfoCaptions(this.result.info.facttables);
String measures = getInfoCaptions(this.result.info.measures);
String topAttributes = getInfoCaptions(this.result.info.topDimensionAttributes);
String leftAttributes = getInfoCaptions(this.result.info.leftDimensionAttributes);
String filter = this.result.info.filter.stream().collect(Collectors.joining(", "));
String lastUpdateBad = this.result.info.lastUpdateBiad;
if(sachgebiet != null) {
gridList.add(List.of("Sachgebiet:", sachgebiet));
}
if(theme != null) {
gridList.add(List.of("Thema:", theme));
}
if(measures != null) {
gridList.add(List.of("Kennzahlen:", measures));
}
if(leftAttributes != null) {
gridList.add(List.of("Zeilenattribute:", leftAttributes));
}
if(topAttributes != null) {
gridList.add(List.of("Spaltenattribute:", topAttributes));
}
if(filter != null) {
gridList.add(List.of("Filter:", filter));
}
if(lastUpdateBad != null) {
gridList.add(List.of("Letztes Update von BI-Analyse-Daten:", lastUpdateBad));
}
if(result.resultType.equals(ResultType.FlatTable)) {
gridList.add(List.of("Tabellentyp:", "Flache Tabelle"));
} else if(result.resultType.equals(ResultType.DrilldownTableGroupable)) {
gridList.add(List.of("Tabellentyp:", "Hierarchische Tabelle"));
}
return listToStringGrid(gridList);
}
private static String getInfoCaptions(List<InfoItem> infoItems) {
if(infoItems != null && infoItems.size() > 0) {
return infoItems.stream().map(f->f.caption).collect(Collectors.joining(", "));
}
return "";
}
private static String[][] listToStringGrid(List<List<String>> list) {
String[][] result = new String[list.size()][list.get(0).size()];
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result[i].length; j++) {
result[i][j] = list.get(i).get(j);
}
}
return result;
}
private static CellRangeAddress mergeCellByOffset(int firstRow, int lastRow, int firstCol, int lastCol, int xOffset, int yOffset) {
return new CellRangeAddress(firstRow + yOffset, lastRow + yOffset, firstCol + xOffset, lastCol + xOffset);
}
private void styleHeaderCells(int start, String[][] grid) {
for (int i = 0; i < grid.length; i++) {
Row row = this.sheet.getRow(i+start);
row.setHeightInPoints((short) 25);
for (int j = 0; j < grid[i].length; j++) {
Cell cell = row.getCell(j);
cell.setCellStyle(getHeaderStyle(workbook));
}
}
}
private static CellStyle getHeaderStyle(XSSFWorkbook workbook) {
return workbook.getCellStyleAt(defaultStyles.get("header").intValue());
}
private static CellStyle getDataCellStyle(XSSFWorkbook workbook) {
return workbook.getCellStyleAt(defaultStyles.get("data").intValue());
}
private static CellStyle getTotalCellStyle(XSSFWorkbook workbook) {
return workbook.getCellStyleAt(defaultStyles.get("total").intValue());
}
private void styleDataCells(int startDataCells) {
for (int i = startDataCells; i < startDataCells + this.result.rows.size(); i++) {
Row row = this.sheet.getRow(i);
for (int j = 0; j < this.visibleColumns.size(); j++) {
Cell cell = row.getCell(j);
if(this.visibleColumns.get(j).groupable) {
cell.setCellStyle(getHeaderStyle(workbook));
} else {
cell.setCellStyle(getDataCellStyle(workbook));
}
}
}
}
private void mergeHeaderCells(String grid[][], int xOffset, int yOffset) {
// merge header grid cells
if(topDimensionAttributes > 0) {
for(int i = 0; i < grid.length; i++) {
String lastCell = "";
int cellsToMerge = 0;
for (int j = 0; j < grid[i].length; j++) {
String currentCell = grid[i][j];
if(!currentCell.equals(lastCell) && cellsToMerge > 0) {
sheet.addMergedRegion(mergeCellByOffset(i, i, j - cellsToMerge - 1, j - 1, xOffset, yOffset));
}
if(currentCell.equals(lastCell)) {
cellsToMerge++;
} else {
cellsToMerge = 0;
}
lastCell = currentCell;
}
if(cellsToMerge > 0) {
int j = grid[i].length - 1;
sheet.addMergedRegion(mergeCellByOffset(i, i, j - cellsToMerge, j, xOffset, yOffset));
}
}
}
// merge left header cols
if(grid.length > 1) {
for (int i = 0; i < leftDimensionAttributes; i++) {
sheet.addMergedRegion(mergeCellByOffset(0, grid.length - 1, i, i, xOffset, yOffset));
}
}
}
private int createRowsFromGrid(String[][] grid, int startFrom) {
if(grid == null) {
return startFrom;
}
int rowNum = startFrom;
for (int i = 0; i < grid.length; i++) {
Row poiRow = sheet.createRow(rowNum++);
int colNum = 0;
for (int j = 0; j < grid[i].length; j++) {
Cell cell = poiRow.createCell(colNum++);
if(grid[i][j] != null && !grid[i][j].isBlank()) {
cell.setCellValue(grid[i][j]);
} else {
cell.setBlank();
}
}
}
return rowNum;
}
private int createDataRows(int startFrom) {
int rowNum = startFrom;
// build cells from row data without sumrow
List<de.superx.rest.model.Row> resultRows = result.rows.stream().filter(r -> r.aggregated != -1).collect(Collectors.toList());
Row[] rows = new Row[resultRows.size()];
for (int i = 0; i < resultRows.size(); i++) {
rows[i] = sheet.createRow(rowNum++);
rows[i].setHeightInPoints((short) 20);
}
for (int i = 0; i < visibleColumns.size(); i++) {
Column col = visibleColumns.get(i);
for(int j = 0; j < resultRows.size(); j++) {
Object obj = resultRows.get(j).cells.get(col.field);
String objVal = String.valueOf(obj);
Cell cell = rows[j].createCell(i);
if(obj == null) {
cell.setBlank();
continue;
}
if(col.type == ColumnType.IntegerColumn || col.type == ColumnType.DecimalColumn) {
Double value = Double.valueOf(objVal);
cell.setCellValue(value.doubleValue());
} else {
cell.setCellValue(obj.toString());
}
//if(col.groupable) {
// cell.setCellStyle(style);
//}
}
}
return rowNum;
}
private String[][] createHeaderGrid(){
int colSize = visibleColumns.size();
int rowSize = topDimensionAttributes + 1;
String[][] grid = new String[rowSize][colSize];
for(int i = 0; i < colSize; i++) {
Column column= this.visibleColumns.get(i);
String[] columnHeader = column.header.split("\\|\\|");
boolean isLeftDimensionAttributeColumn = (columnHeader.length == 1 && !columnHeader[0].contains("|"))? true : false;
for(int j = 0; j < rowSize; j++) {
if(isLeftDimensionAttributeColumn) {
grid[j][i] = columnHeader[0];
}else {
String header = columnHeader[j];
String[] headerValues = header.split("\\|");
grid[j][i] = headerValues[1];
}
}
}
return grid;
}
public ExcelSheetBuilder withFileName(String name) {
this.sheet = workbook.createSheet(name);
return this;
}
public ExcelSheetBuilder withReportName(String name) {
this.reportName = replaceEmptyString(name, "Nicht gespeicherte BI-Analyse");
return this;
}
public ExcelSheetBuilder withDescription(String description) {
this.reportDescription = replaceEmptyString(description, "-");
return this;
}
private static String replaceEmptyString(String value, String replacement) {
if(value == null || value.isBlank()) {
return replacement;
}
return value;
}
public ExcelSheetBuilder withDate(Date currentDate) {
this.date = new SimpleDateFormat("dd.MM.yyyy HH:mm").format(currentDate);
return this;
}
private static List<Column> getVisibleColumns(Result result) {
return result.columns
.stream()
.filter(col -> !col.hidden)
.collect(Collectors.toList());
}
}

21
src/de/superx/bianalysis/FaultyMetadataException.java

@ -0,0 +1,21 @@
package de.superx.bianalysis;
import de.superx.bianalysis.metadata.Identifier;
public class FaultyMetadataException extends RuntimeException {
private static final long serialVersionUID = -5959640234409065198L;
public FaultyMetadataException(String message) {
super(message);
}
public FaultyMetadataException(Identifier id) {
super("Metadata Object with ID: '" + id.composedId + "' does not exist.");
}
public FaultyMetadataException(Identifier id, String metaType) {
super("Metadata " + metaType + " with ID: '" + id.composedId + "' does not exist.");
}
}

57
src/de/superx/bianalysis/ReportDefinition.java

@ -0,0 +1,57 @@
package de.superx.bianalysis;
import java.util.ArrayList;
import java.util.List;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.models.Filter;
import de.superx.bianalysis.service.DbMetaAdapter;
public class ReportDefinition {
public List<Identifier> factTableIds;
public List<Identifier> leftDimensionAttributeIds;
public List<Identifier> topDimensionAttributeIds;
public List<Identifier> measureIds;
public List<Filter> filters;
public boolean hideEmptyColumns;
public ReportDefinition() {
this.factTableIds = new ArrayList<>();
this.leftDimensionAttributeIds = new ArrayList<>();
this.topDimensionAttributeIds = new ArrayList<>();
this.measureIds = new ArrayList<>();
this.filters = new ArrayList<>();
this.hideEmptyColumns = false;
}
public ReportDefinition(ReportDefinition definition) {
super();
this.factTableIds = definition.factTableIds;
this.topDimensionAttributeIds = definition.topDimensionAttributeIds;
this.measureIds = definition.measureIds;
this.filters = definition.filters;
this.leftDimensionAttributeIds = new ArrayList<>();
this.hideEmptyColumns = definition.hideEmptyColumns;
}
public ReportMetadata getReportMetadata(DbMetaAdapter dbAdapter, Identifier factTableId) {
ReportMetadata reportMetadata = new ReportMetadata(this, factTableId, dbAdapter);
return reportMetadata;
}
public static List<Identifier> getAttributesForDefinitions(List<ReportDefinition> definitions){
List<Identifier> ids = new ArrayList<>();
for (ReportDefinition def : definitions) {
for (Identifier id : def.topDimensionAttributeIds) {
ids.add(id);
}
for (Identifier id : def.leftDimensionAttributeIds) {
ids.add(id);
}
}
return ids;
}
}

338
src/de/superx/bianalysis/ReportMetadata.java

@ -0,0 +1,338 @@
package de.superx.bianalysis;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.models.DimensionAttribute;
import de.superx.bianalysis.models.FactTable;
import de.superx.bianalysis.models.Filter;
import de.superx.bianalysis.models.InfoItem;
import de.superx.bianalysis.models.Measure;
import de.superx.bianalysis.service.DbMetaAdapter;
import de.superx.jdbc.entity.Sachgebiet;
public class ReportMetadata {
public final FactTable factTable;
public final Sachgebiet sachgebiet;
public final List<DimensionAttribute> leftDimensionAttributes;
public final List<DimensionAttribute> topDimensionAttributes;
public final List<Measure> measures;
public final List<Filter> filters;
public String lastBiadUpdate;
// only used if hierarchy dimension is present in left dim attributes
public int maxBridgeLvl;
public int minBridgeLvl;
public DbMetaAdapter dbMetaAdapter;
public boolean hideEmptyColumns;
public ReportMetadata(ReportDefinition reportDefinition, Identifier factTableId, DbMetaAdapter dbAdapter) {
this.dbMetaAdapter = dbAdapter;
if(factTableId == null) { // merged Report
this.factTable = new FactTable();
this.sachgebiet = new Sachgebiet();
} else {
this.factTable = dbAdapter.getFactTable(factTableId);
this.sachgebiet = dbAdapter.getSachgebietById(this.factTable.getSachgebiettid());
}
List<DimensionAttribute> databaseOrderedLeftDimensionAttributes = dbAdapter.getDimensionAttributeMetadata(reportDefinition.leftDimensionAttributeIds, factTableId);
this.leftDimensionAttributes = reorderDimensionAttributesToReportOrder(databaseOrderedLeftDimensionAttributes, reportDefinition, false);
List<DimensionAttribute> databaseOrderedTopDimensionAttributes = dbAdapter.getDimensionAttributeMetadata(reportDefinition.topDimensionAttributeIds, factTableId);
this.topDimensionAttributes = reorderDimensionAttributesToReportOrder(databaseOrderedTopDimensionAttributes, reportDefinition, true);
List<Measure> databaseOrderedMeasures = dbAdapter.getMeasureMetadata(reportDefinition.measureIds);
this.measures = reorderMeasuresToReportOrder(databaseOrderedMeasures, reportDefinition);
if (reportDefinition.filters != null) {
this.filters = dbAdapter.getFilterMetadata(reportDefinition.filters);
} else {
this.filters = new ArrayList<Filter>();
}
this.setTopDimensionAttributeValues(dbAdapter);
if(factTableId != null) {
this.setMaxBridgeLvl();
} else {
// for merged report
this.setMaxBridgeLvlForConformed(reportDefinition.factTableIds);
}
this.lastBiadUpdate = dbAdapter.getLastUpdate(440);
this.hideEmptyColumns = reportDefinition.hideEmptyColumns;
}
public ReportMetadata(ReportMetadata metadata, List<DimensionAttribute> leftDimensionAttributes) {
this.dbMetaAdapter = metadata.dbMetaAdapter;
this.factTable = metadata.factTable;
this.sachgebiet = metadata.sachgebiet;
this.topDimensionAttributes = metadata.topDimensionAttributes;
this.measures = metadata.measures;
this.filters = metadata.filters;
this.leftDimensionAttributes = leftDimensionAttributes;
this.hideEmptyColumns = metadata.hideEmptyColumns;
}
public ReportMetadata() {
this.factTable = new FactTable();
this.sachgebiet = new Sachgebiet();
this.leftDimensionAttributes = new ArrayList<>();
this.topDimensionAttributes = new ArrayList<>();
this.measures = new ArrayList<>();
this.filters = new ArrayList<>();
}
public List<DimensionAttribute> getSortOrderLeftDimensionAttributes(){
return leftDimensionAttributes.stream().filter(d -> d.getSortOrderColumn() != null).collect(Collectors.toList());
}
private void setMaxBridgeLvl() {
List<DimensionAttribute> attrs = leftDimensionAttributes
.stream()
.filter(a -> a.isHierarchy() )
.collect(Collectors.toList());
if(attrs.size() > 1) {
throw new RuntimeException("NOT YET IMPLEMENTED: There can only be one hierarchy attribute.");
}
if(!attrs.isEmpty()) {
this.maxBridgeLvl = dbMetaAdapter.getBridgeMaxLevel(attrs.get(0), this);
this.minBridgeLvl = dbMetaAdapter.getBridgeMinLevel(getHierarchyFilter(), this.maxBridgeLvl, attrs.get(0).getTablename());
}
}
private void setMaxBridgeLvlForConformed(List<Identifier> factTableIds) {
List<DimensionAttribute> attrs = leftDimensionAttributes
.stream()
.filter(a -> a.isHierarchy())
.collect(Collectors.toList());
if(!attrs.isEmpty()) {
DimensionAttribute attr = attrs.get(0);
int lvl = 0;
for (Identifier fact : factTableIds) {
String name = dbMetaAdapter.getFactTableNameMaxBridgeLvl(fact, attr.getId());
if(name == null || name.isBlank()) {
continue;
}
int value = -1;
Identifier checkedAttr = dbMetaAdapter.checkIfFactTableHasDimensionAttribute(attr.getId(), fact);
if (checkedAttr != null && !checkedAttr.equals(attr.getId())) {
DimensionAttribute rolePlayingAttribute = dbMetaAdapter.getDimensionAttributeMetadataById(checkedAttr);
value = dbMetaAdapter.getBridgeMaxLevel(rolePlayingAttribute, this, name);
}
if (value > lvl) {
lvl = value;
}
}
this.maxBridgeLvl = lvl;
}
}
private void setTopDimensionAttributeValues(DbMetaAdapter dbAdapter) {
for(DimensionAttribute attr : this.topDimensionAttributes) {
Filter filter = getFilterForDimensionAttribute(attr.getId());
if(filter != null) {
attr.setDimensionAttributeValues(filter.filterValues);
} else {
attr.setDimensionAttributeValues(dbAdapter.getDimensionAttributeValues(attr, null, null));
}
}
}
private Filter getFilterForDimensionAttribute(Identifier id) {
return this.filters
.stream()
.filter(f -> f.dimensionAttributeId.equals(id))
.findFirst()
.orElse(null);
}
private static List<Measure> reorderMeasuresToReportOrder(List<Measure> measures, ReportDefinition reportDefinition) {
List<Measure> orderedMeasures = new ArrayList<Measure>();
reportDefinition.measureIds.forEach(measureId -> {
Measure nextMeasure = measures
.stream()
.filter( measure -> measure.getId().equals( measureId ) )
.findFirst()
.orElse(null);
orderedMeasures.add(nextMeasure);
});
return orderedMeasures;
}
public static List<DimensionAttribute> reorderDimensionAttributesToReportOrder(List<DimensionAttribute> dimensionAttributes, ReportDefinition reportDefinition, boolean isTopAttribute) {
List<DimensionAttribute> orderedDimensionAttributes = new ArrayList<DimensionAttribute>();
List<Identifier> attributeIds;
if (isTopAttribute) {
attributeIds = reportDefinition.topDimensionAttributeIds;
} else {
attributeIds = reportDefinition.leftDimensionAttributeIds;
}
attributeIds.forEach(attributeId -> {
DimensionAttribute nextAttribute = dimensionAttributes
.stream()
.filter( dimensionAttribute -> dimensionAttribute.getId().equals( attributeId ))
.findFirst()
.orElse(null);
orderedDimensionAttributes.add(nextAttribute);
});
return orderedDimensionAttributes;
}
public DimensionAttribute getDimById(Identifier id) {
DimensionAttribute attr = topDimensionAttributes
.stream()
.filter(a -> a.getDimensionId().equals(id))
.findFirst()
.orElse(null);
if(attr != null) {
return attr;
}
attr = leftDimensionAttributes
.stream()
.filter(a -> a.getDimensionId().equals(id))
.findFirst()
.orElse(null);
return attr;
}
public DimensionAttribute getDimAttrById(Identifier id) {
DimensionAttribute attr = topDimensionAttributes
.stream()
.filter(a -> a.getId().equals(id))
.findFirst()
.orElse(null);
if(attr != null) {
return attr;
}
attr = leftDimensionAttributes
.stream()
.filter(a -> a.getId().equals(id))
.findFirst()
.orElse(null);
return attr;
}
/**
* We want to join dimension tables only once. There we need a list of unique ids of
* the dimensions, otherwise we duplicate our joins.
*/
public List<DimensionAttribute> getUniqueDimensionAttributes(){
Map<String, DimensionAttribute> joinTables = new HashMap<String, DimensionAttribute>();
for (DimensionAttribute attr : leftDimensionAttributes) {
if(!joinTables.containsKey(attr.getDimensionTableAlias())) {
joinTables.put(attr.getDimensionTableAlias(), attr);
}
}
for (DimensionAttribute attr : topDimensionAttributes) {
if(!joinTables.containsKey(attr.getDimensionTableAlias())) {
joinTables.put(attr.getDimensionTableAlias(), attr);
}
}
// join dimension if attribute occurs in filter
for (Filter filter : filters) {
Identifier attrId = filter.dimensionAttributeId;
DimensionAttribute attr = dbMetaAdapter.getDimensionAttributeMetadataById(attrId);
if(!joinTables.containsKey(attr.getDimensionTableAlias())) {
joinTables.put(attr.getDimensionTableAlias(), attr);
}
}
// join dimension if measure has a filter for an attribute
for (Measure measure : measures) {
if(measure.filterAttributeId != null) {
Identifier attrId = measure.filterAttributeId;
DimensionAttribute attr = dbMetaAdapter.getDimensionAttributeMetadataById(attrId);
if(!joinTables.containsKey(attr.getDimensionTableAlias())) {
joinTables.put(attr.getDimensionTableAlias(), attr);
}
}
}
return new ArrayList<DimensionAttribute>(joinTables.values());
}
public List<InfoItem> getMeasureInfo() {
if(measures != null && !measures.isEmpty()) {
return measures.stream().map(m->
new InfoItem(m.getId().composedId, m.getCaption(), m.getDescription())).collect(Collectors.toList());
}
return null;
}
public List<InfoItem> getTopDimAttrAsInfo() {
if(topDimensionAttributes != null && !topDimensionAttributes.isEmpty()) {
return topDimensionAttributes.stream().map(m->
new InfoItem(m.getStringId(), m.getCaption(), m.getDescription())).collect(Collectors.toList());
}
return null;
}
public List<Filter> getFilterNoHierarchy() {
List<Filter> filterNoBridge = new ArrayList<>();
for (Filter filter : this.filters) {
DimensionAttribute attr = dbMetaAdapter.getDimensionAttributeById(filter.dimensionAttributeId);
if(!attr.isHierarchy()) {
filterNoBridge.add(filter);
}
}
return filterNoBridge;
}
public List<InfoItem> getLeftDimAttrAsInfo() {
if(leftDimensionAttributes != null && !leftDimensionAttributes.isEmpty()) {
return leftDimensionAttributes.stream().map(m->
new InfoItem(m.getStringId(), m.getCaption(), m.getDescription())).collect(Collectors.toList());
}
return null;
}
public List<String> getFilterAsInfo(){
ArrayList<String> filterList = new ArrayList<String>();
DimensionAttribute dimAttr;
for (Filter filter: filters) {
dimAttr = filter.getDimAttribute(this);
if(dimAttr == null) {
dimAttr = dbMetaAdapter.getDimensionAttributeById(filter.dimensionAttributeId);
}
filterList.add(" (" + dimAttr.getCaption() + ") " + filter.getValuesAsString());
}
return filterList;
}
public List<DimensionAttribute> getHierarchyAttributes() {
return leftDimensionAttributes
.stream()
.filter(a -> a.isHierarchy())
.collect(Collectors.toList());
}
public List<Filter> getHierarchyFilter(){
List<Filter> hierarchyFilter = new ArrayList<>();
for (Filter filter : this.filters) {
if(isHierarchyFilter(filter)) {
hierarchyFilter.add(filter);
}
}
return hierarchyFilter;
}
public boolean isHierarchyFilter(Filter filter) {
return dbMetaAdapter.isAttributeHierarchyBridge(filter.dimensionAttributeId);
}
}

536
src/de/superx/bianalysis/ResultBuilder.java

@ -0,0 +1,536 @@
package de.superx.bianalysis;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import de.superx.bianalysis.models.DimensionAttribute;
import de.superx.bianalysis.models.InfoItem;
import de.superx.bianalysis.models.Measure;
import de.superx.rest.model.Column;
import de.superx.rest.model.ColumnType;
import de.superx.rest.model.Item;
import de.superx.rest.model.Result;
import de.superx.rest.model.ResultType;
import de.superx.rest.model.Row;
public class ResultBuilder {
private static final boolean IGNORE_SELF_LOOPS = true;
private DataSource dataSource;
private ReportMetadata reportMetadata;
private List<ColumnElement> columnElements;
Logger logger = Logger.getLogger(ResultBuilder.class);
public ResultBuilder() {}
// used for testing
public ResultBuilder(ReportMetadata metadata, List<ColumnElement> columns) {
this.reportMetadata = metadata;
this.columnElements = columns;
}
public ResultBuilder(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setReportMetadata(ReportMetadata reportMetadata) {
this.reportMetadata = reportMetadata;
}
public void setColumnElements(List<ColumnElement> columnElements) {
this.columnElements = columnElements;
}
private Row buildRowCells(ResultSet rs) {
Row row = new Row();
Map<String, Object> cells = new TreeMap<String, Object>();
if (reportMetadata.leftDimensionAttributes != null && !reportMetadata.leftDimensionAttributes.isEmpty()) {
int aggregationLvl = reportMetadata.leftDimensionAttributes.size() -1;
for (DimensionAttribute dimensionAttribute : reportMetadata.leftDimensionAttributes) {
if(dimensionAttribute.isHierarchy()) {
try {
String prevLbl = "";
int countLvl = 0;
aggregationLvl += reportMetadata.maxBridgeLvl - reportMetadata.minBridgeLvl - 1;
for (int i = reportMetadata.minBridgeLvl; i < reportMetadata.maxBridgeLvl; i++) {
Object cell = rs.getObject("col" + i);
String curLbl = (String) cell;
if(cell == null) {
// An empty cell means a lower aggregation level because
// of how the GROUP BY ROLLUP works.
aggregationLvl--;
}
if(IGNORE_SELF_LOOPS &&
curLbl != null &&
curLbl != "" &&
curLbl.equals(prevLbl)) {
// If the cell label is equal to the previous cell label
// then this row contains a self loop, meaning the node is
// both its own parent and child. This happens due to the
// GROUP BY ROLLUP part of the sql statement, which groups
// columns in which the same node can appear right next to
// each other in two columns.
continue;
}
String id = dimensionAttribute.getAttrConformedId();
if(id == null) {
id = dimensionAttribute.getStringId();
}
String cellKey = id + " (Ebene " + countLvl + ")";
if(countLvl == 0) {
cellKey = dimensionAttribute.getAttrConformedId();
}
if(cell != null && cellKey != null) {
cells.put(cellKey, cell);
row.rowKey += cellKey + cell;
countLvl++;
}
prevLbl = (String) cell;
}
} catch (SQLException e) {
e.printStackTrace();
}
} else {
try {
Object val = rs.getObject(dimensionAttribute.getDimensionColumnAlias());
if(val != null) {
String id = dimensionAttribute.getAttrConformedId();
if(id == null) {
id = dimensionAttribute.getStringId();
}
cells.put(id, val);
row.rowKey += id + val;
} else {
aggregationLvl--;
}
} catch (SQLException e) {
e.printStackTrace();
}
if(dimensionAttribute.getSortOrderColumn() != null) {
try {
String id = dimensionAttribute.getAttrConformedId();
if(id == null) {
id = dimensionAttribute.getStringId();
}
cells.put(id + "_sorting", rs.getObject(dimensionAttribute.getDimensionColumnAlias()+"_"+dimensionAttribute.getSortOrderColumn()));
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
try {
row.aggregated = aggregationLvl;
if(row.aggregated == -1) {
int colNum = this.reportMetadata.maxBridgeLvl + this.columnElements.size() - this.reportMetadata.measures.size();
for (Measure measure : reportMetadata.measures) {
cells.put(getTotalCellHeaderPrefix(reportMetadata) + measure.getId().composedId, rs.getObject("col" + (colNum++)));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
if (!columnElements.isEmpty()) {
for (ColumnElement columnElement : columnElements) {
try {
cells.put(columnElement.caption, rs.getObject("col" + columnElement.columnNumber));
} catch (SQLException e) {
e.printStackTrace();
}
}
}
row.cells = cells;
return row;
}
public static List<Column> buildColumns(ReportMetadata reportMetadata, List<ColumnElement> columnElements) {
List<Column> columns = new ArrayList<Column>();
if (reportMetadata.leftDimensionAttributes != null) {
reportMetadata.leftDimensionAttributes.forEach((dimensionAttribute) -> {
String id = dimensionAttribute.getAttrConformedId();
if(id == null) {
id = dimensionAttribute.getStringId();
}
if(dimensionAttribute.isHierarchy()) {
int cnt = 0;
for (int i = reportMetadata.minBridgeLvl; i < reportMetadata.maxBridgeLvl - 1; i++) {
if(cnt == 0) {
columns.add(new Column(id, dimensionAttribute.getCaption(), ColumnType.StringColumn, true));
} else {
String caption = id + " (Ebene " + cnt + ")";
String header = dimensionAttribute.getCaption() + " (Ebene " + (cnt) + ")";
columns.add(new Column(caption, header, ColumnType.HierarchyLevelColumn, true, id, false));
}
cnt += 1;
}
} else {
if(dimensionAttribute.getSortOrderColumn() != null) {
columns.add(new Column(id, dimensionAttribute.getCaption(), ColumnType.StringColumn, true, dimensionAttribute.getStringId() + "_sorting", false));
columns.add(new Column(id + "_sorting", dimensionAttribute.getCaption(), ColumnType.SortOrderColumn, false, dimensionAttribute.getStringId(), true));
}else {
columns.add(new Column(id, dimensionAttribute.getCaption(), ColumnType.StringColumn, true));
}
}
});
}
if (!columnElements.isEmpty()) {
columnElements.forEach((columnElement) -> {
Column col = new Column(columnElement.caption, columnElement.header, columnElement.measure.getMeasureType(), false);
col.aggregation = columnElement.measure.getAggregationType();
columns.add(col);
});
}
return columns;
}
public List<Row> getRowsForReport(String sqlStatement, Connection con) {
List<Row> rows = null;
try (Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sqlStatement)) {
rows = buildRowList(rs);
} catch (SQLException e) {
System.out.println(sqlStatement);
throw new RuntimeException(e);
}
return rows;
}
public List<Row> buildRowList(ResultSet rs) throws SQLException {
List<Row> rows = new ArrayList<>();
while (rs.next()) {
Row row = buildRowCells(rs);
rows.add(row);
}
List<Row> result = new ArrayList<>();
if (reportMetadata.getHierarchyAttributes().size() > 0) {
HashMap<String, Row> keys = new HashMap<>();
for (Row row : rows) {
if (keys.containsKey(row.rowKey)) {
Row currentRow = keys.get(row.rowKey );
if (currentRow.aggregated > row.aggregated) {
keys.put(currentRow.rowKey , row);
}
// workaround: fix multiple aggregated rows, take only highest
if(currentRow.aggregated == -1 && row.aggregated == -1) {
for(String cell : currentRow.cells.keySet()) {
Number currentCellVal = (Number) currentRow.cells.get(cell);
Number candidateVal = (Number) row.cells.get(cell);
if(candidateVal.doubleValue() > currentCellVal.doubleValue()) {
keys.put(currentRow.rowKey, row);
}
}
}
} else {
keys.put(row.rowKey, row);
}
}
rows = new ArrayList<Row>(keys.values());
}
for (Row row : rows) {
if(row != null) {
result.add(row);
}
}
return rows;
}
public Result buildReport(List<Item> sqlStatements, boolean isCreateRight) {
JdbcTemplate jt = new JdbcTemplate(dataSource);
Result report;
report = new Result();
if(isCreateRight) {
report.info.setSqlStatements(sqlStatements);
}
String sql = findByLabel(sqlStatements, "noAggregatesSQL").value;
String sqlColumnTotal = findByLabel(sqlStatements, "totalsColumnSQL").value;
List<Column> columns = buildColumns(reportMetadata, columnElements);
List<Row> rows = null;
List<Row> totalColumns = null;
try (Connection con = jt.getDataSource().getConnection()){
rows = getRowsForReport(sql, con);
} catch (Exception e) {
logger.error(e);
e.printStackTrace();
report.info.setSegmentCaption(reportMetadata.factTable.getCaption());
report.info.setErrorMessage(e.getCause().getMessage());
return report;
}
// add one column for each measure to the report with the total sum
if(!reportMetadata.topDimensionAttributes.isEmpty()) {
try {
totalColumns = getTotalColumnResult(sqlColumnTotal, jt);
ResultBuilder.setTotalColumnToColumns(columns, reportMetadata);
ResultBuilder.setTotalColumnToRows(rows, totalColumns);
} catch (Exception e) {
e.printStackTrace();
report.info.setErrorMessage("Die Gesamtspalte konnte nicht ermittelt werden.");
}
}
setAttributesToReport(report, reportMetadata, rows, columns);
try {
if(reportMetadata.hideEmptyColumns) {
removeEmptyColumns(columns, rows);
}
} catch(Exception e ) {
logger.error(e);
}
return report;
}
public static void removeEmptyColumns(List<Column> columns, List<Row> rows) {
HashMap<String, Integer> map = new HashMap<>();
for (Column col : columns) {
if(!map.containsKey(col.field)) {
map.put(col.field, Integer.valueOf(-1));
}
}
for (Row row : rows) {
for (String cellKey : row.cells.keySet()) {
Object value = row.cells.get(cellKey);
if(value instanceof Number) {
Number val = (Number) value;
if(val.intValue() != 0) {
if(map.containsKey(cellKey)) {
map.remove(cellKey);
}
}
} else {
if(value == null) {
continue;
}
if(map.containsKey(cellKey)) {
map.remove(cellKey);
}
}
}
}
for (Row row : rows) {
for(String key : map.keySet()) {
if(row.cells.containsKey(key)) {
row.cells.remove(key);
}
}
}
if(rows.size() > 1) {
for(Iterator<Column> iterator = columns.iterator(); iterator.hasNext(); ) {
if(map.containsKey(iterator.next().field))
iterator.remove();
}
}
}
public static void setAttributesToReport(Result report, ReportMetadata reportMetadata, List<Row> rows, List<Column> columns) {
report.setResultType(ResultType.DrilldownTableGroupable);
report.setRows(rows);
report.setColumns(columns);
if(reportMetadata.factTable.getCaption() != null) {
report.info.setSegmentCaption(reportMetadata.factTable.getCaption());
InfoItem facttableInfo = new InfoItem (reportMetadata.factTable.getId().composedId,
reportMetadata.factTable.getCaption(),
reportMetadata.factTable.getDescription());
report.info.addFacttable(facttableInfo);
report.info.addSachgebiet(reportMetadata.sachgebiet.name);
}
report.info.setMeasures(reportMetadata.getMeasureInfo());
report.info.setLeftDimensionAttributes(reportMetadata.getLeftDimAttrAsInfo());
report.info.setTopDimensionAttributes(reportMetadata.getTopDimAttrAsInfo());
report.info.setFilter(reportMetadata.getFilterAsInfo());
report.info.setLastUpdateBiad(reportMetadata.lastBiadUpdate);
report.info.hideEmptyColumns(reportMetadata.hideEmptyColumns);
}
private static String getTotalCellHeaderPrefix(ReportMetadata reportMetadata) {
String totalCellHeaderPrefix = "";
for (int i = 0; i < reportMetadata.topDimensionAttributes.size(); i++) {
DimensionAttribute attr = reportMetadata.topDimensionAttributes.get(i);
if(i == 0) {
totalCellHeaderPrefix += ColumnElement.buildField(attr, "Gesamt");
} else {
totalCellHeaderPrefix += ColumnElement.buildField(attr, " ");
}
}
totalCellHeaderPrefix += " || Kennzahl|";
return totalCellHeaderPrefix;
}
private static String getTotalCellHeaderPrefixHeader(ReportMetadata reportMetadata) {
String totalCellHeaderPrefix = "";
for (int i = 0; i < reportMetadata.topDimensionAttributes.size(); i++) {
DimensionAttribute attr = reportMetadata.topDimensionAttributes.get(i);
if(i == 0) {
totalCellHeaderPrefix += attr.getCaption() + ": " + attr.getCaption() + "| Gesamt ";
} else {
totalCellHeaderPrefix += " || " + attr.getCaption() + ": " + attr.getCaption() + "| ";
}
}
totalCellHeaderPrefix += " || Kennzahl|";
return totalCellHeaderPrefix;
}
public List<Row> getTotalColumnResult(String sqlStatement, JdbcTemplate jt) {
if(sqlStatement.isEmpty()) {
return null;
}
List<Row> rows = null;
rows = jt.query(sqlStatement, new Object[0], new RowMapper<Row>() {
@Override
public Row mapRow(ResultSet rs, int rowNum) {
Row row = new Row();
Map<String, Object> cells = new TreeMap<String, Object>();
int numCols = reportMetadata.maxBridgeLvl;
try {
for (DimensionAttribute attr : reportMetadata.leftDimensionAttributes) {
if(attr.isHierarchy()) {
String prevCell = "";
for (int i = reportMetadata.minBridgeLvl; i < reportMetadata.maxBridgeLvl; i++) {
Object cell = rs.getObject("col" + i);
if(cell == null || cell.equals(prevCell)) {
continue;
}
String cellKey = attr.getStringId() + " (Ebene " + i + ")";
if(i == 0) {
cellKey = attr.getStringId();
}
row.rowKey += cellKey + cell;
prevCell = (String) cell;
}
} else {
Object val = rs.getObject(attr.getDimensionColumnAlias());
if(val != null) {
String id = attr.getAttrConformedId();
if(id == null) {
id = attr.getStringId();
}
cells.put(id, val);
row.rowKey += id + val;
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
for (Measure measure : reportMetadata.measures) {
try {
String key = getTotalCellHeaderPrefix(reportMetadata) + measure.getId().composedId;
Object val = rs.getObject("col" + numCols++);
cells.put(key, val);
} catch (SQLException e) {
e.printStackTrace();
}
}
row.cells = cells;
return row;
}
});
if(reportMetadata.getHierarchyAttributes().size() > 0) {
HashMap<String, Row> rowKeyValue = new HashMap<>();
for (Row row : rows) {
boolean replace = false;
if(rowKeyValue.containsKey(row.rowKey)) {
Row alreadyThere = rowKeyValue.get(row.rowKey);
for(String key : alreadyThere.cells.keySet()) {
Number candidateVal = (Number) row.cells.get(key);
if(candidateVal == null) {
continue;
}
Number alreadyVal = (Number) alreadyThere.cells.get(key);
if(alreadyVal == null) {
continue;
}
if(candidateVal.doubleValue() > alreadyVal.doubleValue()) {
replace = true;
}
}
if(replace) {
rowKeyValue.put(row.rowKey, row);
replace = false;
}
} else {
rowKeyValue.put(row.rowKey, row);
}
}
return new ArrayList<>(rowKeyValue.values());
}
return rows;
}
public static void setTotalColumnToRows(List<Row> rows, List<Row> result) {
for (Row row : rows) {
for (Row r : result) {
if(r.rowKey.equals(row.rowKey)) {
row.cells.putAll(r.cells);
}
}
}
//for (int i = 0; i < rows.size(); i++) {
// Row row = rows.get(i);
// if(row.aggregated == -1) {
// continue;
// }
// row.cells.putAll(result.get(i).cells);
//}
}
public static void setTotalColumnToColumns(List<Column> columns, ReportMetadata reportMetadata) {
for (Measure measure : reportMetadata.measures) {
String field = getTotalCellHeaderPrefix(reportMetadata) + measure.getId().composedId;
String header = getTotalCellHeaderPrefixHeader(reportMetadata) + measure.getCaption();
Column col = new Column(field, header, measure.getMeasureType(), false);
col.setHidden(true);
col.setTotalColumn(true);
columns.add(col);
}
}
private static Item findByLabel(List<Item> items, String label) {
return items.stream()
.filter(s -> s.label.equals(label))
.findAny()
.get();
}
}

158
src/de/superx/bianalysis/ResultMerger.java

@ -0,0 +1,158 @@
package de.superx.bianalysis;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.models.DimensionAttribute;
import de.superx.bianalysis.models.FactTable;
import de.superx.bianalysis.models.Filter;
import de.superx.bianalysis.models.InfoItem;
import de.superx.bianalysis.service.DbMetaAdapter;
import de.superx.jdbc.entity.Sachgebiet;
import de.superx.rest.model.Column;
import de.superx.rest.model.Result;
import de.superx.rest.model.Row;
public class ResultMerger {
private DbMetaAdapter dbAdapter;
public ResultMerger(DbMetaAdapter dbAdapter) {
this.dbAdapter = dbAdapter;
}
public Result buildMergedReport(ReportDefinition definition, List<Result> reportResults) {
Result result = new Result();
ReportMetadata metadata = new ReportMetadata(definition, null, dbAdapter);
List<ColumnElement> columnElements = ColumnElementBuilder.buildColumnElements(metadata);
List<Column> columns = ResultBuilder.buildColumns(metadata, columnElements);
if(!metadata.topDimensionAttributes.isEmpty()) {
ResultBuilder.setTotalColumnToColumns(columns, metadata);
}
// create list of merged rows
List<List<Row>> allRows = Result.getRowsFromReports(reportResults);
List<Row> rows = mergeRows(allRows);
if(metadata.hideEmptyColumns) {
ResultBuilder.removeEmptyColumns(columns, rows);
}
ResultBuilder.setAttributesToReport(result, metadata, rows, columns);
// override merge report specific attributes
result.setSubResults(reportResults);
List<InfoItem> factTablesInfo = getFactTablesAsInfo(dbAdapter, definition.factTableIds);
result.info.setSegmentCaption(factTablesInfo.stream().map(f -> f.caption).collect(Collectors.joining(", ")));
result.info.setSachgebiete(getSachgebieteAsInfo(dbAdapter, definition.factTableIds));
result.info.setFacttables(factTablesInfo);
for (Result r : reportResults) {
if(r.info.error != null && !r.info.error.isBlank()) {
result.info.setErrorMessage(r.info.error);
break;
}
}
return result;
}
private static List<String> getSachgebieteAsInfo(DbMetaAdapter dbAdapter, List<Identifier> factTableIds) {
List<String> sachgebiete = new ArrayList<String>();
List<Integer> tids = new ArrayList<>();
for (Identifier id : factTableIds) {
FactTable factTable = dbAdapter.getFactTable(id);
Sachgebiet sachgebiet = dbAdapter.getSachgebietById(factTable.getSachgebiettid());
Integer tid = sachgebiet.tid;
if(!tids.contains(tid)) {
tids.add(tid);
sachgebiete.add(sachgebiet.name.trim());
}
}
return sachgebiete;
}
private static List<InfoItem> getFactTablesAsInfo(DbMetaAdapter dbAdapter, List<Identifier> factTableIds) {
List<InfoItem> facttables = new ArrayList<InfoItem>();
for (Identifier id : factTableIds) {
FactTable factTable = dbAdapter.getFactTable(id);
facttables.add(new InfoItem(factTable.getId().composedId, factTable.getCaption(), factTable.getDescription()));
}
return facttables;
}
public ReportDefinition createFactTableSpecificReportDefinition(ReportDefinition reportDefinition,
Identifier factTableId) {
ReportDefinition definition = new ReportDefinition();
definition.hideEmptyColumns = reportDefinition.hideEmptyColumns;
definition.factTableIds.add(factTableId);
for (int i = 0; i < reportDefinition.leftDimensionAttributeIds.size(); i++) {
Identifier attr = reportDefinition.leftDimensionAttributeIds.get(i);
Identifier checkedAttr = dbAdapter.checkIfFactTableHasDimensionAttribute(attr, factTableId);
if(checkedAttr != null) {
definition.leftDimensionAttributeIds.add(checkedAttr);
}
}
for (int i = 0; i < reportDefinition.topDimensionAttributeIds.size(); i++) {
Identifier attr = reportDefinition.topDimensionAttributeIds.get(i);
Identifier checkedAttr = dbAdapter.checkIfFactTableHasDimensionAttribute(attr, factTableId);
if(checkedAttr != null) {
definition.topDimensionAttributeIds.add(checkedAttr);
}
}
for (int i = 0; i < reportDefinition.measureIds.size(); i++) {
Identifier measure = reportDefinition.measureIds.get(i);
if(dbAdapter.checkIfFactTableHasMeasure(measure, factTableId)) {
definition.measureIds.add(measure);
}
}
for (int i = 0; i < reportDefinition.filters.size(); i++) {
Filter filter = reportDefinition.filters.get(i);
Identifier checkedAttr = dbAdapter.checkIfFactTableHasDimensionAttribute(filter.dimensionAttributeId, factTableId);
if(checkedAttr != null) {
Filter roleFilter = new Filter(filter);
roleFilter.dimensionAttributeId = checkedAttr;
definition.filters.add(roleFilter);
}
}
return definition;
}
public static List<Row> mergeRows(List<List<Row>> rows) {
List<Row> result = new ArrayList<>();
for (List<Row> inputRows : rows) {
for (Row row : inputRows) {
Row rowRepl = new Row(row.aggregated);
rowRepl.rowKey = row.rowKey;
for(String key : row.cells.keySet()){
String newKey = key;
rowRepl.cells.put(newKey, row.cells.get(key));
}
if(!result.contains(rowRepl)) {
result.add(rowRepl);
} else {
// row with the same rowkey exists -> add only cells
Row found = result.get(result.indexOf(rowRepl));
for(String key : rowRepl.cells.keySet()){
if(!found.cells.containsKey(key)) {
found.cells.put(key, rowRepl.cells.get(key));
}
}
}
}
}
return result;
}
}

82
src/de/superx/bianalysis/StoredReport.java

@ -0,0 +1,82 @@
package de.superx.bianalysis;
import java.util.ArrayList;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.json.JsonMapper;
import de.superx.rest.model.Result;
import de.superx.rest.model.TreeNode;
@Table(value ="metadata\".\"rw_report_definitions")
public class StoredReport {
@Id
public int id;
public String name;
public String description;
public String definition;
@Column(value = "show_total_column")
@JsonProperty("show_total_column")
public int showTotalColumn;
@Transient
public Boolean isReadOnly = Boolean.FALSE;
@Transient
public ReportDefinition reportDefinition;
@Transient
public Result exportedResult;
@Transient
public ArrayList<TreeNode> hierarchy;
public StoredReport(String name, ReportDefinition reportDefinition, Result exportedResult) {
super();
this.name = name;
this.reportDefinition = reportDefinition;
this.exportedResult = exportedResult;
}
public StoredReport() {
super();
}
public static void setReportDefinitionJson(StoredReport report) {
ObjectWriter ow = new ObjectMapper().writer();
String reportDefinitionJson = null;
try {
reportDefinitionJson = ow.writeValueAsString(report.reportDefinition);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
report.definition = reportDefinitionJson;
}
public static void setReportDefinitionFromJson(StoredReport report) {
ObjectMapper mapper = JsonMapper.builder().findAndAddModules().build();
ReportDefinition reportDefinition = null;
try {
reportDefinition = mapper.readValue(report.definition, ReportDefinition.class);
} catch (Exception e) {
e.printStackTrace();
}
report.reportDefinition = reportDefinition;
report.definition = "";
}
}

302
src/de/superx/bianalysis/bin/BiAnalysisCLI.java

@ -0,0 +1,302 @@
package de.superx.bianalysis.bin;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Path;
import java.util.List;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.metadata.MetaImport;
import de.superx.bianalysis.metadata.MetaJson;
import de.superx.bianalysis.metadata.MetadataImporter;
import de.superx.bianalysis.metadata.models.json.MetaDimension;
import de.superx.bianalysis.metadata.models.json.MetaDimensionAttribute;
import de.superx.bianalysis.metadata.models.json.MetaFact;
import de.superx.bianalysis.metadata.models.json.MetaMeasure;
import de.superx.bianalysis.metadata.models.json.MetaObject;
import de.superx.bianalysis.metadata.models.yml.MetaYml;
import de.superx.servlet.SuperXManager;
import de.superx.util.PathAndFileUtils;
public class BiAnalysisCLI {
private static final String DEFAULT_RELEASE_BRANCH = "2025_12";
public static void main(String[] args) throws IOException {
Options options = createOptions();
CommandLine parsedArgs = readArgs(args, options);
if(parsedArgs.hasOption("-i")) {
addMissingIdsInMetadataDir(parsedArgs);
} else if(parsedArgs.hasOption("-m")) {
convertJsonFilesToSql();
} else if(parsedArgs.hasOption("-y")) {
generateYmlForJsonFile(parsedArgs);
} else if(parsedArgs.hasOption("-d")) {
generateWikiMarkdown(parsedArgs);
} else {
printHelp(options);
}
}
private static void generateWikiMarkdown(CommandLine parsedArgs) throws IOException {
SuperXManager.setWEB_INFPfad(PathAndFileUtils.getWebinfPath());
String facttable = parsedArgs.getOptionValue("d");
String filePath = PathAndFileUtils.getReportGeneratorDir("hisinone");
String ymlPath = PathAndFileUtils.getDbtTransformDirectory("hisinone") + File.separator + "docs_and_tests";
MetadataImporter importer = new MetadataImporter(ymlPath);
Logger.getLogger(MetadataImporter.class).setLevel(Level.ERROR);
importer.deserializeMetadataFromJsonFiles(filePath);
String docDirectory = PathAndFileUtils.getModulePath("biad");
docDirectory = String.join(File.separator, docDirectory, "conf", "his1", "edustore_doc");
for(MetaFact fact : importer.getAllFactTables()) {
if("all".equals(facttable) || fact.getFacttable().equals(facttable)) {
PrintWriter writer = new PrintWriter(docDirectory + File.separator + fact.getFacttable() + "_mediawiki.txt", "UTF-8");
writer.println("===Kennzahlen ===");
writer.println(";Kennzahlen " + fact.getCaption());
writer.println();
writer.println("{| class=\"wikitable\"\n ! Kennzahl !! Beschreibung");
writer.println("|-");
for(int i = 0; i < fact.getMeasures().size(); i++) {
MetaMeasure m = fact.getMeasures().get(i);
writer.println("| "+m.getCaption());
writer.println("| "+m.getDescription());
if(i != fact.getMeasures().size() - 1) {
writer.println("|-");
}
}
writer.println("|-\n|}");
writer.println();
writer.println();
writer.println("===Dimension ===");
writer.println(";"+fact.getCaption());
writer.println(":"+fact.getDescription());
writer.println();
writer.println("'''Dimension und Dimensionsattribut'''");
writer.println();
for(MetaDimension d : fact.getDimensions()) {
String dimCaption = d.getCaption();
if((dimCaption == null || dimCaption.isBlank()) && d.getConformedDimension() != null) {
dimCaption = d.getConformedDimension().getCaption();
}
String dimDescription = d.getDescription();
if((dimDescription == null || dimDescription.isBlank()) && d.getConformedDimension() != null) {
dimDescription = d.getConformedDimension().getDescription();
}
writer.println(";"+dimCaption);
writer.println(":"+dimDescription);
List<MetaDimensionAttribute> attributes = d.getAttributes();
if(attributes == null || attributes.size() == 0) {
attributes = d.getConformedDimension().getAttributes();
}
for(MetaDimensionAttribute a : attributes) {
String caption = a.getCaption() == null ? a.getConfDimAttrRef().getCaption() : a.getCaption();
writer.println("*"+caption);
try {
String desc = a.getDescription() == null ? a.getConfDimAttrRef().getDescription() : a.getDescription();
if(!desc.equals("null")) {
writer.println("*:"+desc);
}
} catch (Exception e) {
// TODO: handle exception
}
}
writer.println();
}
writer.close();
}
}
}
private static void generateYmlForJsonFile(CommandLine parsedArgs) {
String file = parsedArgs.getOptionValue("y");
if(file == null || !new File(file).exists()) {
throw new RuntimeException("File " + file +" is not valid.");
}
MetadataImporter importer = new MetadataImporter();
Logger.getLogger(MetadataImporter.class).setLevel(Level.ERROR);
importer.setShouldReadYMLDoc(false);
importer.deserializeMetadataFromJsonFiles(file);
MetaImport metaImport = importer.getMetaImports().get(0);
MetaYml yml = importer.createYMLFileForMetaJson(metaImport);
System.out.println(MetadataImporter.writeYmlToString(yml));
}
private static void addMissingIdsInMetadataDir(CommandLine parsedArgs) {
String[] files = parsedArgs.getOptionValues("i");
BasicConfigurator.configure(); // initializes console logging to stdout
try {
MetadataImporter metaImporter = new MetadataImporter();
metaImporter.setShouldReadYMLDoc(false);
metaImporter.deserializeMetadataFromJsonFiles(files);
for (MetaJson meta : metaImporter.getMetaJsons()) {
List<Identifier> allIds = meta.getIds();
boolean isFileUpdateNecessary = false;
for (MetaObject obj : meta.getMetaObjects()) {
if(obj.getId() == null) {
Identifier id = Identifier.getNewIdentifierValue(allIds, obj.getNamespace());
obj.setId(id);
allIds.add(id);
isFileUpdateNecessary = true;
}
if(obj.getDefaultRelease() == null) {
obj.setDefaultRelease(DEFAULT_RELEASE_BRANCH);
isFileUpdateNecessary = true;
}
}
if(isFileUpdateNecessary) {
writeMetaImportToFile(meta);
Logger.getRootLogger().info("Updated file " + meta.getFile().getPath());
}
}
if (!metaImporter.errorMessages.isEmpty()) {
System.out.println(metaImporter.getPrintableErrorMessages());
System.exit(1);
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
private static void convertJsonFilesToSql() {
SuperXManager.setWEB_INFPfad(PathAndFileUtils.getWebinfPath());
String filePath = PathAndFileUtils.getReportGeneratorDir("hisinone");
String ymlPath = PathAndFileUtils.getDbtTransformDirectory("hisinone");
String out =
"DROP TABLE IF EXISTS metadata.facttable; " +
"DROP TABLE IF EXISTS metadata.measure; " +
"DROP TABLE IF EXISTS metadata.measure_filter; " +
"DROP TABLE IF EXISTS metadata.dimension; " +
"DROP TABLE IF EXISTS metadata.dimension_attribute; ";
Path schemaSqlDir = Path.of("superx", "WEB-INF", "conf", "edustore", "db", "install", "schluesseltabellen");
out += readLinesWithNewline(new File(schemaSqlDir.toString() + File.separator + "biad_create_meta_tables.sql"));
out += readLinesWithNewline(new File(schemaSqlDir.toString() + File.separator + "biad_alter_meta_tables.sql"));
out += readLinesWithNewline(new File(schemaSqlDir.toString() + File.separator + "biad_metadaten_fuellen.sql"));
Logger.getLogger(MetadataImporter.class).setLevel(Level.ERROR);
MetadataImporter importer = new MetadataImporter(ymlPath);
importer.deserializeMetadataFromJsonFiles(filePath);
out += String.join("\n", importer.getAllUpsertStrings(false));
if(!importer.errorMessages.isEmpty()) {
System.out.println(importer.getPrintableErrorMessages());
System.exit(1);
} else {
System.out.println(out);
}
}
private static CommandLine readArgs(String[] args, Options options) {
CommandLineParser parser = new GnuParser();
try {
return parser.parse(options, args, false);
} catch (ParseException e) {
e.printStackTrace();
System.exit(1);
}
return null;
}
private static void printHelp(Options options) {
HelpFormatter help = new HelpFormatter();
help.setOptionComparator(null);
help.setWidth(200);
help.printHelp("This tool streamlines common tasks during development for the BIAnalysis.", options);
}
private static Options createOptions() {
Options options = new Options();
OptionBuilder.withDescription("convert metadata directory to sql");
OptionBuilder.withLongOpt("convert-metadata");
Option outMeta = OptionBuilder.create("m");
OptionBuilder.withDescription("generate yml documentation for json file");
OptionBuilder.withLongOpt("generate-yml");
OptionBuilder.withArgName("json-file");
OptionBuilder.hasArg(true);
Option generateYml = OptionBuilder.create("y");
OptionBuilder.withDescription("generate wiki documentation for measures and dimensions");
OptionBuilder.withLongOpt("generate-doc");
OptionBuilder.withArgName("facttable");
OptionBuilder.hasArg(true);
Option generateDoc = OptionBuilder.create("d");
OptionBuilder.withLongOpt("add-ids");
OptionBuilder.withDescription("add missing ids to json files");
OptionBuilder.withArgName("directories");
OptionBuilder.hasArgs();
Option updateIds = OptionBuilder.create("i");
options.addOption(updateIds);
options.addOption(generateYml);
options.addOption(generateDoc);
options.addOption(outMeta);
options.addOption(new Option("h", "help", false, "get help"));
return options;
}
public static void writeMetaImportToFile(MetaJson meta) {
ObjectMapper mapper = new ObjectMapper();
DefaultPrettyPrinter.Indenter indenter = new DefaultIndenter(" ", DefaultIndenter.SYS_LF);
DefaultPrettyPrinter printer = new DefaultPrettyPrinter();
printer.indentObjectsWith(indenter);
printer.indentArraysWith(indenter);
try {
mapper.writer(printer).writeValue(meta.getFile(), meta);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static String readLinesWithNewline(File file) {
String result = "";
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
result += line;
}
} catch (IOException e) {
e.printStackTrace();
}
return result+"\n";
}
}

74
src/de/superx/bianalysis/metadata/Identifier.java

@ -0,0 +1,74 @@
package de.superx.bianalysis.metadata;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@JsonSerialize(using = IdentifierSerializer.class)
public class Identifier {
private static final String ID_SEPARATOR = ":";
@JsonIgnore
public Integer value;
@JsonIgnore
public String namespace;
public String composedId;
public Identifier(String composedId) {
this.composedId = composedId;
String[] result = composedId.split(ID_SEPARATOR);
this.namespace = result[0];
this.value = Integer.valueOf(result[1]);
}
public Identifier(Identifier id) {
this.value = id.value;
this.namespace = id.namespace;
this.composedId = id.composedId;
}
@JsonIgnore
public static Identifier getNewIdentifierValue(List<Identifier> list, String namespace) {
List<Integer> values = list
.stream()
.filter(i->i.value!=null)
.map(i->i.value)
.collect(Collectors.toList());
Integer value;
if(values.isEmpty()) {
value = Integer.valueOf(1);
} else {
value = Integer.valueOf(Collections.max(values).intValue() + 1);
}
return new Identifier(namespace + ID_SEPARATOR + value);
}
@Override
@JsonIgnore
public boolean equals(Object obj) {
if(obj == null || !(obj instanceof Identifier)) {
return false;
}
Identifier id = (Identifier) obj;
return id.composedId.equals(this.composedId);
}
@Override
@JsonIgnore
public int hashCode() {
return this.value.hashCode() + this.namespace.hashCode();
}
@Override
public String toString() {
return composedId;
}
}

27
src/de/superx/bianalysis/metadata/IdentifierSerializer.java

@ -0,0 +1,27 @@
package de.superx.bianalysis.metadata;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
public class IdentifierSerializer extends StdSerializer<Identifier>{
public IdentifierSerializer() {
this(null);
}
public IdentifierSerializer(Class<Identifier> t) {
super(t);
}
@Override
public void serialize(
Identifier id, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeRawValue('"'+id.composedId+'"');
}
}

148
src/de/superx/bianalysis/metadata/MetaImport.java

@ -0,0 +1,148 @@
package de.superx.bianalysis.metadata;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.apache.log4j.Logger;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.superx.bianalysis.FaultyMetadataException;
import de.superx.bianalysis.metadata.models.json.MetaDimension;
import de.superx.bianalysis.metadata.models.json.MetaDimensionAttribute;
import de.superx.bianalysis.metadata.models.json.MetaFact;
import de.superx.bianalysis.metadata.models.json.MetaMeasure;
import de.superx.bianalysis.metadata.models.json.MetaMeasureFilter;
import de.superx.bianalysis.metadata.models.json.MetaObject;
public class MetaImport extends MetaJson {
public List<MetaFact> facts;
private static Logger log = Logger.getLogger(MetaImport.class);
@JsonIgnore
private Map<String, MetaDimensionAttribute> keysForMeasureFilter = new HashMap<>();
@JsonIgnore
public List<MetaDimension> conformedDimensions;
@JsonIgnore
public void setConformedDimensions(List<MetaDimension> conformedDimensions){
this.conformedDimensions = conformedDimensions;
if(this.conformedDimensions != null) {
for (MetaDimension dim : this.conformedDimensions) {
for (MetaDimensionAttribute attr : dim.getAttributes()) {
attr.setDimension(dim);
keysForMeasureFilter.put(dim.getDimension()+"."+attr.getDimColumn(), attr);
}
}
}
}
@JsonIgnore
@Override
public void init() {
this.allMetaObj = new ArrayList<MetaObject>();
for (MetaFact fact : this.facts) {
allMetaObj.add(fact);
for (MetaDimension dim : fact.getDimensions()) {
allMetaObj.add(dim);
if(dim.getRefTo() != null && !dim.getRefTo().isEmpty()) {
MetaDimension conformedDim = findByRef(dim);
dim.setConformedDimension(conformedDim);
}
for (MetaDimensionAttribute attr : dim.getAttributes()) {
allMetaObj.add(attr);
if(attr.getRefTo() != null && !attr.getRefTo().isEmpty()) {
attr.setConformedDimensionAttribute(findByRefAttr(dim.getConformedDimension().getDimension(), attr));
}
keysForMeasureFilter.put(dim.getDimension()+"."+attr.getDimColumn(), attr);
}
}
if(fact.getMeasures() != null) {
for (MetaMeasure measure : fact.getMeasures()) {
allMetaObj.add(measure);
MetaMeasureFilter filter = measure.getFilter();
if(filter != null) {
if(filter.getDimensionRef() != null && !filter.getDimensionRef().isBlank()) {
MetaDimensionAttribute attr = keysForMeasureFilter.get(filter.getDimensionRef());
if(attr == null) {
throw new FaultyMetadataException("Could not resolve dimensionRef '" + filter.getDimensionRef() +
"' (" + file.getName() + " -> " + fact.getFacttable() + ")");
}
filter.setAttribute(attr);
allMetaObj.add(filter);
} else if(filter.getFactColumnRef() != null && !filter.getFactColumnRef().isBlank()) {
allMetaObj.add(filter);
}
}
}
}
}
}
private MetaDimensionAttribute findByRefAttr(String dimensionTable, MetaDimensionAttribute attribute) {
String attributeColumn = attribute.getRefTo();
MetaDimensionAttribute confAttr = null;
for (MetaDimension confDim : this.conformedDimensions) {
if(!confDim.getDimension().equals(dimensionTable)) {
continue;
}
for (MetaDimensionAttribute attr : confDim.getAttributes()) {
if(attr.getDimColumn().equals(attributeColumn)) {
confAttr = attr;
break;
}
}
}
if(confAttr == null) {
throw new FaultyMetadataException(
"Could not resolve attribute reference '" + attributeColumn + "' ("
+ file.getName() + " -> "
+ attribute.getDimension().getFact().getFacttable() + " -> "
+ attribute.getDimension().getRefTo() + ")"
);
}
return confAttr;
}
@JsonIgnore
private MetaDimension findByRef(MetaDimension dim) {
String refTo = dim.getRefTo();
MetaDimension resolvedRefTo = null;
for (MetaDimension dimConf : this.conformedDimensions) {
if (dimConf.getDimension() == null) {
log.error("Missing dimension attribute for " + dimConf.getCaption());
continue;
}
if (dimConf.getDimension().equals(refTo)) {
resolvedRefTo = dimConf;
break;
}
}
if (resolvedRefTo == null) {
throw new FaultyMetadataException("Could not resolve dimension reference '" + refTo + "' (" + file.getName() + " -> " + dim.getFact().getFacttable() + ")");
}
return resolvedRefTo;
}
@JsonIgnore
public List<MetaDimension> getDimensionsWithoutRefTo() {
List<MetaDimension> dims = new ArrayList<>();
for (MetaFact fact : facts) {
for (MetaDimension dim : fact.getDimensions()) {
if(dim.getRefTo() == null) {
dims.add(dim);
}
}
}
return dims;
}
}

38
src/de/superx/bianalysis/metadata/MetaImportConformedDimensions.java

@ -0,0 +1,38 @@
package de.superx.bianalysis.metadata;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.superx.bianalysis.metadata.models.json.MetaDimension;
import de.superx.bianalysis.metadata.models.json.MetaDimensionAttribute;
import de.superx.bianalysis.metadata.models.json.MetaMeasure;
import de.superx.bianalysis.metadata.models.json.MetaObject;
public class MetaImportConformedDimensions extends MetaJson {
@JsonProperty("conformed_dimensions")
public List<MetaDimension> conformedDimensions;
@Override
public void init() {
this.allMetaObj = new ArrayList<MetaObject>();
for (MetaDimension metaDimension : this.conformedDimensions) {
metaDimension.setConformed(true);
this.allMetaObj.add(metaDimension);
for (MetaDimensionAttribute attr : metaDimension.getAttributes()) {
attr.setDimension(metaDimension);
this.allMetaObj.add(attr);
}
}
for (MetaObject metaObject : allMetaObj) {
metaObject.setNamespace(this.namespace);
if(metaObject.getId() != null) {
metaObject.getId().namespace = this.namespace;
}
}
}
}

58
src/de/superx/bianalysis/metadata/MetaJson.java

@ -0,0 +1,58 @@
package de.superx.bianalysis.metadata;
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.superx.bianalysis.metadata.models.json.MetaObject;
public abstract class MetaJson {
public String namespace;
@JsonIgnore
protected File file;
@JsonIgnore
protected List<MetaObject> allMetaObj;
@JsonIgnore
public abstract void init();
@JsonIgnore
public File getFile() {
return this.file;
}
@JsonIgnore
public List<MetaObject> getMetaObjects() {
return this.allMetaObj;
}
@JsonIgnore
public void setFile(File file) {
this.file = file;
}
@JsonIgnore
public List<Identifier> getIds() {
return this.getMetaObjects()
.stream()
.map(o -> o.getId())
.filter(i -> i != null && i.composedId != null)
.collect(Collectors.toList());
}
@JsonIgnore
public void setNamespaceToMetaObjects() {
for (MetaObject metaObject : allMetaObj) {
metaObject.setNamespace(this.namespace);
if(metaObject.getId() != null) {
metaObject.getId().namespace = this.namespace;
}
}
}
}

593
src/de/superx/bianalysis/metadata/MetadataImporter.java

@ -0,0 +1,593 @@
package de.superx.bianalysis.metadata;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.JdbcTemplate;
import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import de.superx.bianalysis.StoredReport;
import de.superx.bianalysis.metadata.models.json.MetaDimension;
import de.superx.bianalysis.metadata.models.json.MetaDimensionAttribute;
import de.superx.bianalysis.metadata.models.json.MetaFact;
import de.superx.bianalysis.metadata.models.json.MetaObject;
import de.superx.bianalysis.metadata.models.yml.MetaYml;
import de.superx.bianalysis.metadata.models.yml.MetaYmlModel;
import de.superx.bianalysis.metadata.models.yml.MetaYmlModelColumns;
import de.superx.util.PathAndFileUtils;
/**
* Provides functionality for updating the tables in the metadata schema.
* The tables are updated by reading the metadata information from various
* metaimport.json files and transforming that information into executable sql.
*
* The BIAnalysis Tool uses the tables to read information about the different
* meta objects and more importantly to figure out their relationships, e.g. what
* dimension is part of which facttable or which attribute belongs to which
* dimension.
*
* To learn more about the metadata concept for the BIAnalysis Tool see:
* doc\bi_analysis\report_wizard\metadaten.adoc
*
*/
public final class MetadataImporter {
/**
* Each file containing metadata information must have the following file suffix.
*/
private static final String METAIMPORT_FILE_SUFFIX = "_metaimport.json";
protected static final String CONFORMED_DIMENSIONS_FILE_SUFFIX = "conformed_dimensions" + METAIMPORT_FILE_SUFFIX;
/**
* Holds all Metaimport objects with which this instance was initalized.
* (One MetaImport object corresponds to exactly one deserialized json file)
*/
private List<MetaJson> metaImports = new ArrayList<>();
public List<String> errorMessages = new ArrayList<>();
/**
* SQL String for deleting from all metadata tables except 'custom' releases.
*/
public static final String TRUNCATE_METADATA_SQL =
"DELETE FROM metadata.facttable WHERE default_release != 'custom' or default_release is null; " +
"DELETE FROM metadata.measure WHERE default_release != 'custom' or default_release is null; " +
"DELETE FROM metadata.measure_filter WHERE default_release != 'custom' or default_release is null; " +
"DELETE FROM metadata.dimension WHERE default_release != 'custom' or default_release is null; " +
"DELETE FROM metadata.dimension_attribute WHERE default_release != 'custom' or default_release is null; ";
private static Logger log = Logger.getLogger(MetadataImporter.class);
private boolean shouldReadYMLDoc = true;
private String ymlDir = "";
public MetadataImporter() {}
public MetadataImporter(String ymlDir) {this.ymlDir = ymlDir;}
/**
* Calling this method initalizes the MetadataImporter by deserializing all unique meta objects
* from the provided json files. Faulty json files are ignored.
*
* @param paths Path(s) to the metadata file(s). A path can point to a directory or a file.
* Multiple paths and/or directories can be provided.
*/
public void deserializeMetadataFromJsonFiles(String... paths) {
ObjectMapper mapper = JsonMapper.builder().findAndAddModules().build();
List<MetaImportConformedDimensions> conformedDimension = new ArrayList<>();
List<MetaDimension> conformedDims = new ArrayList<>();
for (String path : paths) {
List<File> metaFiles = readMetaImportFiles(path);
for (File file : metaFiles) {
MetaJson meta = null;
try{
if(file.getName().endsWith(CONFORMED_DIMENSIONS_FILE_SUFFIX)) {
meta = mapper.readValue(file, MetaImportConformedDimensions.class);
conformedDimension.add((MetaImportConformedDimensions) meta);
} else {
meta = mapper.readValue(file, MetaImport.class);
conformedDims.addAll(((MetaImport) meta).getDimensionsWithoutRefTo());
}
} catch(JsonMappingException e) {
String message = "Could not deserialize metadata from file: " + file.getName() + "\n";
message += e.getMessage();
errorMessages.add(message);
} catch(Exception e) {
errorMessages.add(ExceptionUtils.getFullStackTrace(e));
}
if(meta != null) {
log.info("Read metadata from file: " + file.getName());
meta.setFile(file);
metaImports.add(meta);
}
}
}
// gather all conformed dimensions
List<MetaDimension> confDims = new ArrayList<>();
confDims.addAll(conformedDims);
for (MetaImportConformedDimensions conf : conformedDimension) {
confDims.addAll(conf.conformedDimensions);
}
// resolve conformed references ('ref_to' attributes)
for (MetaJson metaJson : metaImports) {
if (conformedDimension.size() > 0 && metaJson instanceof MetaImport) {
((MetaImport) metaJson).setConformedDimensions(confDims);
}
try {
metaJson.init();
metaJson.setNamespaceToMetaObjects();
} catch (Exception e) {
errorMessages.add(ExceptionUtils.getFullStackTrace(e));
}
}
if(shouldReadYMLDoc) {
addDescriptionsFromYMLFiles();
}
}
public List<String> readStoredReports() {
List<String> result = new ArrayList<>();
try {
String dir = PathAndFileUtils.getStoredReportDir("hisinone");
File[] files = new File(dir).listFiles();
if(files == null) {
return result;
}
for (File file : files) {
try {
ObjectMapper mapper = JsonMapper.builder().findAndAddModules().build();
StoredReport report = mapper.readValue(file, StoredReport.class);
UpsertStringBuilder builder = new UpsertStringBuilder()
.forTable("metadata", "rw_report_definitions")
.withIntCol("id", Integer.valueOf(report.id))
.withStringCol("name", report.name)
.withStringCol("definition", report.definition)
.withIntCol("show_total_column", Integer.valueOf(report.showTotalColumn));
result.add(builder.build(true));
} catch (JsonMappingException e) {
String message = "Could not deserialize stored report from file: " + file.getName() + "\n";
message += e.getMessage();
errorMessages.add(message);
}
}
// After inserting the stored reports with a fixed id we need to re-sync the
// id column of the rw_report_definitions table
if(result.size() != 0) {
result.add("SELECT setval(pg_get_serial_sequence('metadata.rw_report_definitions', 'id'),"
+ "(SELECT max(id) FROM metadata.rw_report_definitions ));");
}
} catch(Exception e) {
errorMessages.add("Unable to read stored report:\n");
errorMessages.add(ExceptionUtils.getFullStackTrace(e));
}
return result;
}
public void addDescriptionsFromYMLFiles() {
String dir = ymlDir;
if(ymlDir == null || ymlDir.isBlank()) {
dir = PathAndFileUtils.getDbtTransformDirectory("hisinone");
}
HashMap<String, String> map = getMarkdownDefinitions(dir);
addYMLDescriptionsToMetaObjects(dir, map);
}
public void addYMLDescriptionsToMetaObjects(String ymlDir, HashMap<String, String> mdDefs){
log.info("Adding descriptions from yml files");
HashMap<String, String> descriptions = createDescriptions(new File(ymlDir), mdDefs);
List<MetaObject> objs = getAllMetaObjectsWithConformed();
for (MetaObject metaObj : objs ) {
String docIdentifier = metaObj.getDocIdentifier();
if(docIdentifier == null || docIdentifier.isBlank()) {
continue;
}
// only use yml doc if json description does not exist
if(metaObj.getDescription() == null || metaObj.getDescription().isBlank()) {
String desc = descriptions.get(docIdentifier);
if(desc == null) {
log.warn("Missing yml description for: " + docIdentifier);
} else {
metaObj.setDescription(desc);
if(desc.isBlank()) {
log.warn("Empty yml description for MetaObject: " + docIdentifier);
}
}
}
}
}
public MetaYml createYMLFileForMetaJson(MetaJson metaJson) {
MetaYml newYml = new MetaYml();
List<MetaYmlModel> newYmlModels = new ArrayList<>();
newYml.setVersion(1);
newYml.setModels(newYmlModels);
if(metaJson instanceof MetaImport) {
MetaImport metaimport = (MetaImport) metaJson;
for (MetaFact fact : metaimport.facts) {
MetaYmlModel factModel = new MetaYmlModel(fact.getFacttable(), " ");
newYmlModels.add(factModel);
List<MetaYmlModelColumns> factCols = new ArrayList<>();
for(MetaDimension dim : fact.getDimensions()) {
if(dim.getRefTo() == null) {
factCols.add(new MetaYmlModelColumns(dim.getFactColumn(), " ", "not_null"));
MetaYmlModel dimModel = new MetaYmlModel(dim.getDimension(), " ");
newYmlModels.add(dimModel);
List<MetaYmlModelColumns> dimCols = new ArrayList<>();
for(MetaDimensionAttribute attr : dim.getAttributes()) {
dimCols.add(new MetaYmlModelColumns(attr.getDimColumn(), " ", "not_null"));
}
dimModel.setColumns(dimCols);
}
}
factModel.setColumns(factCols);
}
} else {
MetaImportConformedDimensions metaimport = (MetaImportConformedDimensions) metaJson;
for(MetaDimension dim : metaimport.conformedDimensions) {
MetaYmlModel dimModel = new MetaYmlModel(dim.getDimension(), " ");
newYmlModels.add(dimModel);
List<MetaYmlModelColumns> dimCols = new ArrayList<>();
for(MetaDimensionAttribute attr : dim.getAttributes()) {
dimCols.add(new MetaYmlModelColumns(attr.getDimColumn(), " ", "not_null"));
}
dimModel.setColumns(dimCols);
}
}
return newYml;
}
private HashMap<String, String> createDescriptions(File startDir, HashMap<String, String> mdDefs){
HashMap<String, String> result = new HashMap<>();
for (MetaYml yml : getDescriptionYMLs(startDir)) {
for (MetaYmlModel model : yml.getModels()) {
String modelName = model.getName();
String modelDesc = model.getDescription();
result.put(modelName, getDescription(modelDesc, mdDefs));
for (MetaYmlModelColumns column : model.getColumns()) {
String colName = column.getName();
String colDesc = column.getDescription();
result.put(modelName + "." + colName, getDescription(colDesc, mdDefs));
}
}
}
return result;
}
private static String getDescription(String desc, HashMap<String, String> mdDefs) {
if(desc == null) {
return "";
}
if(desc.startsWith("{{")) {
String[] parts = desc.split("\"");
String docRef = parts[1];
return mdDefs.get(docRef);
}
return desc;
}
private List<MetaYml> getDescriptionYMLs(File startDir){
List<MetaYml> ymls = new ArrayList<>();
List<String> files = getFiles(startDir, "", ".yml");
ObjectMapper mapperYml = new ObjectMapper(new YAMLFactory());
for (String f : files) {
File file = new File(startDir + File.separator + f);
MetaYml doc = null;
try {
doc = mapperYml.readValue(file, MetaYml.class);
} catch (Exception e) {
String message = "Could not read documentation from file: " + file.getName() + "\n";
errorMessages.add(message);
errorMessages.add(ExceptionUtils.getFullStackTrace(e));
}
if(doc != null) {
log.info("Read documentation from file: " + file.getName());
ymls.add(doc);
}
}
return ymls;
}
/**
* Gathers all metadata json files.
*
* @param path A path to a metadata json file or a directory containing metadata json files.
* @return A list of files matching the metadata json suffix.
*/
private static List<File> readMetaImportFiles(String path) {
File metaimportPath = new File(PathAndFileUtils.getDbtJsonPath(path));
List<File> metaimportFiles = new ArrayList<>();
if (metaimportPath.isDirectory()) {
metaimportPath.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if (name.endsWith(METAIMPORT_FILE_SUFFIX)) {
File file = new File(dir.getAbsolutePath() + File.separator + name);
metaimportFiles.add(file);
return true;
}
return false;
}
});
} else {
metaimportFiles.add(metaimportPath);
}
return metaimportFiles;
}
private static List<String> getFiles(File startDir, String subDir, String extension) {
List<String> filtered = new ArrayList<String>();
for (File file : startDir.listFiles()) {
String name = file.getName();
if(file.isDirectory()) {
filtered.addAll(getFiles(file, subDir + File.separator + name, extension));
}
String filename = name.strip().toLowerCase();
if(filename.endsWith(extension)) {
filtered.add(subDir + File.separator + name);
}
}
return filtered;
}
/*
/**
* Generates the sql upsert strings for all unique, deserialized MetaObjects.
*
* @param hasOnConflictConstruct If set to true generates upsert strings with the postgres-specific "ON CONFLICT" clause.
* @return All the generated upserts from the metadata files.
*/
public List<String> getAllUpsertStrings(boolean hasOnConflictConstruct) {
List<String> upsertStmts = new ArrayList<>();
List<Identifier> ids = new ArrayList<>();
for (MetaJson meta : metaImports) {
for(MetaObject obj: meta.getMetaObjects()) {
Identifier id = obj.getId();
if(id == null) {
String message = String.format("Missing ID for Element '%s' in file: %s.", obj.getCaption(), meta.getFile().getAbsolutePath());
errorMessages.add(message);
continue;
}
if(ids.contains(id)) {
String message = String.format("Duplicate ID '%s'. Ignoring Element '%s'.", obj.getCaption(), obj.getId().composedId);
errorMessages.add(message);
continue;
}
ids.add(obj.getId());
String stmt = obj.getUpsertBuilder().build(hasOnConflictConstruct);
upsertStmts.add(stmt);
}
}
return upsertStmts;
}
public void updateMetadataForH2Database(DataSource dataSource) throws Exception {
String metaFilesDir = String.join(File.separator, new String[] {"test", "resources", "db", "fixtures", "reportwizard", "metadata"});
deserializeMetadataFromJsonFiles(metaFilesDir);
JdbcTemplate jt = new JdbcTemplate(dataSource);
String upserts = String.join("\n", getAllUpsertStrings(false).toString());
jt.execute(upserts);
}
/**
* Updates tables in the metadata schema.
*
* @param metaPath Location of the metadata file or directory.
* @param dataSource The datasource on which the sql is executed.
* @throws Exception
*/
public void updateMetadataSchema(String project, DataSource dataSource) throws Exception {
String metaFilesDir = PathAndFileUtils.getReportGeneratorDir(project);
deserializeMetadataFromJsonFiles(metaFilesDir);
try (Connection con = dataSource.getConnection()) {
try (Statement st = con.createStatement()) {
log.info("Update Metadata for BIAnalysis.");
st.execute(TRUNCATE_METADATA_SQL);
List<String> upserts = getAllUpsertStrings(true);
upserts.addAll(readStoredReports());
for (String sql : upserts) {
log.info(sql);
try (Statement stUpsert = con.createStatement()) {
stUpsert.execute(sql);
} catch (Exception e) {
throw e;
}
}
}
// execute sql in "attributes_sql" in metadata files to build the attributes
// dynamically
for (MetaJson i : this.metaImports) {
for (MetaObject obj : i.getMetaObjects()) {
if (!(obj instanceof MetaDimension)) continue;
MetaDimension dim = (MetaDimension) obj;
if (dim.getAttributesSql() == null) continue;
String sqlDone = "";
String sql = "select param_val from unload_params where param_id = '" + dim.getAttributesSql() + "';";
try (Statement stAttr = con.createStatement(); ResultSet rs = stAttr.executeQuery(sql)) {
if(rs.next()) {
sqlDone = rs.getString("param_val");
}
}
try (Statement stAttr = con.createStatement(); ResultSet rs = stAttr.executeQuery(sqlDone)) {
int numAttributes = 0;
while (rs.next()) {
MetaDimensionAttribute attribute = new MetaDimensionAttribute();
attribute.setDimension(dim);
attribute.setCaption(rs.getString("caption"));
attribute.setDimColumn(rs.getString("dim_column"));
// create a new 'on the fly' identifier for the new metadata
// attribute
Identifier id = Identifier.getNewIdentifierValue(i.getIds(), dim.getNamespace());
Integer val = Integer.valueOf(id.value.intValue() + numAttributes);
attribute.setId(new Identifier(dim.getNamespace() + ":" +val));
numAttributes++;
String stmt = attribute.getUpsertBuilder().build(true);
try (Statement stUpsert = con.createStatement()) {
stUpsert.execute(stmt);
}
}
}
}
}
}
}
public static String writeYmlToString(MetaYml yml) {
YAMLFactory yf = new YAMLFactory()
.enable(YAMLGenerator.Feature.MINIMIZE_QUOTES)
.disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER);
ObjectMapper mapper = new ObjectMapper(yf);
DefaultPrettyPrinter.Indenter indenter = new DefaultIndenter(" ", DefaultIndenter.SYS_LF);
DefaultPrettyPrinter printer = new DefaultPrettyPrinter();
printer.indentObjectsWith(indenter);
printer.indentArraysWith(indenter);
try {
//mapper.writer(printer).writeValue(file, yml);
return mapper.writer(printer).writeValueAsString(yml);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public String getPrintableErrorMessages() {
String output = "";
if(!errorMessages.isEmpty()) {
output += "The following errors occured:\n";
for (String message : errorMessages) {
output += message + "\n";
}
}
return output;
}
public HashMap<String, String> getMarkdownDefinitions(String ymlDir) {
List<String> files = getFiles(new File(ymlDir), "", ".md");
HashMap<String, String> map = new HashMap<>();
for (String file : files) {
try {
try (BufferedReader br = new BufferedReader(new FileReader(ymlDir + File.separator + file))) {
String line;
String key = null;
boolean readHeading = false;
while ((line = br.readLine()) != null) {
if (line.startsWith("{% docs ")) {
key = line.split(" ")[2];
map.put(key, "");
} else if(key != null && line.startsWith("# ")) {
readHeading = true;
} else {
if(readHeading && !line.isBlank()) {
map.put(key, line);
key = null;
readHeading = false;
}
}
}
}
} catch (Exception e) {
String message = "ERROR getting markdown definitions from file: " + file + "\n";
errorMessages.add(message);
errorMessages.add(ExceptionUtils.getFullStackTrace(e));
}
}
return map;
}
public Optional<MetaImport> getMetaImport(String fileName) {
return metaImports.stream()
.filter(json -> (json instanceof MetaImport) && json.file.getName().equals(fileName))
.map(json -> (MetaImport) json)
.findFirst();
}
public Optional<MetaJson> getMetaJson(String fileName) {
return metaImports.stream()
.filter(json -> json.file.getName().equals(fileName))
.findFirst();
}
public List<MetaImport> getMetaImports() {
return metaImports.stream()
.filter(json -> (json instanceof MetaImport))
.map(json -> (MetaImport) json)
.collect(Collectors.toList());
}
public List<MetaJson> getMetaJsons() {
return metaImports.stream().collect(Collectors.toList());
}
public List<MetaObject> getAllMetaObjects(){
return metaImports.stream()
.filter(json -> (json instanceof MetaImport))
.map(meta -> ((MetaImport) meta).getMetaObjects())
.flatMap(List::stream)
.collect(Collectors.toList());
}
public List<MetaObject> getAllMetaObjectsWithConformed(){
return metaImports.stream()
.map(meta -> meta.getMetaObjects())
.flatMap(List::stream)
.collect(Collectors.toList());
}
public List<MetaFact> getAllFactTables(){
return metaImports.stream()
.filter(json -> (json instanceof MetaImport))
.map(meta -> ((MetaImport) meta).facts)
.flatMap(List::stream)
.collect(Collectors.toList());
}
public void setShouldReadYMLDoc(boolean shouldReadYMLDoc) {
this.shouldReadYMLDoc = shouldReadYMLDoc;
}
}

99
src/de/superx/bianalysis/metadata/UpsertStringBuilder.java

@ -0,0 +1,99 @@
package de.superx.bianalysis.metadata;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
public class UpsertStringBuilder {
private StringJoiner values;
private StringJoiner columns;
private StringJoiner onConflict;
private String schema;
private String tablename;
private List<UpsertStringBuilder> builders = new ArrayList<>();
public UpsertStringBuilder() {
values = new StringJoiner(", ");
columns = new StringJoiner(", ");
onConflict = new StringJoiner(", ");
}
public void addUpsertStringBuilder(UpsertStringBuilder builder) {
this.builders.add(builder);
}
public UpsertStringBuilder forTable(String schema, String tablename) {
this.tablename = tablename;
this.schema = schema;
return this;
}
public UpsertStringBuilder withStringCol(String colName, String value) {
appendToSelection(colName);
if(value == null) {
values.add("null");
} else {
values.add("'"+value+"'");
}
return this;
}
public UpsertStringBuilder withStringCol(String colName, Object value) {
if(value != null) {
return this.withStringCol(colName, value.toString());
}
return this.withStringCol(colName, "unknown");
}
public UpsertStringBuilder withStringCol(String colName, String value, String defaultVal) {
if(value != null) {
return this.withStringCol(colName, value);
}
return this.withStringCol(colName, defaultVal);
}
public UpsertStringBuilder withStringCol(String colName, Object value, Object defaultVal) {
if(value != null) {
return this.withStringCol(colName, value);
}
return this.withStringCol(colName, defaultVal);
}
public UpsertStringBuilder withIntCol(String colName, Integer value) {
appendToSelection(colName);
values.add(String.valueOf(value));
return this;
}
public UpsertStringBuilder withIdCol(String colName, Identifier id) {
if(id != null) {
return this.withStringCol(colName, id.composedId);
}
return this.withStringCol(colName, null);
}
private void appendToSelection(String colName) {
onConflict.add(String.format("%s = EXCLUDED.%s", colName, colName));
columns.add(colName);
}
public String build(boolean hasOnConflictConstruct) {
String result = "INSERT INTO %s.%s(%s) VALUES(%s)";
result = String.format(result, this.schema, this.tablename, this.columns, this.values);
if(hasOnConflictConstruct) {
// TODO: log message for on id conflict
//result += " ON CONFLICT(id) DO UPDATE SET " + this.onConflict;
result += " ON CONFLICT(id) DO NOTHING";
}
result += ";\n";
if(this.builders.size() > 0) {
for (UpsertStringBuilder upsertStringBuilder : builders) {
result += upsertStringBuilder.build(hasOnConflictConstruct);
}
}
return result;
}
}

269
src/de/superx/bianalysis/metadata/models/json/MetaDimension.java

@ -0,0 +1,269 @@
package de.superx.bianalysis.metadata.models.json;
import java.util.ArrayList;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.metadata.UpsertStringBuilder;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonInclude(Include.NON_DEFAULT)
@JsonPropertyOrder({ "id", "default_release", "ref_to", "caption", "dimension", "fact_column", "alias", "bridge", "attributes"})
public class MetaDimension extends MetaObject {
@JsonProperty("ref_to")
private String refTo;
private String dimension;
@JsonProperty("fact_column")
private String factColumn;
private String alias;
private String view;
@JsonProperty("id_column")
private String idColumn;
private List<MetaDimensionAttribute> attributes;
@JsonProperty("is_hierarchy")
private boolean isHierarchy;
@JsonProperty("is_historical")
private boolean isHistorical;
@JsonProperty("attributes_sql")
private String attributesSql;
@JsonIgnore
private MetaFact fact;
// true if dimension is from the conformed_dimensions_metaimport.json
@JsonIgnore
private boolean isConformed = false;
// isConformed must be false
// the correpsonding dimension from the conformed_dimensions_metaimport.json
// referenced by 'ref_to'
@JsonIgnore
private MetaDimension conformedDimension;
public MetaDimension() {
super("dimension");
}
public void setConformedDimension(MetaDimension dimension) {
this.conformedDimension = dimension;
}
@Override
public UpsertStringBuilder getUpsertBuilder() {
Identifier factId = (isConformed) ? null : this.fact.id;
UpsertStringBuilder builder = new UpsertStringBuilder();
if(conformedDimension == null) {
builder = super.getUpsert()
.withIdCol("facttable_id", factId)
.withStringCol("joincolumn", this.factColumn)
.withStringCol("alias", this.alias)
.withStringCol("is_hierarchy", String.valueOf(this.isHierarchy))
.withStringCol("is_historical", String.valueOf(this.isHistorical))
//.withStringCol("attributes_sql", this.attributesSql)
.withStringCol("tablename", this.dimension)
.withStringCol("id_column", this.idColumn);
} else {
builder = new UpsertStringBuilder()
.forTable("metadata", this.sourceTable)
.withStringCol("namespace", this.namespace)
.withIdCol("id", this.id)
.withIntCol("default_release", Integer.valueOf(1));
builder = builder.withIdCol("facttable_id", factId);
if(this.idColumn != null && !this.idColumn.isBlank()) {
builder = builder.withStringCol("id_column", idColumn);
} else {
builder = builder.withStringCol("id_column", this.conformedDimension.getIdColumn());
}
if(this.caption != null && !this.caption.isBlank()) {
builder = builder.withStringCol("caption", caption);
} else {
builder = builder.withStringCol("caption", this.conformedDimension.getCaption());
}
if(this.factColumn != null && !this.factColumn.isBlank()) {
builder = builder.withStringCol("joincolumn", this.factColumn);
} else {
builder = builder.withStringCol("joincolumn", this.conformedDimension.getFactColumn());
}
if(this.alias != null && !this.factColumn.isBlank()) {
builder = builder.withStringCol("alias", this.alias);
} else {
builder = builder.withStringCol("alias", this.conformedDimension.getAlias());
}
if(this.isHierarchy) {
builder = builder.withStringCol("is_hierarchy", String.valueOf(isHierarchy));
} else {
builder = builder.withStringCol("is_hierarchy", String.valueOf(conformedDimension.isHierarchy));
}
if(this.isHistorical) {
builder = builder.withStringCol("is_historical", String.valueOf(isHistorical));
} else {
builder = builder.withStringCol("is_historical", String.valueOf(conformedDimension.isHistorical));
}
if(this.conformedDimension.getDimension() != null && !this.conformedDimension.getDimension().isBlank()) {
if(view != null && !view.isBlank()) {
builder = builder.withStringCol("tablename", this.view);
} else {
builder = builder.withStringCol("tablename", this.conformedDimension.getDimension());
}
} else {
builder = builder.withStringCol("tablename", this.dimension);
}
builder = builder.withIdCol("conformed", this.conformedDimension.id);
}
if(this.description != null && !this.description.isBlank()) {
builder = builder.withStringCol("description", this.description);
} else {
if(conformedDimension != null) {
builder = builder.withStringCol("description", conformedDimension.getDescription());
} else {
builder = builder.withStringCol("description", "");
}
}
return builder;
}
public String getRefTo() {
return refTo;
}
public void setRefTo(String refTo) {
this.refTo = refTo;
}
public String getDimension() {
return dimension;
}
public void setDimension(String dimension) {
this.dimension = dimension;
}
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
public List<MetaDimensionAttribute> getAttributes() {
if(this.attributes == null) {
return new ArrayList<>();
}
return attributes;
}
public void setAttributes(List<MetaDimensionAttribute> attributes) {
for (MetaDimensionAttribute metaDimensionAttribute : attributes) {
metaDimensionAttribute.setDimension(this);
}
this.attributes = attributes;
}
public MetaFact getFact() {
return fact;
}
public void setFact(MetaFact fact) {
this.fact = fact;
}
@JsonIgnore
public boolean isConformed() {
return isConformed;
}
@JsonIgnore
public void setConformed(boolean isConformed) {
this.isConformed = isConformed;
}
public MetaDimension getConformedDimension() {
return conformedDimension;
}
public String getFactColumn() {
return factColumn;
}
public void setFactColumn(String factColumn) {
this.factColumn = factColumn;
}
public void addAttribute(MetaDimensionAttribute metaDimensionAttribute) {
if(this.attributes == null) {
this.attributes = new ArrayList<>();
}
this.attributes.add(metaDimensionAttribute);
}
@Override
@JsonIgnore
public String getDocIdentifier() {
if(this.conformedDimension != null) {
return conformedDimension.getDocIdentifier();
}
return this.dimension;
}
public boolean isHierarchy() {
return isHierarchy;
}
public void setHierarchy(boolean isHierarchy) {
this.isHierarchy = isHierarchy;
}
public boolean isHistorical() {
return isHistorical;
}
public void setHistorical(boolean isHistorical) {
this.isHistorical = isHistorical;
}
public String getView() {
return view;
}
public void setView(String view) {
this.view = view;
}
public String getIdColumn() {
return idColumn;
}
public void setIdColumn(String idColumn) {
this.idColumn = idColumn;
}
public String getAttributesSql() {
return attributesSql;
}
public void setAttributesSql(String attributesSql) {
this.attributesSql = attributesSql;
}
}

179
src/de/superx/bianalysis/metadata/models/json/MetaDimensionAttribute.java

@ -0,0 +1,179 @@
package de.superx.bianalysis.metadata.models.json;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import de.superx.bianalysis.metadata.UpsertStringBuilder;
@JsonInclude(Include.NON_DEFAULT)
@JsonPropertyOrder({ "id", "default_release", "ref", "caption", "dim_column"})
public class MetaDimensionAttribute extends MetaObject {
@JsonProperty("dim_column")
private String dimColumn;
@JsonProperty("sort_order_column")
private String sortOrderColumn;
@JsonProperty("hierarchical_filter")
private boolean hierarchicalFilter;
@JsonIgnore
private MetaDimension dimension;
@JsonIgnore
private MetaDimensionAttribute confDimAttrRef;
@JsonProperty("ref_to")
private String refTo;
@JsonProperty("filter_selection")
private String filterSelection;
public MetaDimensionAttribute() {
super("dimension_attribute");
}
public MetaDimensionAttribute(String attrColumn) {
super("dimension_attribute");
this.refTo = attrColumn;
//this.refTo = dimensionTable + "." + attrColumn;
}
public void setConformedDimensionAttribute(MetaDimensionAttribute attribute) {
this.confDimAttrRef = attribute;
}
@Override
public UpsertStringBuilder getUpsertBuilder() {
UpsertStringBuilder builder = new UpsertStringBuilder();
if(confDimAttrRef == null) {
builder = super.getUpsert()
.withIdCol("dimension_id", this.dimension.id)
.withStringCol("columnname", this.dimColumn)
.withStringCol("sort_order_column", this.sortOrderColumn)
.withStringCol("filter_selection", this.filterSelection);
} else {
builder = new UpsertStringBuilder()
.forTable("metadata", this.sourceTable)
.withStringCol("namespace", this.namespace)
.withIdCol("id", this.id)
.withIntCol("default_release", Integer.valueOf(1));
if(getCaption() != null && !getCaption().isBlank()) {
builder = builder.withStringCol("caption", caption);
} else {
builder = builder.withStringCol("caption", confDimAttrRef.getCaption());
}
if(getDimColumn() != null && !getDimColumn().isBlank()) {
builder = builder.withStringCol("columnname", this.dimColumn);
} else {
builder = builder.withStringCol("columnname", confDimAttrRef.getDimColumn());
}
if(getFilterSelection() != null && !getFilterSelection().isBlank()) {
builder = builder.withStringCol("filter_selection", this.filterSelection);
} else {
builder = builder.withStringCol("filter_selection", confDimAttrRef.getFilterSelection());
}
if(getSortOrderColumn() != null && !getSortOrderColumn().isBlank()) {
builder = builder.withStringCol("sort_order_column", this.sortOrderColumn);
} else {
builder = builder.withStringCol("sort_order_column", confDimAttrRef.getSortOrderColumn());
}
builder = builder.withIdCol("dimension_id", this.dimension.id);
builder = builder.withIdCol("conformed", this.confDimAttrRef.id);
}
if(confDimAttrRef != null && confDimAttrRef.hierarchicalFilter) {
builder = builder.withStringCol("hierarchical_filter", String.valueOf(confDimAttrRef.hierarchicalFilter));
} else {
builder = builder.withStringCol("hierarchical_filter", String.valueOf(hierarchicalFilter));
}
if(this.description != null && !this.description.isBlank()) {
builder = builder.withStringCol("description", this.description);
} else {
if(confDimAttrRef != null) {
builder = builder.withStringCol("description", confDimAttrRef.getDescription());
} else {
builder = builder.withStringCol("description", "");
}
}
return builder;
}
public String getDimColumn() {
return dimColumn;
}
public void setDimColumn(String dimColumn) {
this.dimColumn = dimColumn;
}
public String getSortOrderColumn() {
return sortOrderColumn;
}
public void setSortOrderColumn(String sortOrderColumn) {
this.sortOrderColumn = sortOrderColumn;
}
public String getFilterSelection() {
return filterSelection;
}
public void setFilterSelection(String filterSelection) {
this.filterSelection = filterSelection;
}
public MetaDimension getDimension() {
return dimension;
}
public void setDimension(MetaDimension dimension) {
this.dimension = dimension;
}
public MetaDimensionAttribute getConfDimAttrRef() {
return confDimAttrRef;
}
public void setConfDimAttrRef(MetaDimensionAttribute confDimAttrRef) {
this.confDimAttrRef = confDimAttrRef;
}
public String getRefTo() {
return refTo;
}
public void setRefTo(String refTo) {
this.refTo = refTo;
}
@JsonIgnore
@Override
public String getDocIdentifier() {
if(refTo != null) {
return this.confDimAttrRef.getDocIdentifier();
}
return this.dimension.getDocIdentifier()+"."+this.dimColumn;
}
public boolean isHierarchicalFilter() {
return hierarchicalFilter;
}
public void setHierarchicalFilter(boolean hierarchicalFilter) {
this.hierarchicalFilter = hierarchicalFilter;
}
}

77
src/de/superx/bianalysis/metadata/models/json/MetaFact.java

@ -0,0 +1,77 @@
package de.superx.bianalysis.metadata.models.json;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.metadata.UpsertStringBuilder;
@JsonPropertyOrder({ "id", "default_release", "caption", "sachgebiettid", "facttable", "conformed_dimensions", "dimensions", "measures" })
public class MetaFact extends MetaObject {
private Integer sachgebiettid;
private String facttable;
private List<MetaDimension> dimensions;
private List<MetaMeasure> measures;
public MetaFact() {
super("facttable");
}
@Override
public UpsertStringBuilder getUpsertBuilder() {
UpsertStringBuilder builder = super.getUpsert()
.withIntCol("sachgebiettid", this.sachgebiettid)
.withStringCol("tablename", this.facttable)
.withStringCol("description", super.getDescription());
return builder;
}
public Integer getSachgebiettid() {
return sachgebiettid;
}
public void setSachgebiettid(Integer sachgebiettid) {
this.sachgebiettid = sachgebiettid;
}
public String getFacttable() {
return facttable;
}
public void setFacttable(String facttable) {
this.facttable = facttable;
}
public List<MetaDimension> getDimensions() {
return dimensions;
}
public void setDimensions(List<MetaDimension> dimensions) {
for (MetaDimension metaDimension : dimensions) {
metaDimension.setFact(this);
}
this.dimensions = dimensions;
}
public List<MetaMeasure> getMeasures() {
return measures;
}
public void setMeasures(List<MetaMeasure> measures) {
for (MetaMeasure metaMeasure : measures) {
metaMeasure.setFact(this);
}
this.measures = measures;
}
@JsonIgnore
@Override
public String getDocIdentifier() {
return this.facttable;
}
}

82
src/de/superx/bianalysis/metadata/models/json/MetaMeasure.java

@ -0,0 +1,82 @@
package de.superx.bianalysis.metadata.models.json;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import de.superx.bianalysis.metadata.UpsertStringBuilder;
import de.superx.rest.model.ColumnType;
@JsonPropertyOrder({ "id", "default_release"} )
public class MetaMeasure extends MetaObject {
private String factcolumn;
private String aggregation;
private ColumnType type;
private MetaMeasureFilter filter;
@JsonIgnore
private MetaFact fact;
public MetaMeasure() {
super("measure");
}
@Override
public UpsertStringBuilder getUpsertBuilder() {
return super.getUpsert()
.withIdCol("facttable_id", (this.fact != null) ? this.fact.id : null)
.withIdCol("measure_filter_id", (this.filter != null) ? this.filter.id : null)
.withStringCol("columnname", this.factcolumn)
.withStringCol("aggregation_type", this.aggregation)
.withStringCol("description", this.description)
.withStringCol("measure_type", this.type, ColumnType.IntegerColumn);
}
public String getFactcolumn() {
return factcolumn;
}
public void setFactcolumn(String factcolumn) {
this.factcolumn = factcolumn;
}
public String getAggregation() {
return aggregation;
}
public void setAggregation(String aggregation) {
this.aggregation = aggregation;
}
public ColumnType getType() {
return type;
}
public void setType(ColumnType type) {
this.type = type;
}
public MetaMeasureFilter getFilter() {
return filter;
}
public void setFilter(MetaMeasureFilter filter) {
this.filter = filter;
}
public MetaFact getFact() {
return fact;
}
public void setFact(MetaFact fact) {
this.fact = fact;
}
@JsonIgnore
@Override
public String getDocIdentifier() {
return this.factcolumn;
}
}

106
src/de/superx/bianalysis/metadata/models/json/MetaMeasureFilter.java

@ -0,0 +1,106 @@
package de.superx.bianalysis.metadata.models.json;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import de.superx.bianalysis.metadata.UpsertStringBuilder;
@JsonPropertyOrder({ "id", "default_release"} )
public class MetaMeasureFilter extends MetaObject {
private String dimensionRef;
private String factColumnRef;
@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
private List<String> included;
@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
private List<String> excluded;
@JsonIgnore
private MetaDimensionAttribute attribute;
public MetaMeasureFilter() {
super("measure_filter");
}
@Override
public UpsertStringBuilder getUpsertBuilder() {
UpsertStringBuilder builder = super.getUpsert();
builder.withStringCol("included_values", concatValues(included));
builder.withStringCol("excluded_values", concatValues(excluded));
if(this.dimensionRef != null) {
builder.withIdCol("dimension_attribute_id", this.attribute.id);
} else if(this.factColumnRef != null){
builder.withStringCol("fact_column_filter", this.factColumnRef);
}
return builder;
}
private static String concatValues(List<String> values) {
if (values == null || values.isEmpty()) {
return null;
}
String result = "";
int size = values.size();
for (int i = 0; i < size - 1; i++) {
result += "''" + values.get(i) + "'', ";
}
result += "''" + values.get(size - 1) + "''";
return result;
}
public String getDimensionRef() {
return dimensionRef;
}
public void setDimensionRef(String dimensionRef) {
this.dimensionRef = dimensionRef;
}
public List<String> getIncluded() {
return included;
}
public void setIncluded(List<String> included) {
this.included = included;
}
public List<String> getExcluded() {
return excluded;
}
public void setExcluded(List<String> excluded) {
this.excluded = excluded;
}
public MetaDimensionAttribute getAttribute() {
return attribute;
}
public void setAttribute(MetaDimensionAttribute attribute) {
this.attribute = attribute;
}
@JsonIgnore
@Override
public String getDocIdentifier() {
return "";
}
public String getFactColumnRef() {
return factColumnRef;
}
public void setFactColumnRef(String factColumnRef) {
this.factColumnRef = factColumnRef;
}
}

112
src/de/superx/bianalysis/metadata/models/json/MetaObject.java

@ -0,0 +1,112 @@
package de.superx.bianalysis.metadata.models.json;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.metadata.UpsertStringBuilder;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_NULL)
public abstract class MetaObject {
protected Identifier id;
protected String caption;
protected String description;
@JsonProperty("default_release")
protected String defaultRelease;
@JsonIgnore
protected String sourceTable;
@JsonIgnore
protected String namespace;
protected MetaObject(String sourceTable) {
this.sourceTable = sourceTable;
}
/**
* Returns the documentation identifier for a specific meta object.
* The Identifier is used in a *.md file and is referenced in the yml
* file like the following: '{{ doc("<identifier>") }}'.
*/
@JsonIgnore
public abstract String getDocIdentifier();
@JsonIgnore
public abstract UpsertStringBuilder getUpsertBuilder();
@JsonIgnore
protected UpsertStringBuilder getUpsert() {
return new UpsertStringBuilder()
.forTable("metadata", this.sourceTable)
.withStringCol("namespace", this.namespace)
.withIdCol("id", this.id)
.withStringCol("default_release", this.defaultRelease)
.withStringCol("caption", this.caption);
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof MetaObject)) {
return false;
} else if(((MetaObject)obj).id == null) {
return false;
}
return this.id.equals(((MetaObject)obj).id);
}
public Identifier getId() {
return id;
}
public void setId(Identifier id) {
this.id = id;
}
public String getCaption() {
return caption;
}
public void setCaption(String caption) {
this.caption = caption;
}
public String getSourceTable() {
return sourceTable;
}
public void setSourceTable(String sourceTable) {
this.sourceTable = sourceTable;
}
public String getNamespace() {
return namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDefaultRelease() {
return defaultRelease;
}
public void setDefaultRelease(String defaultRelease) {
this.defaultRelease = defaultRelease;
}
}

32
src/de/superx/bianalysis/metadata/models/yml/MetaYml.java

@ -0,0 +1,32 @@
package de.superx.bianalysis.metadata.models.yml;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class MetaYml {
private int version;
private List<MetaYmlModel> models;
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public List<MetaYmlModel> getModels() {
if(this.models == null) {
return new ArrayList<MetaYmlModel>();
}
return models;
}
public void setModels(List<MetaYmlModel> models) {
this.models = models;
}
}

49
src/de/superx/bianalysis/metadata/models/yml/MetaYmlModel.java

@ -0,0 +1,49 @@
package de.superx.bianalysis.metadata.models.yml;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class MetaYmlModel {
private String name;
private String description;
private List<MetaYmlModelColumns> columns;
public MetaYmlModel() { }
public MetaYmlModel(String name, String description) {
super();
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<MetaYmlModelColumns> getColumns() {
if(this.columns == null) {
return new ArrayList<MetaYmlModelColumns>();
}
return columns;
}
public void setColumns(List<MetaYmlModelColumns> columns) {
this.columns = columns;
}
}

52
src/de/superx/bianalysis/metadata/models/yml/MetaYmlModelColumns.java

@ -0,0 +1,52 @@
package de.superx.bianalysis.metadata.models.yml;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class MetaYmlModelColumns {
private String name;
private String description;
private List<Object> tests;
public MetaYmlModelColumns() {}
public MetaYmlModelColumns(String name, String description, String test) {
super();
this.name = name;
this.description = description;
this.tests = new ArrayList<Object>();
this.tests.add(test);
}
public MetaYmlModelColumns(String name, String description) {
super();
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<Object> getTests() {
return tests;
}
public void setTests(List<Object> tests) {
this.tests = tests;
}
}

94
src/de/superx/bianalysis/models/Dimension.java

@ -0,0 +1,94 @@
package de.superx.bianalysis.models;
import java.util.List;
import org.springframework.data.annotation.Transient;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.repository.dto.DimensionDto;
public class Dimension {
private DimensionDto dimensionDto;
@Transient
public String conformedCaption;
@Transient
public String conformedDescription;
@Transient
public List<DimensionAttribute> dimensionAttributes;
public Dimension(DimensionDto dimDto) {
this.setDimensionDto(dimDto);
}
public void setDimensionAttributes(List<DimensionAttribute> lda) {
for (DimensionAttribute dimensionAttribute : lda) {
dimensionAttribute.setDimensionColumnAlias(dimensionAttribute.getColumnname() + "_" + getId().value);
}
this.dimensionAttributes = lda;
}
public boolean isHidden() {
if(this.dimensionDto.isHidden == null) {
return false;
}
return this.dimensionDto.isHidden.booleanValue();
}
public DimensionDto getDimensionDto() {
return dimensionDto;
}
public void setDimensionDto(DimensionDto dimensionDto) {
this.dimensionDto = dimensionDto;
}
public Identifier getId() {
return this.dimensionDto.id;
}
public String getCaption() {
return this.dimensionDto.caption;
}
public Identifier getFactTableId() {
return this.dimensionDto.factTableId;
}
public String getTablename() {
return this.dimensionDto.tablename;
}
public String getJoincolumn() {
return this.dimensionDto.joincolumn;
}
public String getAlias() {
return this.dimensionDto.alias;
}
public String getDescription() {
return this.dimensionDto.description;
}
public boolean isHierarchy() {
if(this.dimensionDto.isHierarchy == null) return false;
return this.dimensionDto.isHierarchy.booleanValue();
}
public boolean isHistorical() {
if(this.dimensionDto.isHistorical == null) return false;
return this.dimensionDto.isHistorical.booleanValue();
}
public String getConformed() {
return this.dimensionDto.conformed;
}
public String getIdColumn() {
return this.dimensionDto.idColumn;
}
}

276
src/de/superx/bianalysis/models/DimensionAttribute.java

@ -0,0 +1,276 @@
package de.superx.bianalysis.models;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.repository.dto.AttributeDto;
public class DimensionAttribute {
public static final List<String> SPECIAL_VALUES = List.of("n. v.", "k.A.", "k.a.", "unbekannt", "Unbekannt", "ungültig", "Ungültig");
public static final Comparator<String> SPECIAL_VALUE_COMPARATOR = (a1, a2) -> {
if (a1.equals(a2)) {
return 0;
}
if (DimensionAttribute.SPECIAL_VALUES.contains(a1)) {
return -1;
}
if (DimensionAttribute.SPECIAL_VALUES.contains(a2)) {
return 1;
}
return a1.compareTo(a2);
};
public static String specialValueListForSql() {
String result = String.join("', '", SPECIAL_VALUES);
return "'" + result + "'";
}
private String conformedCaption;
private String conformedDescription;
@JsonIgnore
private AttributeDto attributeTable;
@JsonIgnore
private String dimCaption;
@JsonIgnore
private String dimId;
@JsonIgnore
private String dimConformedId;
@JsonIgnore
private String tablename;
@JsonIgnore
private String joincolumn;
private boolean isHierarchy;
@JsonIgnore
private boolean isHistorical;
@JsonIgnore
private String dimensionTableAlias;
@JsonIgnore
private String dimensionColumnAlias;
private List<String> dimensionAttributeValues;
@JsonIgnore
private String dimIdJoinColumn;
public DimensionAttribute() {
super();
}
public DimensionAttribute(AttributeDto attributeTable) {
this.attributeTable = attributeTable;
}
public void setDimension(Dimension dim) {
this.dimCaption = dim.getCaption();
this.dimId = dim.getId().composedId;
this.tablename = dim.getTablename();
this.joincolumn = dim.getJoincolumn();
this.isHierarchy = dim.isHierarchy();
this.isHistorical = dim.isHistorical();
this.dimIdJoinColumn = dim.getIdColumn();
if(dim.getAlias() != null){
this.dimensionTableAlias = dim.getAlias();
} else {
this.dimensionTableAlias = generateDimensionTableAlias(joincolumn);
}
this.dimensionColumnAlias = getColumnname() + "_" + getId().value;
}
public static String generateDimensionTableAlias(String joincolumn) {
if (joincolumn != null) {
return joincolumn.replaceFirst("_id$", "");
}
return null;
}
@Override
public int hashCode() {
return Objects.hash(getId());
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
DimensionAttribute other = (DimensionAttribute) obj;
return Objects.equals(this.getId(), other.getId());
}
public String getCaption() {
return this.attributeTable.caption;
}
public boolean isHidden() {
if(this.attributeTable.isHidden == null) {
return false;
}
return this.attributeTable.isHidden.booleanValue();
}
public String getColumnname() {
return this.attributeTable.columnname;
}
public String getSortOrderColumn() {
return this.attributeTable.sortOrderColumn;
}
public String getFilterSelection() {
return this.attributeTable.filterSelection;
}
public String getDimId() {
return dimId;
}
public void setDimId(String dimId) {
this.dimId = dimId;
}
public String getDimConformedId() {
return dimConformedId;
}
public void setDimConformedId(String dimConformedId) {
this.dimConformedId = dimConformedId;
}
public String getAttrConformedId() {
return this.attributeTable.attrConformedId;
}
public Identifier getId() {
return this.attributeTable.id;
}
@JsonIgnore
public String getStringId() {
return this.attributeTable.id.composedId;
}
public String getDimCaption() {
return dimCaption;
}
public void setDimCaption(String dimCaption) {
this.dimCaption = dimCaption;
}
public String getDimensionTableAlias() {
return dimensionTableAlias;
}
public void setDimensionTableAlias(String dimensionTableAlias) {
this.dimensionTableAlias = dimensionTableAlias;
}
public String getDimensionColumnAlias() {
return dimensionColumnAlias;
}
public void setDimensionColumnAlias(String dimensionColumnAlias) {
this.dimensionColumnAlias = dimensionColumnAlias;
}
public String getConformedCaption() {
return conformedCaption;
}
public void setConformedCaption(String conformedCaption) {
this.conformedCaption = conformedCaption;
}
public String getConformedDescription() {
return conformedDescription;
}
public void setConformedDescription(String conformedDescription) {
this.conformedDescription = conformedDescription;
}
public String getDescription() {
return this.attributeTable.description;
}
public Identifier getDimensionId() {
return this.attributeTable.dimensionId;
}
public String getTablename() {
return tablename;
}
public void setTablename(String tablename) {
this.tablename = tablename;
}
public String getJoincolumn() {
return joincolumn;
}
public void setJoincolumn(String joincolumn) {
this.joincolumn = joincolumn;
}
@JsonProperty(value="isHierarchy")
public boolean isHierarchy() {
return isHierarchy;
}
public boolean isHistorical() {
return isHistorical;
}
public void setHierarchy(boolean isHierarchy) {
this.isHierarchy = isHierarchy;
}
public void setHistorical(boolean isHistorical) {
this.isHistorical = isHistorical;
}
public boolean isHierarchicalFilter() {
return this.attributeTable.hierarchicalFilter.booleanValue();
}
public List<String> getDimensionAttributeValues() {
return dimensionAttributeValues;
}
public void setDimensionAttributeValues(List<String> dimensionAttributeValues) {
this.dimensionAttributeValues = dimensionAttributeValues;
}
public void setDimIdJoinColumn(String idColumn) {
this.dimIdJoinColumn = idColumn;
}
public String getDimIdJoinColumn() {
return this.dimIdJoinColumn;
}
public void setAttrConformedId(String stringId) {
this.attributeTable.attrConformedId = stringId;
}
}

71
src/de/superx/bianalysis/models/FactTable.java

@ -0,0 +1,71 @@
package de.superx.bianalysis.models;
import java.util.List;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.relational.core.mapping.Table;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.repository.dto.FactDto;
import de.superx.jdbc.entity.Sachgebiet;
@Table(value ="metadata\".\"facttable")
public class FactTable {
private FactDto factDto;
@Transient
private Sachgebiet sachgebiet;
@Transient
private List<Dimension> conformedDimensions;
public FactTable() {}
public FactTable(FactDto factDto) {
this.factDto = factDto;
}
public Identifier getId() {
return this.factDto.id;
}
public String getCaption() {
if(this.factDto != null) {
return this.factDto.caption;
}
return null;
}
public int getSachgebiettid() {
return this.factDto.sachgebiettid.intValue();
}
public String getDescription() {
return this.factDto.description;
}
public String getTablename() {
return this.factDto.tablename;
}
public List<Dimension> getConformedDimensions() {
return conformedDimensions;
}
public void setConformedDimensions(List<Dimension> conformedDimensions) {
this.conformedDimensions = conformedDimensions;
}
public Sachgebiet getSachgebiet() {
return sachgebiet;
}
public void setSachgebiet(Sachgebiet sachgebiet) {
this.sachgebiet = sachgebiet;
}
}

89
src/de/superx/bianalysis/models/Filter.java

@ -0,0 +1,89 @@
package de.superx.bianalysis.models;
import java.util.List;
import java.util.StringJoiner;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.superx.bianalysis.ReportMetadata;
import de.superx.bianalysis.metadata.Identifier;
public class Filter {
public Identifier dimensionAttributeId;
public List<String> filterValues;
public String columnname;
public String tablename;
public String joincolumn;
public String dimensionTableAlias;
public Filter() {
super();
}
public Filter(List<String> values, Identifier dimAttrId) {
this.filterValues = values;
this.dimensionAttributeId = dimAttrId;
}
public Filter(Filter filter) {
this.dimensionAttributeId = filter.dimensionAttributeId;
this.filterValues = filter.filterValues;
this.columnname = filter.columnname;
this.tablename = filter.tablename;
this.joincolumn = filter.joincolumn;
this.dimensionTableAlias = filter.dimensionTableAlias;
}
public void setDimensionAttribute(DimensionAttribute attr) {
this.columnname = attr.getColumnname();
}
public void setDimension(Dimension dim) {
this.tablename = dim.getTablename();
this.joincolumn = dim.getJoincolumn();
if(dim.getAlias() != null) {
this.dimensionTableAlias = dim.getAlias();
} else {
this.dimensionTableAlias = joincolumn.replaceFirst("_id$", "");
}
}
public DimensionAttribute getDimAttribute(ReportMetadata reportMetadata) {
return reportMetadata.getDimAttrById(this.dimensionAttributeId);
}
@Override
public String toString() {
return String.valueOf(this.dimensionAttributeId);
}
public static Filter findFilterById(List<Filter> filters, Identifier id) {
return filters
.stream()
.filter(f -> f.dimensionAttributeId.equals(id))
.findFirst()
.orElse(null);
}
@JsonIgnore
public String getValuesAsString() {
if(this.filterValues == null || this.filterValues.isEmpty()) {
return null;
}
return String.join(", ", this.filterValues);
}
@JsonIgnore
public String getValues() {
if(this.filterValues == null || this.filterValues.isEmpty()) {
return null;
}
StringJoiner joiner = new StringJoiner(", ");
for (String value : filterValues) {
joiner.add("'"+value+"'");
}
return joiner.toString();
}
}

89
src/de/superx/bianalysis/models/Info.java

@ -0,0 +1,89 @@
package de.superx.bianalysis.models;
import java.util.ArrayList;
import java.util.List;
import de.superx.rest.model.Item;
public class Info {
public String segmentCaption;
public String lastUpdateBiad;
public List<String> sachgebiete = new ArrayList<String>();
public List<InfoItem> facttables = new ArrayList<InfoItem>();
public List<InfoItem> measures = new ArrayList<InfoItem>();
public List<InfoItem> leftDimensionAttributes = new ArrayList<InfoItem>();
public List<InfoItem> topDimensionAttributes = new ArrayList<InfoItem>();
public List<String> filter = new ArrayList<String>();
public String hideEmptyColumns;
public List<Item> sqlStatements = new ArrayList<Item>();
public String error;
public void addSachgebiet(String sachgebiet) {
sachgebiete.add(sachgebiet);
}
public void addFacttable(InfoItem facttable) {
facttables.add(facttable);
}
public void setMeasures(List<InfoItem> measures) {
this.measures = measures;
}
public void setLeftDimensionAttributes(List<InfoItem> leftDimensionAttributes) {
this.leftDimensionAttributes = leftDimensionAttributes;
}
public void setTopDimensionAttributes(List<InfoItem> topDimensionAttributes) {
this.topDimensionAttributes = topDimensionAttributes;
}
public void setSachgebiete(List<String> sachgebiete) {
this.sachgebiete = sachgebiete;
}
public void setFacttables(List<InfoItem> facttables) {
this.facttables = facttables;
}
public void setFilter(List<String> filter) {
this.filter = filter;
}
public void setSqlStatements(List<Item> sqlStatements) {
this.sqlStatements = sqlStatements;
}
public void setLastUpdateBiad(String lastUpdateBiad) {
this.lastUpdateBiad = lastUpdateBiad;
}
public void setErrorMessage(String error) {
this.error = error;
}
public void setSegmentCaption(String segmentCaption) {
this.segmentCaption = segmentCaption;
}
public void hideEmptyColumns(boolean hideEmptyColumns) {
if(hideEmptyColumns) {
this.hideEmptyColumns = "Ja";
} else {
this.hideEmptyColumns = "Nein";
}
}
public void setHideEmptyColumns(String hideEmptyColumns) {
this.hideEmptyColumns = hideEmptyColumns;
}
}

19
src/de/superx/bianalysis/models/InfoItem.java

@ -0,0 +1,19 @@
package de.superx.bianalysis.models;
public class InfoItem {
public String id;
public String caption;
public String description;
public InfoItem(String id, String caption, String description) {
this.id = id;
this.caption = caption;
this.description = description;
}
public InfoItem() {
super();
}
}

130
src/de/superx/bianalysis/models/Measure.java

@ -0,0 +1,130 @@
package de.superx.bianalysis.models;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.repository.dto.MeasureDto;
import de.superx.bianalysis.repository.dto.MeasureFilterDto;
import de.superx.rest.model.ColumnType;
public class Measure {
private MeasureDto measureDto;
@JsonIgnore
public String filterTablename;
@JsonIgnore
public String filterJoincolumn;
@JsonIgnore
public String filterColumnname;
@JsonIgnore
public String filterInclude;
@JsonIgnore
public String filterExclude;
@JsonIgnore
public String filterDimensionTableAlias;
@JsonIgnore
public String filterCondition;
@JsonIgnore
public String factColumnFilter;
@JsonIgnore
public Identifier filterAttributeId;
public Measure() {
super();
}
public Measure(MeasureDto measureDTO) {
this.measureDto = measureDTO;
}
public void setMeasureFilterAttributes(MeasureFilterDto filter, DimensionAttribute attribute, Dimension dimension) {
this.filterInclude = filter.includedValues;
this.filterExclude = filter.excludedValues;
this.filterTablename = dimension.getTablename();
this.filterJoincolumn = dimension.getJoincolumn();
this.filterColumnname = attribute.getColumnname();
this.filterAttributeId = attribute.getId();
if (dimension.getAlias() != null) {
this.filterDimensionTableAlias = dimension.getAlias();
} else {
this.filterDimensionTableAlias = generatefilterDimensionTableAlias(filterJoincolumn);
}
this.filterCondition = generateFilterCondition();
}
public void setFactColumnFilter(MeasureFilterDto filter) {
this.factColumnFilter = filter.factColumnFilter;
this.filterInclude = filter.includedValues;
this.filterExclude = filter.excludedValues;
this.filterCondition = generateFilterCondition();
}
private static String generatefilterDimensionTableAlias(String filterJoincolumn) {
if (filterJoincolumn != null) {
return filterJoincolumn.replaceFirst("_id$", "");
}
return null;
}
private String generateFilterCondition() {
if (this.measureDto.measureFilterId.value != null) {
StringBuilder filterConditionStatement = new StringBuilder();
String tableDotColumn = this.filterDimensionTableAlias + "." + this.filterColumnname;
if(factColumnFilter != null && !factColumnFilter.isBlank()) {
tableDotColumn = factColumnFilter;
}
if (this.filterInclude != null) {
filterConditionStatement.append(tableDotColumn + " IN ("
+ this.filterInclude + ")");
}
if (this.filterInclude != null && this.filterExclude != null) {
filterConditionStatement.append(" AND ");
}
if (this.filterExclude != null) {
filterConditionStatement.append(tableDotColumn
+ " NOT IN (" + this.filterExclude + ")");
}
return filterConditionStatement.toString();
}
return null;
}
public Identifier getId() {
return this.measureDto.id;
}
public String getCaption() {
return this.measureDto.caption;
}
public String getColumnname() {
return this.measureDto.columnname;
}
public String getDescription() {
return this.measureDto.description;
}
public String getAggregationType() {
return this.measureDto.aggregationType;
}
public ColumnType getMeasureType() {
return this.measureDto.measureType;
}
public Identifier getMeasureFilterId() {
return this.measureDto.measureFilterId;
}
}

29
src/de/superx/bianalysis/models/Right.java

@ -0,0 +1,29 @@
package de.superx.bianalysis.models;
public enum Right {
VIEW_REPORT("RIGHT_CS_BIA_ANALYSIS_VIEW_ANALYSIS_TABLE"),
CREATE_ANALYSIS("RIGHT_CS_BIA_ANALYSIS_CREATE_ANALYSIS");
private String string;
Right(String string) {
this.setString(string);
}
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
public static String getPrintableRights(Right... rights) {
String out = "";
for (Right right : rights) {
out += right.toString();
}
return out;
}
}

21
src/de/superx/bianalysis/models/RightParam.java

@ -0,0 +1,21 @@
package de.superx.bianalysis.models;
public enum RightParam {
TOPIC_AREA("bianalysis.topic_area"),
TOPIC("bianalysis.topic");
private String string;
RightParam(String string) {
this.setString(string);
}
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
}

42
src/de/superx/bianalysis/repository/DimensionAttributeRepository.java

@ -0,0 +1,42 @@
package de.superx.bianalysis.repository;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.RepositoryDefinition;
import org.springframework.data.repository.query.Param;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.repository.dto.AttributeDto;
import de.superx.jdbc.repository.BiaAdminCrudRepository;
@RepositoryDefinition(domainClass = AttributeDto.class, idClass = Identifier.class)
public interface DimensionAttributeRepository extends BiaAdminCrudRepository<AttributeDto> {
List<AttributeDto> findByDimensionId(Identifier dimensionId);
Optional<AttributeDto> findById(Identifier id);
@Query(
"SELECT da.id"
+ " FROM metadata.dimension_attribute da"
+ " LEFT JOIN metadata.dimension d"
+ " ON d.id = da.dimension_id"
+ " WHERE da.conformed = :confAttrId"
+ " AND facttable_id = :factId"
)
List<Identifier> findAttributesByConformedAttributeAndFactTable(@Param("confAttrId") String confAttrId, @Param("factId") String factId);
@Query(
"SELECT da.id"
+ " FROM metadata.dimension_attribute da"
+ " LEFT JOIN metadata.dimension d"
+ " ON d.id = da.dimension_id"
+ " WHERE da.id = :attrId"
+ " AND d.facttable_id = :factId"
)
Identifier findAttributesByIdAndFactTable(@Param("attrId") String confAttrId, @Param("factId") String factId);
}

50
src/de/superx/bianalysis/repository/DimensionRepository.java

@ -0,0 +1,50 @@
package de.superx.bianalysis.repository;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.RepositoryDefinition;
import org.springframework.data.repository.query.Param;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.repository.dto.DimensionDto;
import de.superx.jdbc.repository.BiaAdminCrudRepository;
@RepositoryDefinition(domainClass = DimensionDto.class, idClass = Identifier.class)
public interface DimensionRepository extends BiaAdminCrudRepository<DimensionDto> {
List<DimensionDto> findByFactTableId(Identifier factTableId);
Optional<DimensionDto> findById(Identifier id);
@Override
List<DimensionDto> findAll();
@Query(
" SELECT d.id"
+ " FROM metadata.dimension d"
+ " LEFT JOIN metadata.dimension_attribute da"
+ " ON da.dimension_id = d.id"
+ " WHERE da.id is null"
+ " AND d.conformed = :confDim"
+ " AND d.facttable_id = :factId"
)
List<Identifier> getRolePlayingIds(@Param("confDim") String confDim, @Param("factId") String factId);
@Query(
"SELECT dimension_id "
+ "FROM metadata.dimension_attribute da "
+ "WHERE id = :attrId"
)
Identifier findDimensionIdForAttribute(@Param("attrId") String attrId);
@Query(
"SELECT conformed"
+ " FROM metadata.dimension"
+ " WHERE facttable_id = :factId"
+ " AND conformed IS NOT NULL"
)
List<Identifier> getUsedConformedDimensionsByFactTable(@Param("factId") String factId);
}

47
src/de/superx/bianalysis/repository/FactRepository.java

@ -0,0 +1,47 @@
package de.superx.bianalysis.repository;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.RepositoryDefinition;
import org.springframework.data.repository.query.Param;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.repository.dto.FactDto;
import de.superx.jdbc.repository.BiaAdminCrudRepository;
@RepositoryDefinition(domainClass = FactDto.class, idClass = Identifier.class)
public interface FactRepository extends BiaAdminCrudRepository<FactDto> {
@Override
List<FactDto> findAll();
Optional<FactDto> findById(Identifier id);
Optional<FactDto> findByTablename(String tablename);
@Query(
"SELECT COUNT(*) > 0"
+ " FROM metadata.facttable f"
+ " LEFT JOIN metadata.measure m"
+ " ON m.facttable_id = f.id"
+ " WHERE f.id = :factId"
+ " AND m.id = :measureId"
)
boolean hasFactTableMeasure(@Param("factId") String factId, @Param("measureId") String measureId);
@Query(
"SELECT f.tablename"
+ " FROM metadata.dimension_attribute da"
+ " LEFT JOIN metadata.dimension d"
+ " ON d.id = da.dimension_id"
+ " LEFT JOIN metadata.facttable f"
+ " ON f.id = d.facttable_id"
+ " WHERE f.id = :factId"
+ " AND (da.conformed = :attrId OR da.id = :attrId)"
)
String getFactTableNameForAttribute(@Param("factId") String factId, @Param("attrId") String attrId);
}

13
src/de/superx/bianalysis/repository/MeasureFilterRepository.java

@ -0,0 +1,13 @@
package de.superx.bianalysis.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.RepositoryDefinition;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.repository.dto.MeasureFilterDto;
import de.superx.jdbc.repository.BiaAdminCrudRepository;
@RepositoryDefinition(domainClass = MeasureFilterDto.class, idClass = Identifier.class)
public interface MeasureFilterRepository extends BiaAdminCrudRepository<MeasureFilterDto> {
}

17
src/de/superx/bianalysis/repository/MeasureRepository.java

@ -0,0 +1,17 @@
package de.superx.bianalysis.repository;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.RepositoryDefinition;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.repository.dto.MeasureDto;
import de.superx.jdbc.repository.BiaAdminCrudRepository;
@RepositoryDefinition(domainClass = MeasureDto.class, idClass = Identifier.class)
public interface MeasureRepository extends BiaAdminCrudRepository<MeasureDto> {
List<MeasureDto> findByFactTableId(Identifier id);
}

23
src/de/superx/bianalysis/repository/StoredReportRepository.java

@ -0,0 +1,23 @@
package de.superx.bianalysis.repository;
import java.util.List;
import java.util.Optional;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.RepositoryDefinition;
import de.superx.bianalysis.StoredReport;
@RepositoryDefinition(domainClass = StoredReport.class, idClass = Integer.class)
public interface StoredReportRepository extends CrudRepository<StoredReport, Integer> {
Optional<StoredReport> findByName(String name);
Optional<StoredReport> findById(int id);
void deleteById(int id);
@Override
List<StoredReport> findAll();
}

74
src/de/superx/bianalysis/repository/dto/AttributeDto.java

@ -0,0 +1,74 @@
package de.superx.bianalysis.repository.dto;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.jdbc.entity.EntityBase;
import de.superx.jdbc.model.DynamicFieldType;
import de.superx.jdbc.model.EntityDescriptor;
import de.superx.jdbc.model.TableRef;
import de.superx.rest.model.ColumnType;
import de.superx.rest.model.FieldType;
@Table(schema = "metadata", value = "dimension_attribute")
public class AttributeDto extends EntityBase {
@Id
@DynamicFieldType(label="ID", readOnly = true, visibleInSimplifiedForm = false)
public Identifier id;
@EntityDescriptor
@DynamicFieldType(label="Titel")
public String caption;
@DynamicFieldType(label="Beschreibung", editControlType=FieldType.TextArea)
public String description;
@DynamicFieldType(label="Dimension", readOnly = true, visibleInSimplifiedForm = false)
@TableRef(schema = "metadata", table = "dimension", keyField = "id", labelField = "caption")
@Column(value = "dimension_id")
public Identifier dimensionId;
@DynamicFieldType(label="Spaltenname", readOnly = true)
public String columnname;
@DynamicFieldType(label="Sortierspalte", readOnly = true, visibleInSimplifiedForm = false)
@Column(value = "sort_order_column")
public String sortOrderColumn;
@DynamicFieldType(label="Filter-Auswahl", visibleInSimplifiedForm = false)
@Column(value = "filter_selection")
public String filterSelection;
@DynamicFieldType(label="Hierarchie", editControlType=FieldType.Select, columnType = ColumnType.BooleanColumnBiAnalysis, readOnly = true)
@Column(value = "hierarchical_filter")
public Boolean hierarchicalFilter;
@DynamicFieldType(label="Ausgeblendet", editControlType=FieldType.Select, columnType = ColumnType.BooleanColumnBiAnalysis)
@Column(value = "is_hidden")
public Boolean isHidden;
@DynamicFieldType(label="Conformed Attribute", readOnly = true, visibleInSimplifiedForm = false)
@TableRef(schema = "metadata", table = "dimension_attribute", keyField = "id", labelField = "caption")
@Column(value = "conformed")
public String attrConformedId;
@DynamicFieldType(label="Auslieferungsversion", visibleInSimplifiedForm = false)
@Column(value = "default_release")
public String defaultRelease;
public AttributeDto() {}
@Override
public boolean canBeCreatedByUser() {
return false;
}
@Override
public boolean canBeDeletedByUser() {
return false;
}
}

79
src/de/superx/bianalysis/repository/dto/DimensionDto.java

@ -0,0 +1,79 @@
package de.superx.bianalysis.repository.dto;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.jdbc.entity.EntityBase;
import de.superx.jdbc.model.DynamicFieldType;
import de.superx.jdbc.model.EntityDescriptor;
import de.superx.rest.model.ColumnType;
import de.superx.rest.model.FieldType;
import de.superx.jdbc.model.TableRef;
@Table(schema="metadata", value = "dimension")
public class DimensionDto extends EntityBase{
@Id
@DynamicFieldType(label="ID", readOnly = true)
public Identifier id;
@EntityDescriptor
@DynamicFieldType(label="Titel")
public String caption;
@DynamicFieldType(label="Beschreibung", editControlType=FieldType.TextArea)
public String description;
@DynamicFieldType(label="Faktentabelle", readOnly = true, visibleInSimplifiedForm = false)
@TableRef(schema = "metadata", table = "facttable", keyField = "id", labelField = "caption")
@Column(value = "facttable_id")
public Identifier factTableId;
@DynamicFieldType(label="Tabellenname", readOnly = true)
public String tablename;
@DynamicFieldType(label="Join-Spalte", readOnly = true, visibleInSimplifiedForm = false)
public String joincolumn;
@DynamicFieldType(label="Join-Alias", readOnly = true, visibleInSimplifiedForm = false)
public String alias;
@DynamicFieldType(label="Hierarchie", editControlType=FieldType.Select, columnType = ColumnType.BooleanColumnBiAnalysis, readOnly = true)
@Column(value = "is_hierarchy")
public Boolean isHierarchy;
@DynamicFieldType(label="Historisch", editControlType=FieldType.Select, columnType = ColumnType.BooleanColumnBiAnalysis, readOnly = true)
@Column(value = "is_historical")
public Boolean isHistorical;
@DynamicFieldType(label="Conformed Dimension", readOnly = true, visibleInSimplifiedForm = false)
@TableRef(schema = "metadata", table = "dimension", keyField = "id", labelField = "caption")
public String conformed;
@DynamicFieldType(label="ID Spalte", readOnly = true, visibleInSimplifiedForm = false)
@Column(value = "id_column")
public String idColumn;
@DynamicFieldType(label="Auslieferungsversion", visibleInSimplifiedForm = false)
@Column(value = "default_release")
public String defaultRelease;
@DynamicFieldType(label="Ausgeblendet", editControlType=FieldType.Select, columnType = ColumnType.BooleanColumnBiAnalysis)
@Column(value = "is_hidden")
public Boolean isHidden;
public DimensionDto() {}
@Override
public boolean canBeCreatedByUser() {
return false;
}
@Override
public boolean canBeDeletedByUser() {
return false;
}
}

50
src/de/superx/bianalysis/repository/dto/FactDto.java

@ -0,0 +1,50 @@
package de.superx.bianalysis.repository.dto;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.jdbc.entity.EntityBase;
import de.superx.jdbc.model.DynamicFieldType;
import de.superx.jdbc.model.EntityDescriptor;
import de.superx.jdbc.model.TableRef;
import de.superx.rest.model.FieldType;
@Table(schema = "metadata", value = "facttable")
public class FactDto extends EntityBase {
@Id
@DynamicFieldType(label="ID", readOnly = true, visibleInSimplifiedForm = false)
public Identifier id;
@EntityDescriptor
@DynamicFieldType(label="Titel")
public String caption;
@DynamicFieldType(label="Beschreibung", editControlType=FieldType.TextArea)
public String description;
@DynamicFieldType(label = "Sachgebiet", editControlType = FieldType.Select)
@TableRef(table = "sachgebiete", keyField = "tid", labelField = "name")
public Integer sachgebiettid;
@DynamicFieldType(label="Tabellenname", readOnly = true)
public String tablename;
@DynamicFieldType(label="Auslieferungsversion", visibleInSimplifiedForm = false)
@Column(value = "default_release")
public String defaultRelease;
public FactDto() {}
@Override
public boolean canBeCreatedByUser() {
return false;
}
@Override
public boolean canBeDeletedByUser() {
return false;
}
}

66
src/de/superx/bianalysis/repository/dto/MeasureDto.java

@ -0,0 +1,66 @@
package de.superx.bianalysis.repository.dto;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.jdbc.entity.EntityBase;
import de.superx.jdbc.model.DynamicFieldType;
import de.superx.jdbc.model.EntityDescriptor;
import de.superx.rest.model.ColumnType;
import de.superx.rest.model.FieldType;
import de.superx.jdbc.model.TableRef;
@Table(schema = "metadata", value = "measure")
public class MeasureDto extends EntityBase {
@Id
@DynamicFieldType(label="ID", readOnly = true, visibleInSimplifiedForm = false)
public Identifier id;
@EntityDescriptor
@DynamicFieldType(label="Titel")
public String caption;
@DynamicFieldType(label="Beschreibung", editControlType=FieldType.TextArea)
public String description;
@DynamicFieldType(label="Spaltenname")
public String columnname;
@DynamicFieldType(label="Faktentabelle", readOnly = true, visibleInSimplifiedForm = false)
@TableRef(schema = "metadata", table = "facttable", keyField = "id", labelField = "caption")
@Column(value = "facttable_id")
public Identifier factTableId;
@DynamicFieldType(label="Filter", readOnly = true, visibleInSimplifiedForm = false)
@TableRef(schema = "metadata", table = "measure_filter", keyField = "id", labelField = "caption")
@Column(value = "measure_filter_id")
public Identifier measureFilterId;
@DynamicFieldType(label="Aggregationstyp")
@Column(value = "aggregation_type")
public String aggregationType;
@DynamicFieldType(label="Datentyp", readOnly = true, visibleInSimplifiedForm = false)
@Column(value = "measure_type")
public ColumnType measureType;
@DynamicFieldType(label="Auslieferungsversion", visibleInSimplifiedForm = false)
@Column(value = "default_release")
public String defaultRelease;
public MeasureDto() {};
@Override
public boolean canBeCreatedByUser() {
return false;
}
@Override
public boolean canBeDeletedByUser() {
return false;
}
}

61
src/de/superx/bianalysis/repository/dto/MeasureFilterDto.java

@ -0,0 +1,61 @@
package de.superx.bianalysis.repository.dto;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.jdbc.entity.EntityBase;
import de.superx.jdbc.model.DynamicFieldType;
import de.superx.jdbc.model.EntityDescriptor;
import de.superx.rest.model.FieldType;
import de.superx.jdbc.model.TableRef;
@Table(schema = "metadata", value = "measure_filter")
public class MeasureFilterDto extends EntityBase {
@Id
@DynamicFieldType(label="ID", readOnly = true, visibleInSimplifiedForm = false)
public Identifier id;
@EntityDescriptor
@DynamicFieldType(label="Titel")
public String caption;
@DynamicFieldType(label="Beschreibung", editControlType=FieldType.TextArea)
public String description;
@DynamicFieldType(label="Attribute", readOnly = true, visibleInSimplifiedForm = false)
@TableRef(schema = "metadata", table = "dimension_attribute", keyField = "id", labelField = "caption")
@Column(value = "dimension_attribute_id")
public Identifier dimensionAttributeId;
@DynamicFieldType(label="Faktenspalte Filter", readOnly = true)
@Column(value = "fact_column_filter")
public String factColumnFilter;
@DynamicFieldType(label="Einbezogene Werte", readOnly = true)
@Column(value = "included_values")
public String includedValues;
@DynamicFieldType(label="Ausgeschlossene Werte", readOnly = true)
@Column(value = "excluded_values")
public String excludedValues;
@DynamicFieldType(label="Auslieferungsversion", visibleInSimplifiedForm = false)
@Column(value = "default_release")
public String defaultRelease;
public MeasureFilterDto() {}
@Override
public boolean canBeCreatedByUser() {
return false;
}
@Override
public boolean canBeDeletedByUser() {
return false;
}
}

277
src/de/superx/bianalysis/rest/BiAnalysisApi.java

@ -0,0 +1,277 @@
package de.superx.bianalysis.rest;
import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Base64;
import java.util.Date;
import org.apache.log4j.Logger;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import de.superx.bianalysis.ExcelSheetBuilder;
import de.superx.bianalysis.ReportDefinition;
import de.superx.bianalysis.StoredReport;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.models.Dimension;
import de.superx.bianalysis.models.DimensionAttribute;
import de.superx.bianalysis.models.FactTable;
import de.superx.bianalysis.models.Measure;
import de.superx.bianalysis.models.Right;
import de.superx.bianalysis.service.BiAnalysisManager;
import de.superx.bianalysis.service.BiAnalysisRightService;
import de.superx.bianalysis.service.DbMetaAdapter;
import de.superx.common.NotYetImplementedException;
import de.superx.rest.RestControllerBase;
import de.superx.rest.model.Download;
import de.superx.rest.model.Result;
import de.superx.rest.model.ResultType;
import de.superx.rest.model.Row;
@RestController
@RequestMapping("/api/reportwizard")
public class BiAnalysisApi extends RestControllerBase {
/* Autor: Robin Wübbeling
* Achtung: Code ist schnell und unschön zusammengestellt, für einen ersten Entwurf
* TODO: Filter
* TODO: Berechnete Kennzahlen
* TODO: Kennzahlenfilter momentan nur über 1 Dimensionsattribut möglich
* TODO: Strings schöner durch "Platzhalter"
* */
static Logger logger = Logger.getLogger(BiAnalysisApi.class);
@Autowired
DbMetaAdapter dbAdapter;
@Autowired
BiAnalysisRightService rightsService;
@Autowired
BiAnalysisManager biAnalysisManager;
@Override
protected Logger getLogger() {
return logger;
}
@RequestMapping(method = RequestMethod.GET, path = "/facttables")
public List<FactTable> listFactTables() throws NotYetImplementedException {
List<Integer> sachgebiete = rightsService.getSachgebiete(Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
List<Identifier> factTables = rightsService.getFactTables(Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
List<FactTable> facts = dbAdapter.getFactTables(sachgebiete, factTables);
return facts;
}
@RequestMapping(method = RequestMethod.GET, path = "/dimensions")
public List<Dimension> listDimensions(@RequestParam(value = "facttable_id") String facttable_id) {
int sachgebietTid = dbAdapter.getSachgebietByFactTableId(facttable_id);
rightsService.checkSachgebiet(sachgebietTid, Right.CREATE_ANALYSIS);
rightsService.checkFactTable(new Identifier(facttable_id), Right.CREATE_ANALYSIS);
return dbAdapter.getDimensions(new Identifier(facttable_id));
}
// TODO: zeig in benamung does es sich vllt. um eine reduzierte liste handelt
// granted vs allowed
// umstellen auf camel case
@RequestMapping(method = RequestMethod.GET, path = "/dimensionAttributeValues")
public List<String> listAttributeValues (@RequestParam(value = "attribute_id") List<Identifier> attribute_id, @RequestParam(value = "facts") List<Identifier> facts) {
List<Integer> tids = rightsService.getSachgebiete(Right.CREATE_ANALYSIS);
List<Identifier> factTables = rightsService.getFactTables(Right.CREATE_ANALYSIS);
List<DimensionAttribute> attributes = dbAdapter.getAllowedDimensionAttributes(attribute_id, tids, factTables);
return dbAdapter.getDimensionAttributeValues(attributes, facts);
}
@RequestMapping(method = RequestMethod.GET, path = "/dimensionAttributeValuesHierarchy")
public List<List<Object>> listAttributeValuesHierarchy(@RequestParam(value = "attribute_id") String attribute_id) {
rightsService.checkCreateRights();
return dbAdapter.getDimensionAttributeValuesHierarchy(new Identifier(attribute_id));
}
@RequestMapping(method = RequestMethod.GET, path = "/measures")
public List<Measure> listMeasures(@RequestParam(value = "facttable_id") String facttable_id) {
rightsService.checkSachgebiet(dbAdapter.getSachgebietByFactTableId(facttable_id), Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
rightsService.checkFactTable(new Identifier(facttable_id), Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
return dbAdapter.getMeasures(new Identifier(facttable_id));
}
@RequestMapping(method = RequestMethod.GET, path = "/findReportDefinition")
public List<StoredReport> findReportDefinition(
@RequestParam(value = "title") Optional<String> title,
@RequestParam(value = "sach") Optional<Integer> sach,
@RequestParam(value = "facts") Optional<List<String>> facts) {
List<Integer> allowedSachgebiete = rightsService.getSachgebiete(Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
List<Identifier> allowedFacts = rightsService.getFactTables(Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
List<StoredReport> result = new ArrayList<>();
for (StoredReport report : dbAdapter.findAllStoredReports()) {
List<Integer> sachgebieteOfReport = dbAdapter.getSachgebieteForReport(report.reportDefinition);
if (!allowedSachgebiete.isEmpty() && !allowedSachgebiete.containsAll(sachgebieteOfReport)) {
continue;
}
if (title.isPresent()) {
if (!report.name.toLowerCase().contains(title.get().toLowerCase())) {
continue;
}
}
if (sach.isPresent()) {
if (!sachgebieteOfReport.contains(sach.get())) {
continue;
}
}
if(allowedFacts != null && allowedFacts.size() > 0) {
boolean isFactAllowed = true;
for (Identifier reportFactId : report.reportDefinition.factTableIds) {
if(!allowedFacts.isEmpty() && !allowedFacts.contains(reportFactId)) {
isFactAllowed = false;
}
}
if (!isFactAllowed) {
continue;
}
}
if (facts.isPresent()) {
boolean isFactMissing = false;
for (Identifier reportFactId : report.reportDefinition.factTableIds) {
if (!facts.get().contains(reportFactId.composedId)) {
isFactMissing = true;
break;
}
}
if (isFactMissing) {
continue;
}
}
result.add(report);
}
return result;
}
@RequestMapping(method = RequestMethod.GET, path = "/getStoredReport")
public StoredReport getStoredReport(@RequestParam(value = "id") int id) {
Optional<StoredReport> storedReportOpt = dbAdapter.findById(id);
if(storedReportOpt.isPresent()) {
StoredReport storedReport = storedReportOpt.get();
checkCreateOrViewRightForFactTables(storedReport.reportDefinition.factTableIds);
try {
storedReport.exportedResult = biAnalysisManager.createResult(storedReport.reportDefinition, dbAdapter);
} catch (Exception e) {
logger.error("Couldn't create report", e);
e.printStackTrace();
}
storedReport.isReadOnly = Boolean.valueOf(!this.rightsService.isCreateRight());
return storedReport;
}
return null;
}
@RequestMapping(method = RequestMethod.POST, path = "/report")
public Result getReport(@RequestBody final ReportDefinition reportDefinition) throws Exception {
List<Identifier> factTableIds = reportDefinition.factTableIds;
checkCreateRightForFactTables(factTableIds);
return biAnalysisManager.createResult(reportDefinition, dbAdapter);
}
@RequestMapping(method = RequestMethod.POST, path = "/persistReportDefinition")
public int persistReportDefinition(@RequestBody final StoredReport storedReport) throws Exception {
StoredReport.setReportDefinitionJson(storedReport);
List<Identifier> factTableIds = storedReport.reportDefinition.factTableIds;
checkCreateRightForFactTables(factTableIds);
return dbAdapter.saveReportDefinition(storedReport);
}
@RequestMapping(value = "/report/download", method = RequestMethod.POST)
public Download getFile(@RequestBody final StoredReport storedReport) throws Exception {
checkCreateOrViewRightForFactTables(storedReport.reportDefinition.factTableIds);
Date date = new Date();
String fileName = "BI-Analyse_";
if(storedReport.id != 0) {
fileName += dbAdapter.findById(storedReport.id).get().name + "_";
if(fileName.length() > 206) {
fileName = fileName.substring(0, 160);
}
fileName = fileName.replaceAll("[^a-zA-Z0-9äöüÄÖÜß_]+", "_");
}
fileName += new SimpleDateFormat("yyyyMMdd_HHmmss").format(date);
if(!storedReport.exportedResult.resultType.equals(ResultType.FlatTable)) {
Row totalRow = storedReport.exportedResult.getTotalRow();
storedReport.exportedResult.rows = (BiAnalysisManager.hierarchyToRows(storedReport.hierarchy));
storedReport.exportedResult.rows.add(totalRow);
}
XSSFWorkbook workbook = new ExcelSheetBuilder(storedReport.exportedResult)
.withFileName(fileName)
.withReportName(storedReport.name)
.withDescription(storedReport.description)
.withDate(date)
.build();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
workbook.write(bos);
String base64String = Base64.getEncoder().encodeToString(bos.toByteArray());
String contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
return new Download(fileName, contentType, base64String);
}
@RequestMapping(method = RequestMethod.POST, path = "/deleteReportDefinition")
public boolean deleteReportDefinition(@RequestBody final int id) throws Exception {
try {
Optional<StoredReport> reportOpt = dbAdapter.findById(id);
if(reportOpt.isEmpty()) {
throw new Exception("FEHLER: Berichtskonfiguration konnte nicht gefunden werden.");
}
checkCreateRightForFactTables(reportOpt.get().reportDefinition.factTableIds);
dbAdapter.deleteById(id);
return true;
} catch(Exception e) {
throw new Exception("FEHLER: Berichtskonfiguration konnte nicht gelöscht werden.", e);
}
}
@RequestMapping(method = RequestMethod.GET, path = "/reportDefinitions")
public List<StoredReport> listReportDefinitions() throws Exception {
rightsService.checkCreateOrViewRights();
List<StoredReport> storedReports = null;
try {
storedReports = dbAdapter.findAllStoredReports();
// TODO mit Marnie abklären, für überschreiben notwendig?
} catch (Exception e) {
e.printStackTrace();
if (e.getCause().getMessage().contains("FEHLER: Relation »metadata.rw_report_definitions« existiert nicht")) {
throw new NotYetImplementedException("Bitte installieren Sie zuerst die Komponente 'BI-Analyse-Daten' und führen Sie anschließend den Konnektor aus.");
}
throw e;
}
return storedReports;
}
private void checkCreateOrViewRightForFactTables(List<Identifier> factTableIds) {
for (Identifier factId : factTableIds) {
int sachgebiet = dbAdapter.getSachgebietByFactTableId(factId.composedId);
rightsService.checkSachgebiet(sachgebiet, Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
rightsService.checkFactTable(factId, Right.CREATE_ANALYSIS, Right.VIEW_REPORT);
}
}
private void checkCreateRightForFactTables(List<Identifier> factTableIds) {
for (Identifier factId : factTableIds) {
int sachgebiet = dbAdapter.getSachgebietByFactTableId(factId.composedId);
rightsService.checkSachgebiet(sachgebiet, Right.CREATE_ANALYSIS);
rightsService.checkFactTable(factId, Right.CREATE_ANALYSIS);
}
}
}

141
src/de/superx/bianalysis/service/BiAnalysisManager.java

@ -0,0 +1,141 @@
package de.superx.bianalysis.service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import de.superx.bianalysis.ColumnElement;
import de.superx.bianalysis.ColumnElementBuilder;
import de.superx.bianalysis.ReportDefinition;
import de.superx.bianalysis.ReportMetadata;
import de.superx.bianalysis.ResultBuilder;
import de.superx.bianalysis.ResultMerger;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.sqlgeneration.SQLGenerator;
import de.superx.bianalysis.sqlgeneration.SQLGeneratorTotals;
import de.superx.common.NotYetImplementedException;
import de.superx.rest.model.Item;
import de.superx.rest.model.Result;
import de.superx.rest.model.Row;
import de.superx.rest.model.TreeNode;
@Service
public class BiAnalysisManager {
static Logger logger = Logger.getLogger(BiAnalysisManager.class);
@Autowired
BiAnalysisRightService biAnalysisRightService;
public Result createResult(ReportDefinition reportDefinition, DbMetaAdapter dbAdapter) throws Exception {
List<Result> results = new ArrayList<>();
ResultMerger resultMerger = new ResultMerger(dbAdapter);
for (Identifier factTableId : reportDefinition.factTableIds) {
ReportDefinition definition = resultMerger.createFactTableSpecificReportDefinition(reportDefinition, factTableId);
if(definition.leftDimensionAttributeIds.isEmpty() ||
definition.measureIds.isEmpty()) {
continue;
}
try {
biAnalysisRightService.checkCreateOrViewRights();
ReportMetadata metadata = new ReportMetadata(definition, factTableId, dbAdapter);
checkColLimit(reportDefinition, dbAdapter, metadata);
Result reportSegment = getReportData(metadata, dbAdapter);
results.add(reportSegment);
} catch (Exception e) {
logger.error("Couldn't create report", e);
throw e;
}
}
Result result;
if(reportDefinition.factTableIds.size() > 1) {
result = resultMerger.buildMergedReport(reportDefinition, results);
} else {
result = results.get(0);
}
return result;
}
private static void checkColLimit(ReportDefinition reportDefinition, DbMetaAdapter dbAdapter, ReportMetadata metadata) throws NotYetImplementedException {
final int POSTGRES_MAX_COL_LIMIT = 1664;
int resultCols = dbAdapter.getColNumbers(metadata.topDimensionAttributes, metadata.filters);
resultCols *= reportDefinition.measureIds.size();
if(resultCols > POSTGRES_MAX_COL_LIMIT - 1) {
throw new NotYetImplementedException("FEHLER: Ihre Anfrage überschreitet das Spaltenlimit. "
+ "Bitte wählen Sie eine andere Kombination an Attributen.");
}
}
public static String getSqlStatement(ReportDefinition definition, DbMetaAdapter dbAdapter) {
String sqlStatement = "";
ReportMetadata reportMetadata = definition.getReportMetadata(dbAdapter, definition.factTableIds.get(0));
List<ColumnElement> columnElements = ColumnElementBuilder.buildColumnElements(reportMetadata);
SQLGenerator sqlGenerator = new SQLGenerator(reportMetadata, columnElements);
sqlStatement = sqlGenerator.buildSqlStatement();
return sqlStatement;
}
private Result getReportData(ReportMetadata metadata, DbMetaAdapter dbAdapter) throws Exception {
List<ColumnElement> columnElements = ColumnElementBuilder.buildColumnElements(metadata);
List<Item> sqlStatements = new ArrayList<>();
String reportSQL = new SQLGenerator(metadata, columnElements).buildFormattedSqlStatement();
String totalsColumnSQL = SQLGeneratorTotals.generateTotalsColumnSQL(metadata);
sqlStatements.add(new Item("noAggregatesSQL", reportSQL));
sqlStatements.add(new Item("totalsColumnSQL", totalsColumnSQL));
ResultBuilder resultBuilder = new ResultBuilder(dbAdapter.getDataSource());
resultBuilder.setColumnElements(columnElements);
resultBuilder.setReportMetadata(metadata);
Result report = resultBuilder.buildReport(sqlStatements, biAnalysisRightService.isCreateRight());
return report;
}
public static List<Row> hierarchyToRows(ArrayList<TreeNode> hierarchy) {
List<Row> rows = new ArrayList<Row>();
for (TreeNode treeNode : hierarchy) {
nodeToRow(treeNode, rows);
}
return rows;
}
private static List<Row> nodeToRow(TreeNode<Map<String, Object>> treeNode, List<Row> rows) {
splitHierarchyColumn(treeNode);
rows.add(new Row(treeNode.data, true));
for (TreeNode child: treeNode.children) {
List<Row> childRows = nodeToRow(child, rows);
for (Row row : childRows) {
if (!rows.contains(row)){
rows.add(row);
}
}
}
return rows;
}
//Im Treenode wird die Hierarchie in einer Spalte abgebildet, diese muss wieder auf die ursprünglichen Spalten aufgeuteilt werden
private static void splitHierarchyColumn(TreeNode<Map<String, Object>> node) {
String realColumn = node.data.get("column").toString();
if( realColumn.contains(" (Ebene ")) {
String[] splittedString = realColumn.split(" \\(Ebene ");
String mainColumn = splittedString[0];
node.data.put(realColumn, node.data.get(mainColumn));
node.data.put(mainColumn, "");
}
}
public static String getTotalsColumnSqlStatement(ReportDefinition definition, DbMetaAdapter dbAdapter) {
String sqlStatement = "";
ReportMetadata metadata = new ReportMetadata(definition, definition.factTableIds.get(0), dbAdapter);
sqlStatement = SQLGeneratorTotals.generateTotalsColumnSQL(metadata);
return sqlStatement;
}
}

135
src/de/superx/bianalysis/service/BiAnalysisRightService.java

@ -0,0 +1,135 @@
package de.superx.bianalysis.service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.models.Right;
import de.superx.bianalysis.models.RightParam;
import de.superx.common.AccessDeniedException;
import de.superx.common.SxUser;
import de.superx.spring.service.UserService;
@Service()
public class BiAnalysisRightService {
@Autowired
DbMetaAdapter dbAdapter;
@Autowired
UserService userService;
public void checkCreateRights() {
SxUser user = (SxUser) userService.currentUserDetails();
if ( user != null && !user.getHis1Rights().contains("RIGHT_CS_BIA_ANALYSIS_CREATE_ANALYSIS") ) {
throw new AccessDeniedException("No right to access Create functions");
}
}
public boolean isCreateRight() {
SxUser user = (SxUser) userService.currentUserDetails();
if ( user != null && !user.getHis1Rights().contains("RIGHT_CS_BIA_ANALYSIS_CREATE_ANALYSIS") ) {
return false;
}
return true;
}
public void checkCreateOrViewRights() {
SxUser user = (SxUser) userService.currentUserDetails();
if ( user != null && !user.getHis1Rights().contains("RIGHT_CS_BIA_ANALYSIS_CREATE_ANALYSIS") &&
!user.getHis1Rights().contains("RIGHT_CS_BIA_ANALYSIS_VIEW_ANALYSIS_TABLE") ) {
throw new AccessDeniedException("No right to access Create and View functions");
}
}
public List<Integer> getSachgebiete(Right... rights) {
List<String> values = getRightParamValues(RightParam.TOPIC_AREA, rights);
List<String> valuesForTopics = dbAdapter.getSachgebieteForFactTables(getRightParamValues(RightParam.TOPIC, rights));
values.addAll(valuesForTopics);
if (values.isEmpty()) {
return new ArrayList<>();
}
List<Integer> sachgebietValues = values.stream()
.map(Integer::parseInt).collect(Collectors.toList());
return sachgebietValues;
}
public List<Identifier> getFactTables(Right... rights) {
List<String> values = getRightParamValues(RightParam.TOPIC, rights);
if (values.isEmpty()) {
return new ArrayList<>();
}
List<Identifier> factsValues = values.stream()
.map(value -> new Identifier(value)).collect(Collectors.toList());
return factsValues;
}
public void checkSachgebiet(int sachgebiet, Right... rights) {
List<Integer> sachgebiete = getSachgebiete(rights);
if (sachgebiete.isEmpty()) {
return;
} else if (!sachgebiete.contains(Integer.valueOf(sachgebiet))){
throw new AccessDeniedException("No right to access Sachgebiet " + sachgebiet);
}
}
public void checkFactTable(Identifier fact, Right... rights) {
List<Identifier> factTables = getFactTables(rights);
if (factTables.isEmpty()) {
return;
} else if (!factTables.contains(fact)){
throw new AccessDeniedException("No right to access Fact Table " + fact.composedId);
}
}
/**
* Return the values of a RightParam for a given array of Rights.
* @param param RightParam which can be assigned to multiple Rights.
* @param rights Rights which may or may not contain the RightParam.
* @return List of values for the RightParam (first occurrence for multiple Rights).
*/
public List<String> getRightParamValues(RightParam param, Right... rights) {
SxUser user = (SxUser) userService.currentUserDetails();
if(user == null) {
return new ArrayList<>();
}
Map<String, Map<String,String>> rightsMap = user.getRightsMap();
Map<String, String> rightParamMap = null;
boolean noRights = true;
for (Right right : rights) {
if(rightsMap.containsKey(right.getString())) {
rightParamMap = rightsMap.get(right.getString());
noRights = false;
if(rightParamMap != null) {
break;
}
}
}
if(noRights) {
throw new AccessDeniedException("Missing rights: " + Right.getPrintableRights(rights));
}
if(rightParamMap == null || rightParamMap.isEmpty()) {
return new ArrayList<>();
}
String paramValues = rightParamMap.get(param.getString());
if (paramValues != null) {
List<String> paramValuesResult = new ArrayList<>();
for (String string : StringUtils.split(paramValues, ',')) {
paramValuesResult.add(string);
}
return paramValuesResult;
}
return new ArrayList<>();
}
}

637
src/de/superx/bianalysis/service/DbMetaAdapter.java

@ -0,0 +1,637 @@
package de.superx.bianalysis.service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import de.superx.bianalysis.FaultyMetadataException;
import de.superx.bianalysis.ReportDefinition;
import de.superx.bianalysis.ReportMetadata;
import de.superx.bianalysis.StoredReport;
import de.superx.bianalysis.metadata.Identifier;
import de.superx.bianalysis.models.Dimension;
import de.superx.bianalysis.models.DimensionAttribute;
import de.superx.bianalysis.models.FactTable;
import de.superx.bianalysis.models.Filter;
import de.superx.bianalysis.models.Measure;
import de.superx.bianalysis.repository.DimensionAttributeRepository;
import de.superx.bianalysis.repository.DimensionRepository;
import de.superx.bianalysis.repository.FactRepository;
import de.superx.bianalysis.repository.MeasureFilterRepository;
import de.superx.bianalysis.repository.MeasureRepository;
import de.superx.bianalysis.repository.StoredReportRepository;
import de.superx.bianalysis.repository.dto.AttributeDto;
import de.superx.bianalysis.repository.dto.DimensionDto;
import de.superx.bianalysis.repository.dto.FactDto;
import de.superx.bianalysis.repository.dto.MeasureDto;
import de.superx.bianalysis.repository.dto.MeasureFilterDto;
import de.superx.common.NotYetImplementedException;
import de.superx.jdbc.entity.Sachgebiet;
import de.superx.jdbc.entity.Systeminfo;
import de.superx.jdbc.repository.SachgebieteRepository;
import de.superx.jdbc.repository.SysteminfoRepository;
@Service()
public class DbMetaAdapter implements InitializingBean {
@Autowired
FactRepository factRepository;
@Autowired
MeasureRepository measureRepository;
@Autowired
DimensionRepository dimensionRepository;
@Autowired
DimensionAttributeRepository dimensionAttrRepo;
@Autowired
MeasureFilterRepository measureFilterRepo;
@Autowired
StoredReportRepository storedReportRepository;
@Autowired
SachgebieteRepository sachgebieterepository;
@Autowired
SysteminfoRepository systeminfoRepository;
@Autowired
DataSource dataSource;
private JdbcTemplate jt;
@Override
public void afterPropertiesSet() throws Exception {
this.jt = new JdbcTemplate(dataSource);
}
public List<FactTable> getFactTables(List<Integer> sachgebieteTids, List<Identifier> facts) throws NotYetImplementedException {
try {
List<FactTable> factTables = this.factRepository.findAll()
.stream()
.filter(f -> getSachgebietForFacttable(f.sachgebiettid.intValue()).tid.intValue() != -1)
.filter(f -> sachgebieteTids.isEmpty() || sachgebieteTids.contains(Integer.valueOf(f.sachgebiettid.intValue())))
.filter(f -> facts.isEmpty() || facts.contains(f.id) || !hasSachgebietTopicRestrictions(facts, f.sachgebiettid.intValue()) )
.map(f -> {
FactTable fact = new FactTable(f);
fact.setSachgebiet(getSachgebietForFacttable(f.sachgebiettid.intValue()));
fact.setConformedDimensions(getConformedDimensionsForFacttable(f.id));
return fact;
})
.collect(Collectors.toList());
return factTables;
} catch (Exception e) {
e.printStackTrace();
if (e.getCause().getMessage().contains("FEHLER: Relation »metadata.facttable« existiert nicht")) {
throw new NotYetImplementedException("Bitte installieren Sie zuerst die Komponente 'BI-Analyse-Daten' und führen Sie anschließend den Konnektor aus.");
}
throw e;
}
}
private boolean hasSachgebietTopicRestrictions(List<Identifier> facts, int tid) {
for (Identifier factId : facts) {
if(getFactTable(factId).getSachgebiettid() == tid) {
return true;
}
}
return false;
}
public List<Dimension> getConformedDimensionsForFacttable(Identifier factId){
List<Dimension> conformedDimension = new ArrayList<>();
List<Identifier> ids = dimensionRepository.getUsedConformedDimensionsByFactTable(factId.composedId);
for (Identifier id : ids) {
Dimension dimension = getDimension(id);
List<DimensionAttribute> attributes = getAttributesOfDimension(dimension.getId());
dimension.setDimensionAttributes(attributes);
for(DimensionAttribute a : attributes) {
a.setDimension(dimension);
}
conformedDimension.add(getDimension(id));
}
return conformedDimension;
}
public List<DimensionAttribute> getDimensionAttributeMetadata(List<Identifier> attributeIds, Identifier factId) {
if (attributeIds == null || attributeIds.size() <= 0 ) {
return null;
}
List<DimensionAttribute> result = new ArrayList<DimensionAttribute>();
for (Identifier id : attributeIds) {
Optional<AttributeDto> optAttribute = dimensionAttrRepo.findById(id);
if(optAttribute.isEmpty()) {
throw new FaultyMetadataException(id, "Attribute");
}
DimensionAttribute attr = new DimensionAttribute(optAttribute.get());
Dimension dim = null;
if(factId != null) {
// case 1: id is role playing -> rpId is null because the attribute array of the conf dim is not empty
// case 2: id is NOT role playing because the attribute array of the conf dim is empty
Identifier rpId = getRolePlayingDimensionWithNoAttributes(id.composedId, factId.composedId);
if(rpId != null) {
dim = getDimension(rpId);
}
}
if(dim == null) {
dim = getDimension(attr.getDimensionId());
}
attr.setDimension(dim);
if(attr.getAttrConformedId() != null) {
Optional<AttributeDto> optAttributeConf = dimensionAttrRepo.findById(new Identifier(attr.getAttrConformedId()));
if(optAttributeConf.isPresent()) {
Dimension dimConf = getDimension(optAttributeConf.get().dimensionId);
attr.setDimConformedId(dimConf.getId().composedId);
}
}
result.add(attr);
}
return result;
}
public List<Measure> getMeasureMetadata(List<Identifier> measureIds) {
if (measureIds != null && measureIds.size() > 0 ) {
List<Measure> result = new ArrayList<Measure>();
for (Identifier id : measureIds) {
Measure measure = getMeasure(id);
if(measure.getMeasureFilterId() != null) {
MeasureFilterDto filter = measureFilterRepo.findById(measure.getMeasureFilterId()).get();
if(filter.dimensionAttributeId != null) {
DimensionAttribute attribute = getDimensionAttributeById(filter.dimensionAttributeId);
Dimension dimension = getDimension(attribute.getDimensionId());
measure.setMeasureFilterAttributes(filter, attribute, dimension);
} else if(filter.factColumnFilter != null) {
measure.setFactColumnFilter(filter);
}
}
result.add(measure);
}
return result;
}
return null;
}
public List<Dimension> getDimensions(Identifier factTableId) {
List<Dimension> dimensions = new ArrayList<>();
for (DimensionDto dimensionDto : dimensionRepository.findByFactTableId(factTableId)) {
if(dimensionDto.isHidden != null && dimensionDto.isHidden.booleanValue() == true) {
continue;
}
Dimension dimension = new Dimension(dimensionDto);
dimensions.add(dimension);
List<DimensionAttribute> attr = getAttributesOfDimension(dimension.getId());
dimension.setDimensionAttributes(attr);
if(dimension.getConformed() != null) {
Dimension dimConf = getDimension(new Identifier(dimension.getConformed()));
dimension.conformedCaption = dimConf.getCaption();
dimension.conformedDescription = dimConf.getDescription();
if(attr.isEmpty() && !dimension.getConformed().isEmpty()) {
attr = getAttributesOfDimension(new Identifier(dimension.getConformed()));
for( DimensionAttribute a : attr) {
a.setAttrConformedId(a.getStringId());
a.setHierarchy(dimConf.isHierarchy());
}
dimension.setDimensionAttributes(attr);
continue;
}
}
for(DimensionAttribute a : attr) {
if(a.getAttrConformedId() != null) {
DimensionAttribute attribute = getDimensionAttributeById(new Identifier(a.getAttrConformedId()));
a.setConformedCaption(attribute.getCaption());
a.setConformedDescription(attribute.getDescription());
}
a.setDimension(dimension);
}
}
return dimensions;
}
public List<DimensionAttribute> getAllowedDimensionAttributes(List<Identifier> ids, List<Integer> sachgebietTids, List<Identifier> factTables){
List<DimensionAttribute> attributes = new ArrayList<>();
for (Identifier id : ids) {
DimensionAttribute attr = getDimensionAttributeById(id);
Dimension dim = getDimension(attr.getDimensionId());
attr.setDimension(dim);
Optional<FactDto> factOpt = factRepository.findById(dim.getId());
if(factOpt.isPresent()) {
if(!factTables.contains(factOpt.get().id)) {
continue;
}
Integer sachgebiettsTid = Integer.valueOf(factOpt.get().sachgebiettid.intValue());
if(!sachgebietTids.isEmpty() && !sachgebietTids.contains(sachgebiettsTid)) {
continue;
}
}
attributes.add(attr);
}
return attributes;
}
public List<String> getDimensionAttributeValues(List<DimensionAttribute> attributes, List<Identifier> factTables) {
List<String> result = new ArrayList<String>();
List<String> tables = new ArrayList<String>();
for (DimensionAttribute attr : attributes) {
if(tables.contains(attr.getTablename())) {
continue;
}
tables.add(attr.getTablename());
for(Identifier factId : factTables) {
FactTable fact = getFactTable(factId);
Dimension dim = getDimension(attr.getDimensionId());
List<String> values = getDimensionAttributeValues(attr, dim, fact);
result.addAll(values);
}
}
return result;
}
public List<List<Object>> getDimensionAttributeValuesHierarchy(Identifier attribute_id) {
DimensionAttribute attr = getDimensionAttributeById(attribute_id);
Dimension dim = getDimension(attr.getDimensionId());
return getDimensionAttributeValuesHierarchy(attr.getColumnname(), dim.getTablename());
}
public List<Filter> getFilterMetadata(List<Filter> filters) {
for (Filter filter : filters) {
DimensionAttribute attr = getDimensionAttributeById(filter.dimensionAttributeId);
Dimension dim = getDimension(attr.getDimensionId());
attr.setDimension(dim);
filter.setDimension(dim);
filter.setDimensionAttribute(attr);
}
return filters;
}
public List<String> getDimensionAttributeValues(DimensionAttribute attr, Dimension dim, FactTable factTable) {
String sortOrderColumnName = attr.getSortOrderColumn() != null ? attr.getSortOrderColumn(): attr.getColumnname();
String templateSql =
"SELECT DISTINCT d.%s AS value, d.%s, " +
"array_position(array[%s], d.%s::text) " +
"FROM presentation.%s d";
if(dim != null
&& attr.getFilterSelection() != null
&& attr.getFilterSelection().equals("show_existing_only")) {
templateSql += " INNER JOIN presentation." + factTable.getTablename()
+ " f ON d.id = f." + dim.getJoincolumn();
}
templateSql += " WHERE d.%s IS NOT NULL ";
if(dim != null
&& attr.getFilterSelection() != null
&& attr.getFilterSelection().equals("show_range")) {
templateSql += " AND d.id BETWEEN ("
+ "SELECT MIN(" + dim.getJoincolumn() + ")"
+ " FROM presentation." + factTable.getTablename()
+ ") AND ("
+ "SELECT MAX(" + dim.getJoincolumn()
+ " FROM presentation." + factTable.getTablename() + ")";
}
// TODO: sometimes we need DESC
templateSql += " ORDER BY 3, 2 ASC;";
String query = String.format(
templateSql,
attr.getColumnname(),
sortOrderColumnName,
DimensionAttribute.specialValueListForSql(),
attr.getColumnname(),
attr.getTablename(),
attr.getColumnname()
);
List<String> values = jt.query(query, (rs, rowNum) -> rs.getString("value"))
.stream().distinct().collect(Collectors.toList());
return values;
}
public List<List<Object>> getDimensionAttributeValuesHierarchy(String columname, String tablename) {
String query = "select distinct id, parent_id, "+columname+" from presentation." + tablename;
List<List<Object>> values = jt.query(query,
new Object[0],
new RowMapper<List<Object>>() {
@Override
public List<Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
List<Object> result = new ArrayList<>();
result.add(Integer.valueOf(rs.getInt("id")));
result.add(Integer.valueOf(rs.getInt("parent_id")));
result.add(rs.getString(columname));
return result;
}
}
);
return values;
}
public DimensionAttribute getDimensionAttributeMetadataById(Identifier id) {
DimensionAttribute attr = getDimensionAttributeById(id);
Dimension dim = getDimension(attr.getDimensionId());
attr.setDimension(dim);
return attr;
}
public Sachgebiet getSachgebietById(int sachgebietId) {
return this.sachgebieterepository.findById(Integer.valueOf(sachgebietId)).get();
}
public int saveReportDefinition(StoredReport report) {
StoredReport savedStoredReport = this.storedReportRepository.save(report);
return savedStoredReport.id;
}
public int getBridgeMaxLevel(DimensionAttribute bridgeAttr, ReportMetadata metadata) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = buildMaxHierarchyLvlSQL(bridgeAttr, metadata.factTable.getTablename(), metadata.getFilterNoHierarchy(), bridgeAttr.getTablename());
int value = jdbcTemplate.queryForObject(sql, Integer.class).intValue() + 1;
return value;
}
public int getBridgeMaxLevel(DimensionAttribute bridgeAttr, ReportMetadata metadata, String factTableName) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = buildMaxHierarchyLvlSQL(bridgeAttr, factTableName, metadata.getFilterNoHierarchy(), bridgeAttr.getTablename());
int value = jdbcTemplate.queryForObject(sql, Integer.class).intValue() + 1;
return value;
}
public int getBridgeMinLevel(List<Filter> filters, int maxLvl, String dimTable) {
if(filters == null || filters.isEmpty() ) {
return 0;
}
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
List<String> filterValues = new ArrayList<>();
for (Filter filter : filters) {
filterValues.add("ancestor_" + filter.columnname + "[%s] IN ( " + filter.getValues() + " )");
}
for (int i = 0; i < maxLvl; i++) {
String sql = "select count(*) from presentation." + dimTable + "_hierarchy"
+ " where ";
StringJoiner filterJoiner = new StringJoiner(" OR ");
for (String string : filterValues) {
filterJoiner.add(String.format(string, Integer.valueOf(i+1)));
}
sql += filterJoiner.toString();
int value = jdbcTemplate.queryForObject(sql, Integer.class).intValue();
if(value > 0) {
return i;
}
}
return -1;
}
public boolean isAttributeHierarchyBridge(Identifier leftDimensionAttributeId) {
Optional<AttributeDto> dimAttrOpt = this.dimensionAttrRepo.findById(leftDimensionAttributeId);
if(dimAttrOpt.isEmpty()) {
return false;
}
Optional<DimensionDto> dimOpt = this.dimensionRepository.findById(dimAttrOpt.get().dimensionId);
if(dimOpt.isEmpty()) {
return false;
}
if(dimOpt.get().isHierarchy == null) return false;
return dimOpt.get().isHierarchy.booleanValue();
}
public int getColNumbers(List<DimensionAttribute> topDimensionAttributes, List<Filter> filters) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
int num = 1;
for (DimensionAttribute dimensionAttribute : topDimensionAttributes) {
if(filters != null && filters.size() > 0) {
Filter filter = Filter.findFilterById(filters, dimensionAttribute.getId());
if(filter != null && filter.filterValues.size() > 0) {
num *= filter.filterValues.size();
continue;
}
}
String sql = String.format("SELECT count(DISTINCT %s) FROM presentation.%s WHERE %s IS NOT NULL", dimensionAttribute.getColumnname(), dimensionAttribute.getTablename(), dimensionAttribute.getColumnname());
int value = jdbcTemplate.queryForObject(sql, new Object[] {}, Integer.class).intValue();
num *= value;
}
return num;
}
/**
* Given a conformed attribute and a facttable this function determines the following:
*
* Does this conformed attribute belong to a role playing dimension with no attributes ?
*
* If it is the case: return the id of the rp dimension
*/
public Identifier getRolePlayingDimensionWithNoAttributes(String attrId, String factId) {
Identifier confDimId = dimensionRepository.findDimensionIdForAttribute(attrId);
System.out.println(attrId);
List<Identifier> preids = dimensionRepository.getRolePlayingIds(confDimId.composedId, factId);
if(preids.size() == 1) {
return preids.get(0);
} else if (preids.size() > 1) {
throw new RuntimeException("Not yet implemented: Can't use conformed dimension "
+ "more than once for the same facttable.");
}
return null;
}
public Identifier checkIfFactTableHasDimensionAttribute(Identifier conformedAttrId, Identifier fact) {
Identifier rpId = getRolePlayingDimensionWithNoAttributes(conformedAttrId.composedId, fact.composedId);
if(rpId != null) {
return conformedAttrId;
}
List<Identifier> ids = dimensionAttrRepo
.findAttributesByConformedAttributeAndFactTable(conformedAttrId.composedId, fact.composedId);
if (ids.size() == 1) {
return ids.get(0);
} else if (ids.size() > 1) {
throw new FaultyMetadataException("Für die Faktentabelle mit der ID '" + fact.composedId
+ "' existieren zwei Role-Playing Dimensions " + "zugehörig zu der Conformed Dimension mit der ID '"
+ conformedAttrId.composedId + "'. " + "Dieser Fall ist zurzeit noch nicht umgesetzt.");
} else {
Identifier id = dimensionAttrRepo.findAttributesByIdAndFactTable(conformedAttrId.composedId, fact.composedId);
return id;
}
}
public boolean checkIfFactTableHasMeasure(Identifier measure, Identifier fact) {
return factRepository.hasFactTableMeasure(fact.composedId, measure.composedId);
}
public String getLastUpdate(int tid) {
Optional<Systeminfo> systeminfoOpt = systeminfoRepository.findById(Integer.valueOf(tid));
if(systeminfoOpt.isPresent()) {
Date lastUpdate = systeminfoOpt.get().datum;
return new SimpleDateFormat("dd.MM.yyyy hh:mm").format(lastUpdate);
}
return "Unknown";
}
public String getFactTableNameMaxBridgeLvl(Identifier fact, Identifier attr) {
return factRepository.getFactTableNameForAttribute(fact.composedId, attr.composedId);
}
public DataSource getDataSource() {
return this.dataSource;
}
public int getSachgebietByFactTableId(String factTableId) {
Optional<FactDto> fact = this.factRepository.findById(new Identifier(factTableId));
if(fact.isPresent()) {
return fact.get().sachgebiettid.intValue();
}
return -1;
}
public List<Integer> getSachgebieteForReport(ReportDefinition reportDefinition) {
List<Integer> result = new ArrayList<>();
for (Identifier factTableId : reportDefinition.factTableIds) {
int sachgebiet = getSachgebietByFactTableId(factTableId.composedId);
result.add(Integer.valueOf(sachgebiet));
}
return result;
}
public List<StoredReport> findAllStoredReports(){
List<StoredReport> reports = new ArrayList<>();
for (StoredReport report : this.storedReportRepository.findAll()) {
StoredReport.setReportDefinitionFromJson(report);
reports.add(report);
}
return reports;
}
public Optional<StoredReport> findById(int id) {
Optional<StoredReport> report = storedReportRepository.findById(id);
if(report.isPresent()) {
StoredReport.setReportDefinitionFromJson(report.get());
}
return report;
}
public void deleteById(int id) {
storedReportRepository.deleteById(id);
}
private Sachgebiet getSachgebietForFacttable(int sachgebiettid) {
Optional<Sachgebiet> sachgebiet = sachgebieterepository
.findById(Integer.valueOf(sachgebiettid));
if(sachgebiet.isPresent()) {
return sachgebiet.get();
}
return new Sachgebiet(Integer.valueOf(-1), "Unknown", null);
}
public List<String> getSachgebieteForFactTables(List<String> rightParamValues) {
List<String> result = new ArrayList<>();
for (String id : rightParamValues) {
int sachgebiet = getSachgebietByFactTableId(id);
if(sachgebiet != -1) {
result.add(String.valueOf(sachgebiet));
}
}
return result;
}
public List<DimensionAttribute> getAttributesOfDimension(Identifier dimId){
List<AttributeDto> attr = dimensionAttrRepo.findByDimensionId(dimId);
List<DimensionAttribute> attributes = attr.stream()
.map(a -> new DimensionAttribute(a))
.filter(a -> !a.isHidden())
.collect(Collectors.toList());
return attributes;
}
public Dimension getDimension(Identifier id) {
Optional<DimensionDto> dimOpt = dimensionRepository.findById(id);
if(dimOpt.isEmpty()) {
throw new FaultyMetadataException(id, "Dimension");
}
Dimension dimension = new Dimension(dimOpt.get());
return dimension;
}
public Measure getMeasure(Identifier id) {
Optional<MeasureDto> measureOpt = measureRepository.findById(id);
if(measureOpt.isEmpty()) {
throw new FaultyMetadataException(id, "Measure");
}
Measure measure = new Measure(measureOpt.get());
return measure;
}
public DimensionAttribute getDimensionAttributeById(Identifier dimAttrId) {
Optional<AttributeDto> optAttr = this.dimensionAttrRepo.findById(dimAttrId);
if(optAttr.isEmpty()) {
throw new FaultyMetadataException(dimAttrId, "Attribute");
}
return new DimensionAttribute(optAttr.get());
}
public List<Measure> getMeasures(Identifier factTableId) {
List<Measure> measures = new ArrayList<>();
for (MeasureDto measureDto : measureRepository.findByFactTableId(factTableId)) {
measures.add(new Measure(measureDto));
}
return measures;
}
public FactTable getFactTable(Identifier factTableId) {
Optional<FactDto> optFact = factRepository.findById(factTableId);
if(optFact.isEmpty()) {
throw new FaultyMetadataException(factTableId, "Fact");
}
return new FactTable(optFact.get());
}
/**
* Generates the SQL which returns the max depth for a hierarchy.
* (Unfortunately i can't think of a better way to achieve this without relying on additional SQL)
*/
private static String buildMaxHierarchyLvlSQL(DimensionAttribute bridgeAttr, String factTable, List<Filter> filters, String dimTab) {
// TODO: filters
String sql = "SELECT MAX(lvl) "
+ "FROM presentation."+ factTable + " fw "
+ "LEFT JOIN presentation."+dimTab+"_hierarchy h "
+ "ON h." + bridgeAttr.getDimIdJoinColumn() +" = fw."+bridgeAttr.getJoincolumn();
return sql;
}
}

378
src/de/superx/bianalysis/sqlgeneration/SQLGenerator.java

@ -0,0 +1,378 @@
package de.superx.bianalysis.sqlgeneration;
import java.util.List;
import java.util.StringJoiner;
import de.superx.bianalysis.ColumnElement;
import de.superx.bianalysis.ReportMetadata;
import de.superx.bianalysis.models.DimensionAttribute;
import de.superx.bianalysis.models.Filter;
import de.superx.bianalysis.models.Measure;
/**
* Lets consider the following example for the SQL Generation:
*
* Dimensions: X, Y, Z with one attribute each
* Attributes
* - X: DA
* - values: DA1, DA1
* - Y: DB
* - values: DB1, DB1
* - Z: DC
* - values: DC1, DC1
* Measures:
* - M1: count on col_a
* - M2: sum on col_b
*
* For the simplest use case (all attributes and measures selected without any
* filters or bridge tables) the generated table would look like this:
*
* +---------+-----------------------+----------------------+
* | | DA1 | DA2 |
* | |-----------+-----------+-----------+----------+
* | DC | DB1 | DB2 | DB1 | DB2 |
* | |-----+-----+-----+-----+-----+-----+-----+----+
* | | M1 | M2 | M1 | M2 | M1 | M2 | M1 | M2 |
* +=========+=====+=====+=====+=====+=====+=====+=====+====+
* | DC1 | | | | | | | | |
* +---------+-----+-----+-----+-----+-----+-----+-----+----+
* | DC2 | | | | | | | | |
* +---------+-----+-----+-----+-----+-----+-----+-----+----+
*
* and the generated SQL would look like this:
*
* SELECT
* DC,
* COUNT(col_a) FILTER (WHERE DA = 'DA1' AND DB = 'DB1') as "col0",
* SUM(col_b) FILTER (WHERE DA = 'DA1' AND DB = 'DB1') as "col1",
* COUNT(col_a) FILTER (WHERE DA = 'DA1' AND DB = 'DB2') as "col2",
* SUM(col_b) FILTER (WHERE DA = 'DA1' AND DB = 'DB2') as "col3",
* COUNT(col_a) FILTER (WHERE DA = 'DA2' AND DB = 'DB1') as "col4",
* SUM(col_b) FILTER (WHERE DA = 'DA2' AND DB = 'DB1') as "col5",
* COUNT(col_a) FILTER (WHERE DA = 'DA2' AND DB = 'DB2') as "col6",
* SUM(col_b) FILTER (WHERE DA = 'DA2' AND DB = 'DB2') as "col7"
* FROM
* presentation.fact_table
* JOIN presentation.dim_a
* ON fact_table.dim_a = dim_a.id
* JOIN presentation.dim_b
* ON fact_table.dim_b = dim_b.id
* JOIN presentation.dim_a
* ON fact_table.dim_c = dim_c.id
* GROUP BY dim_c.DC
*
*
* !! Special Cases:
*
* 1. Filtering Attributes
* User Filtered to see only DA with values DA1.
* In this case the select section would shrink to the following four columns:
*
* COUNT(col_a) FILTER (WHERE DA = 'DA1' AND DB = 'DB1') as "col0",
* SUM(col_b) FILTER (WHERE DA = 'DA1' AND DB = 'DB1') as "col1",
* COUNT(col_a) FILTER (WHERE DA = 'DA1' AND DB = 'DB2') as "col2",
* SUM(col_b) FILTER (WHERE DA = 'DA1' AND DB = 'DB2') as "col3",
* COUNT(col_a) FILTER (WHERE DA = 'DA2' AND DB = 'DB1') as "col4"
*
* and the following where clause would be appended:
*
* WHERE dim_a.DA IN ('DA1')
*
* 2. Measures with Build-In-Filter
* Consider the measure M1 should only count the values DA1 of attribute DA.
* In this case the filter condition is prepended to the selection section
* of the specific columns for this measure:
*
* COUNT(col_a) FILTER (WHERE col_a IN ('DA1') AND DA = 'DA1' AND DB = 'DB1') as "col0",
* ...
* COUNT(col_a) FILTER (WHERE col_a IN ('DA1') AND DA = 'DA1' AND DB = 'DB2') as "col2",
* ...
* COUNT(col_a) FILTER (WHERE col_a IN ('DA1') AND DA = 'DA2' AND DB = 'DB1') as "col4",
* ...
* COUNT(col_a) FILTER (WHERE col_a IN ('DA1') AND DA = 'DA2' AND DB = 'DB2') as "col6",
* ...
*
* The filter condition for a measure can be either an IN or NOT IN condition.
*
*/
public class SQLGenerator {
public ReportMetadata reportMetadata;
public List<ColumnElement> columnElements;
public char formatSql = ' ';
private final static String HIERARCHY_MODEL_SUFFIX = "_hierarchy";
public SQLGenerator(ReportMetadata reportMetadata, List<ColumnElement> columnElements) {
this.reportMetadata = reportMetadata;
this.columnElements = columnElements;
}
public SQLGenerator(ReportMetadata reportMetadata) {
this.reportMetadata = reportMetadata;
}
public String buildFormattedSqlStatement() {
formatSql = '\n';
return buildSqlStatement();
}
public String buildSqlStatement() {
StringBuilder statement = new StringBuilder();
statement.append("SELECT ");
statement.append(buildSelectSection());
statement.append(formatSql + "FROM presentation." + reportMetadata.factTable.getTablename() );
statement.append(buildJoinSection());
statement.append(buildFilterSection());
statement.append(buildGroupBySection());
statement.append(buildOrderBySection());
return statement.toString();
}
public String buildSelectSection() {
StringJoiner columns = new StringJoiner(", ");
String dimensionAttributesStatement = selectDimensionAttributes();
if (dimensionAttributesStatement != null && !dimensionAttributesStatement.isBlank() ) {
columns.add(dimensionAttributesStatement);
}
StringJoiner measuresStatementJoiner = new StringJoiner(", ");
columnElements.forEach((columnElement) -> {
measuresStatementJoiner.add(selectMeasure(columnElement));
});
String measuresStatement = measuresStatementJoiner.toString();
if (measuresStatement != null && !measuresStatement.isBlank()) {
columns.add(measuresStatement);
}
return columns.toString();
}
public String selectDimensionAttributes() {
if (reportMetadata.leftDimensionAttributes == null) {
return null;
}
StringJoiner columns = new StringJoiner(", ");
for (DimensionAttribute attribute : reportMetadata.leftDimensionAttributes) {
String columnName = attribute.getColumnname();
String tableAlias = attribute.getDimensionTableAlias();
String columnAlias = attribute.getDimensionColumnAlias();
if(attribute.isHierarchy()) {
// Build select expressions for each hierarchy level (ancestor node),
// assigning aliases col0, col1, etc.
StringBuilder resultBuilder = new StringBuilder();
for (int i = reportMetadata.minBridgeLvl; i < reportMetadata.maxBridgeLvl; i++) {
resultBuilder
.append(attribute.getDimensionTableAlias())
.append(".ancestor_")
.append(columnName)
.append('[').append(i + 1).append(']')
.append(" AS \"col").append(i).append("\"");
if (i < reportMetadata.maxBridgeLvl - 1) {
resultBuilder.append(", ");
}
}
columns.add(resultBuilder.toString());
} else {
columns.add(String.format("%s.%s AS %s", tableAlias, columnName, columnAlias));
String sortOrderColumn = attribute.getSortOrderColumn();
if (sortOrderColumn != null) {
columns.add(String.format("%s.%s AS %s_%s",
tableAlias, sortOrderColumn, columnAlias, sortOrderColumn));
}
}
}
return columns.toString();
}
public String getMeasureTablePart(String factTableTablename, Measure measure, List<DimensionAttribute> dimensionAttributes) {
String result = "";
String tableCol = factTableTablename + "." + measure.getColumnname();
if(measure.getAggregationType().equals("sum")) {
result = "SUM(" + tableCol + ")";
} else if (measure.getAggregationType().equals("count")) {
result = "COUNT(" + tableCol + ")";
} else if (measure.getAggregationType().equals("distinct-count")) {
result = "COUNT(distinct(" + tableCol + "))";
} else if (measure.getAggregationType().equals("avg")) {
result = "AVG(" + tableCol + ")";
} else if (measure.getAggregationType().equals("min")) {
result = "MIN(" + tableCol + ")";
} else if (measure.getAggregationType().equals("max")) {
result = "MAX(" + tableCol + ")";
} else if (measure.getAggregationType().equals("std")) {
result = "STDDEV_SAMP(" + tableCol + ")";
} else if (measure.getAggregationType().equals("var")) {
result = "VAR_SAMP(" + tableCol + ")";
}
return result;
}
public String selectMeasure(ColumnElement columnElement) {
String factTableTablename = reportMetadata.factTable.getTablename();
StringBuilder measureSelect = new StringBuilder();
Measure measure = columnElement.measure;
measureSelect.append(getMeasureTablePart(factTableTablename, measure, reportMetadata.leftDimensionAttributes));//todo topdimen hinzufügen
if ( measure.filterCondition != null ) {
// if there exists a filter condition for a specific measure, prepend it to the column filter condition
measureSelect.append(formatSql+ "FILTER (WHERE " + measure.filterCondition);
if (columnElement.dimensionAttributeFilter != null) {
measureSelect.append(" AND " + columnElement.dimensionAttributeFilter);
}
measureSelect.append(")");
} else if (columnElement.dimensionAttributeFilter != null) {
measureSelect.append(formatSql + "FILTER (WHERE " + columnElement.dimensionAttributeFilter + ")");
}
if (measureSelect.length() != 0) {
measureSelect.append(" AS \"col" + columnElement.columnNumber + "\"");
}
return measureSelect.toString();
}
public String buildJoinSection() {
StringBuilder statement = new StringBuilder();
for (DimensionAttribute attr : reportMetadata.getUniqueDimensionAttributes()) {
String joinColumn = "id";
if( attr.getDimIdJoinColumn() != null
&& !attr.getDimIdJoinColumn().isBlank()) {
// Hierarchy dimension models must always be joined on an id column.
// See the "hierarchy_dim.sql" dbt macro for implementation details.
// For other models, the default join column can be customized in the metadata JSON files
// using the "id_column" attribute.
joinColumn = attr.getDimIdJoinColumn();
}
String dimensionTable = attr.getTablename();
boolean isTopAttribute = reportMetadata.topDimensionAttributes.contains(attr);
if(attr.isHierarchy() && !isTopAttribute) {
// Hierarchy dimension tables use a dedicated join suffix.
// For example, dim_orgunit is joined as dim_orgunit_hierarchy.
// This hierarchy table contains all node paths in the hierarchy tree.
// For additional details, see the "hierarchy_dim.sql" macro.
dimensionTable += HIERARCHY_MODEL_SUFFIX;
}
String join = String.format(
" JOIN presentation.%s AS %s ON %s.%s = %s.%s",
dimensionTable,
attr.getDimensionTableAlias(),
reportMetadata.factTable.getTablename(),
attr.getJoincolumn(),
attr.getDimensionTableAlias(),
joinColumn
);
statement.append(join);
/* TODO userinput for histroical keys:
1. is_current
2. last_known
3. specific date: (ANY_DATE BETWEEN %s.valid_from AND %s.valid_to)
*/
if(attr.isHistorical()) {
String currentFilter = String.format(
" AND %s.is_current = true ",
attr.getDimensionTableAlias()
);
statement.append(currentFilter);
}
}
return statement.toString();
}
public String buildFilterSection() {
if (reportMetadata.filters == null || reportMetadata.filters.size() <= 0) {
return "";
}
StringBuilder statement = new StringBuilder(" WHERE ");
StringJoiner groups = new StringJoiner(" AND ");
for (Filter filter : reportMetadata.filters) {
if(reportMetadata.isHierarchyFilter(filter)) {
StringBuilder resultBuilder = new StringBuilder();
for (int i = reportMetadata.minBridgeLvl; i < reportMetadata.maxBridgeLvl; i++) {
resultBuilder
.append(filter.joincolumn)
.append(".ancestor_")
.append(filter.columnname)
.append('[').append(i).append("] IN (")
.append(filter.getValues())
.append(')');
if (i < reportMetadata.maxBridgeLvl - 1) {
resultBuilder.append(" OR ");
}
}
groups.add(resultBuilder.toString());
} else {
groups.add(filter.dimensionTableAlias + "." + filter.columnname + " IN (" + filter.getValues() + ")");
}
}
statement.append(groups.toString());
if(groups.length() == 0) {
return "";
}
return statement.toString();
}
public String buildGroupBySection() {
if(reportMetadata.leftDimensionAttributes == null || reportMetadata.leftDimensionAttributes.size() <= 0) {
return "";
}
StringBuilder statement = new StringBuilder("GROUP BY ROLLUP (");
StringJoiner groups = new StringJoiner(", ");
for (DimensionAttribute attr : reportMetadata.leftDimensionAttributes) {
if(attr.isHierarchy()) {
// TODO: what is happening here?
int numOfHierarchyAttributes = reportMetadata.getHierarchyAttributes().size();
for (int i = 0; i < numOfHierarchyAttributes; i++) {
for (int j = 0; j < reportMetadata.maxBridgeLvl; j++) {
if(j < reportMetadata.minBridgeLvl) {
continue;
}
groups.add("col"+(j + (i * reportMetadata.maxBridgeLvl)));
}
}
} else {
groups.add(attr.getDimensionTableAlias() + "." + attr.getColumnname());
if(attr.getSortOrderColumn() != null) {
groups.add(attr.getDimensionTableAlias() + "." + attr.getSortOrderColumn());
}
}
}
statement.append(groups.toString());
if(groups.length() == 0) {
return "";
}
statement.append(")");
return formatSql + statement.toString();
}
public StringJoiner buildOrderBySection() {
StringJoiner orderCols = new StringJoiner(", ", " ORDER BY ", "");
orderCols.setEmptyValue("");
for (DimensionAttribute attr : reportMetadata.leftDimensionAttributes) {
if(attr.isHierarchy()) {
for (int i = reportMetadata.minBridgeLvl; i < reportMetadata.maxBridgeLvl; i++) {
orderCols.add("col" + i);
}
continue;
}
if(attr.getSortOrderColumn() != null) {
orderCols.add(attr.getDimensionTableAlias() + "." + attr.getSortOrderColumn());
} else {
orderCols.add(attr.getDimensionColumnAlias());
}
}
return orderCols;
}
}

82
src/de/superx/bianalysis/sqlgeneration/SQLGeneratorTotals.java

@ -0,0 +1,82 @@
package de.superx.bianalysis.sqlgeneration;
import java.util.List;
import java.util.StringJoiner;
import de.superx.bianalysis.ReportMetadata;
import de.superx.bianalysis.models.DimensionAttribute;
import de.superx.bianalysis.models.Filter;
import de.superx.bianalysis.models.Measure;
public class SQLGeneratorTotals {
public SQLGeneratorTotals() {}
public static String buildTotalsColumnSQL(SQLGenerator generator, int maxBridgeLvlOfReport) {
ReportMetadata metadata = generator.reportMetadata;
StringBuilder statement = new StringBuilder();
statement.append("SELECT ");
statement.append(buildSelectSectionForTotalsCol(generator, metadata, maxBridgeLvlOfReport));
statement.append(generator.formatSql + "FROM presentation." + metadata.factTable.getTablename() );
statement.append(generator.buildJoinSection());
statement.append(buildFilterSectionForTotalsCol(generator, metadata));
statement.append(generator.buildGroupBySection());
return statement.toString();
}
private static String buildFilterSectionForTotalsCol(SQLGenerator generator, ReportMetadata metadata) {
if(metadata.topDimensionAttributes.size() == 0 && metadata.filters.size() == 0) {
return "";
}
StringBuilder where = new StringBuilder(" WHERE ");
StringJoiner groups = new StringJoiner(" AND ");
for (DimensionAttribute attribute : metadata.topDimensionAttributes) {
groups.add(attribute.getDimensionTableAlias() + "." + attribute.getColumnname() + " IN (" + getValues(attribute.getDimensionAttributeValues()) + ")");
}
for (Filter filter : generator.reportMetadata.filters) {
groups.add(filter.dimensionTableAlias + "." + filter.columnname + " IN (" + filter.getValues() + ")");
}
where.append(groups);
return where.toString();
}
private static String buildSelectSectionForTotalsCol(SQLGenerator generator, ReportMetadata metadata, int maxBridgeLvlOfReport) {
StringJoiner columns = new StringJoiner(", ");
columns.add(generator.selectDimensionAttributes());
//columns.add(metadata.aggregationLvl + " AS aggregationLvl");
int numCols = generator.reportMetadata.maxBridgeLvl;
for (Measure measure : metadata.measures) {
String value = generator.getMeasureTablePart(metadata.factTable.getTablename(), measure, metadata.leftDimensionAttributes);
if ( measure.filterCondition != null ) {
value += " FILTER (WHERE " + measure.filterCondition +")";
}
value += " AS \"col" + (numCols++) + "\"";
columns.add(value);
}
String selectSection = columns.toString();
return selectSection;
}
private static String getValues(List<String> values) {
if(values == null || values.isEmpty()) {
return null;
}
StringJoiner joiner = new StringJoiner(", ");
for (String value : values) {
joiner.add("'"+value+"'");
}
return joiner.toString();
}
public static String generateTotalsColumnSQL(ReportMetadata metadata) {
if(metadata.topDimensionAttributes.isEmpty()) {
return "";
}
SQLGenerator generator = new SQLGenerator(metadata);
String finalSQL = buildTotalsColumnSQL(generator, metadata.maxBridgeLvl)
+ generator.buildOrderBySection();
return finalSQL;
}
}

433
src/de/superx/bin/AbstractWebserviceClient.java

@ -2,16 +2,27 @@ package de.superx.bin;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter; import java.io.StringWriter;
import java.net.Authenticator; import java.net.Authenticator;
import java.net.PasswordAuthentication; import java.net.PasswordAuthentication;
import java.net.Authenticator.RequestorType;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import java.util.regex.Pattern;
import javax.xml.soap.MessageFactory; import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders; import javax.xml.soap.MimeHeaders;
@ -19,25 +30,55 @@ import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory; import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage; import javax.xml.soap.SOAPMessage;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.OutputKeys; import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer; import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import de.memtext.util.DateUtils; import de.memtext.util.DateUtils;
import de.memtext.util.StringUtils; import de.memtext.util.StringUtils;
import de.memtext.util.XMLUtils; import de.memtext.util.XMLUtils;
import de.superx.util.SqlStringUtils;
public class AbstractWebserviceClient { public class AbstractWebserviceClient {
int pause = 0; int pause = 0;
boolean isDeleteTmpXmlFileWanted = true; boolean isDeleteTmpXmlFileWanted = true;
private XMLInputFactory factory = XMLInputFactory.newInstance();
public AbstractWebserviceClient() { protected String auth = null;
protected final static String DATUMSPATTERN = "(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)";
protected static final Logger logger = Logger.getLogger("wc");
// String test="PVC-U T-St&#xFC;ck 90&#xB0;, 3fach Klebemu&#xDBC0;&#xDC01;e";
private static final Pattern INVALID_XML_PATTERN=Pattern.compile("[^\\u0009\\u000A\\u000D\\u0020-\\uD7FF\\uE000-\\uFFFD\\u10000-\\u10FFF]+");
private static final String XSLT_REMOVE_NAMESPACE = "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n" +
" <xsl:output method=\"xml\" />\n" +
" <xsl:template match=\"*\">\n" +
" <xsl:element name=\"{local-name()}\">\n" + // Neuen Namen ohne Namespace erstellen
" <xsl:apply-templates select=\"@*|node()\"/>\n" +
" </xsl:element>\n" +
" </xsl:template>\n" +
" <xsl:template match=\"@*\">\n" +
" <xsl:attribute name=\"{local-name()}\"><xsl:value-of select=\".\"/></xsl:attribute>\n" +
" </xsl:template>\n" +
"</xsl:stylesheet>";
private Transformer transformerRemoveNamespace;
public AbstractWebserviceClient() {
String a = System.getProperty("SOAP-AUTH");
if (a != null && !a.equals(""))
auth = a;
Authenticator.setDefault(new Authenticator() { Authenticator.setDefault(new Authenticator() {
@Override @Override
protected PasswordAuthentication getPasswordAuthentication() { protected PasswordAuthentication getPasswordAuthentication() {
@ -46,21 +87,44 @@ public class AbstractWebserviceClient {
String host = System.getProperty(prot + ".proxyHost", ""); String host = System.getProperty(prot + ".proxyHost", "");
String port = System.getProperty(prot + ".proxyPort", ""); String port = System.getProperty(prot + ".proxyPort", "");
String user = System.getProperty(prot + ".proxyUser", ""); String user = System.getProperty(prot + ".proxyUser", "");
String password = System.getProperty(prot String password = System.getProperty(prot + ".proxyPassword", "");
+ ".proxyPassword", "");
if (getRequestingHost().toLowerCase().equals( if (getRequestingHost().toLowerCase().equals(host.toLowerCase())) {
host.toLowerCase())) {
if (Integer.parseInt(port) == getRequestingPort()) { if (Integer.parseInt(port) == getRequestingPort()) {
// Seems to be OK. // Seems to be OK.
return new PasswordAuthentication(user, password return new PasswordAuthentication(user, password.toCharArray());
.toCharArray());
} }
} }
} }
return null; return null;
} }
}); });
}
protected static String adaptDatePattern(String input) {
input=input.replaceAll("0000-00-00","");
return input.replaceAll(DATUMSPATTERN, "$3.$2.$1");
}
/**
* Macht Probleme <AEDAT>
* </AEDAT> wird zu Leerzeichen/WhiteSpace -> Probleme beim CSV-Import im Copy
* Liefert Formatiertes Ergebnis <SOAP:Header/><SOAP:Body> wird durch Ersetzung
* zu <SOAP:Header/> <SOAP:Body> Der 2. regex ist für den SEHR
* unwahrscheinlichen Fall, dass innerhalb eines Eintrags selbst als Fehleingabe
* ein >< vorkommen würde, der überflüssige, bei CSV evtl Fehler verursachende
* Newline wird wieder entfernt. z.B. <BUCHUNGSTEXT> Kauf von XY >< zum
* Rabattpreis</BUCHUNGSTEXT>
*
* @param input
* @return formatted String
*/
protected String format(String input) {
// return input.replaceAll("><", ">\n<").replaceAll("(<.*>\n)(.*>)\n(<.*)(</.*>\n)", "$1$2$3$4");
return input.replaceAll("<Envelope","\n<Envelope");
} }
/** /**
@ -71,80 +135,113 @@ public class AbstractWebserviceClient {
* @return * @return
* @throws Exception * @throws Exception
*/ */
protected StringBuffer readSOAP(String soapxml, String url) protected StringBuffer readSOAP(String soapxml, String url) throws Exception {
throws Exception {
int attempt = 1; int attempt = 1;
boolean allDone = false; boolean allDone = false;
StringWriter sw = null;
Exception exception = null; Exception exception = null;
StringBuffer result = new StringBuffer();
while (allDone == false && attempt < 4) { while (allDone == false && attempt < 4) {
try { try {
sw = new StringWriter();
if (pause > 0) { if (pause > 0) {
Thread.sleep(pause * 1000); Thread.sleep(pause * 1000);
// System.out.println("pause "+pause);
} }
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
.newInstance(); SOAPConnection soapConnection = soapConnectionFactory.createConnection();
SOAPConnection soapConnection = soapConnectionFactory
.createConnection();
SOAPMessage sr = getSoapMessageFromString(soapxml); SOAPMessage sr = getSoapMessageFromString(soapxml);
sr.getMimeHeaders().addHeader("SOAPAction", sr.getMimeHeaders().addHeader("SOAPAction", "http://sap.com/xi/WebService/soap1.1");
"http://sap.com/xi/WebService/soap1.1");
addAuthentification(sr);
SOAPMessage soapResponse = soapConnection.call(sr, url); SOAPMessage soapResponse = soapConnection.call(sr, url);
// soapResponse.writeTo(System.out); result.append(extractString(soapResponse));
Transformer transformer = TransformerFactory.newInstance()
.newTransformer();
// optional indenting
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "2");
// File tmpF = File.createTempFile("soapdata", ".xml");
transformer.transform(
new DOMSource(soapResponse.getSOAPPart()),
new StreamResult(sw));
soapConnection.close(); soapConnection.close();
System.gc(); System.gc();
// if (attempt < 3) throw new RuntimeException("RUntime"); if (result.indexOf("<Fault>") > -1)
// StringBuffer result=readFile(tmpF); throw new IllegalStateException("Webservice meldet Fehler - kein Netzwerkproblem:\n" + result);
// if (isDeleteTmpXmlFileWanted) tmpF.delete();
// else System.out.println(" tmp File "+tmpF);
allDone = true; allDone = true;
} catch (Exception e) { } catch (Exception e) {
exception = e; exception = e;
System.out System.out.println(
.println(DateUtils.getNowString() DateUtils.getNowString() + " Aufruf fehlgeschlagen (s. WebserviceLog) - versuche erneut");
+ " Aufruf fehlgeschlagen (s. WebserviceLog) - versuche erneut");
StringWriter swException = new StringWriter(); StringWriter swException = new StringWriter();
PrintWriter pw = new PrintWriter(swException); PrintWriter pw = new PrintWriter(swException);
e.printStackTrace(pw); e.printStackTrace(pw);
Logger.getLogger("wc").severe( Logger.getLogger("wc")
" Problem bei Aufruf von " + url + "\n" + soapxml .severe(" Problem bei Aufruf von " + url + "\n" + soapxml + "\n" + swException.toString());
+ "\n" + swException.toString());
attempt++; attempt++;
} }
} }
if (allDone == false) if (allDone == false)
throw exception; throw exception;
StringBuffer result = new StringBuffer(sw.toString());
return result;
}
protected boolean isReplyOk(StringBuffer data) throws SAXException, IOException {
boolean result = false;
Document resultDocument = XMLUtils.buildDocumentFromString(data, false);
if (XMLUtils.hasANodeWithName(resultDocument, "TYPE")) {
Node type = XMLUtils.getFirstNode(resultDocument, "TYPE");
if (XMLUtils.getTheValue(type).equals("I"))
result = true;
}
return result; return result;
} }
protected File createSoapFile(String soapxml, String url) throws Exception { private String extractString(SOAPMessage soapResponse) throws SOAPException, IOException, TransformerException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
soapResponse.writeTo(out);
String strMsg = new String(out.toByteArray());
//replace ungültige XML-Hex-Entities im High Surrogate Bereich #324507
strMsg=replaceHighSurrogates(strMsg);
StringWriter writer = new StringWriter();
if (transformerRemoveNamespace==null)
{
initTransformerNamespace();
}
transformerRemoveNamespace.transform(new StreamSource(new StringReader(strMsg)), new StreamResult(writer));
//Transformer macht zwar Einrücken/indent wird aber unten bei purge wegen optionellem Auftreten in Buchungskommentaren wieder entfernt
strMsg= writer.toString();
return strMsg;
}
private void initTransformerNamespace() throws TransformerConfigurationException, TransformerFactoryConfigurationError {
transformerRemoveNamespace=TransformerFactory.newInstance().newTransformer((new StreamSource(new StringReader(XSLT_REMOVE_NAMESPACE))));
transformerRemoveNamespace.setOutputProperty(OutputKeys.INDENT, "yes");
transformerRemoveNamespace.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","2");
//ident wird zwar gemacht, aber da \n in
}
protected File createSoapFile(String soapxml, String url) throws Exception {
int attempt = 1; int attempt = 1;
boolean allDone = false; boolean allDone = false;
// Logging von Saaj abschalten
// vergl.
// http://www.docjar.com/html/api/com/sun/xml/internal/messaging/saaj/client/p2p/HttpSOAPConnection.java.html
// Logger.getLogger(LogDomainConstants.HTTP_CONN_DOMAIN,
// "com.sun.xml.internal.messaging.saaj.client.p2p.LocalStrings").setLevel(Level.OFF);
// Die Konstante wird bei Build nicht gefunden, entspricht aber einem festen
// String
// System.out.println(LogDomainConstants.HTTP_CONN_DOMAIN);
// in OpenJDK und geergänzenden jars nicht mehr aktiv
// sicherheitshalber
try {
Logger.getLogger("com.sun.xml.internal.messaging.saaj.client.p2p",
"com.sun.xml.internal.messaging.saaj.client.p2p.LocalStrings").setLevel(Level.OFF);
} catch (Exception e) {
}
Exception exception = null; Exception exception = null;
File tmpF = File.createTempFile("soapdata", ".xml"); File tmpF = File.createTempFile("soapdata", ".xml");
while (allDone == false && attempt < 4) { while (allDone == false && attempt < 5) {
try { try {
if (tmpF.exists()) if (tmpF.exists())
tmpF.delete(); tmpF.delete();
@ -153,45 +250,33 @@ public class AbstractWebserviceClient {
Thread.sleep(pause * 1000); Thread.sleep(pause * 1000);
// System.out.println("pause "+pause); // System.out.println("pause "+pause);
} }
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
.newInstance(); SOAPConnection soapConnection = soapConnectionFactory.createConnection();
SOAPConnection soapConnection = soapConnectionFactory
.createConnection();
SOAPMessage sr = getSoapMessageFromString(soapxml); SOAPMessage sr = getSoapMessageFromString(soapxml);
sr.getMimeHeaders().addHeader("SOAPAction", sr.getMimeHeaders().addHeader("SOAPAction", "http://sap.com/xi/WebService/soap1.1");
"http://sap.com/xi/WebService/soap1.1"); addAuthentification(sr);
SOAPMessage soapResponse = soapConnection.call(sr, url); SOAPMessage soapResponse = soapConnection.call(sr, url);
Transformer transformer = TransformerFactory.newInstance() String strMsg = extractString(soapResponse);
.newTransformer(); Files.writeString(tmpF.toPath(), strMsg, StandardOpenOption.CREATE);
// optional indenting
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(
new DOMSource(soapResponse.getSOAPPart()),
new StreamResult(tmpF));
soapConnection.close(); soapConnection.close();
System.gc(); System.gc();
// if (attempt<3) throw new RuntimeException("runtime");
allDone = true; allDone = true;
} catch (Exception e) { } catch (Exception e) {
exception = e; exception = e;
System.out System.out.println("\n" + DateUtils.getNowString()
.println("\n" + " Aufruf fehlgeschlagen (s. WebserviceLog) - versuche erneut");
+ DateUtils.getNowString()
+ " Aufruf fehlgeschlagen (s. WebserviceLog) - versuche erneut");
StringWriter swException = new StringWriter(); StringWriter swException = new StringWriter();
PrintWriter pw = new PrintWriter(swException); PrintWriter pw = new PrintWriter(swException);
e.printStackTrace(pw); e.printStackTrace(pw);
Logger.getLogger("wc").severe( Logger.getLogger("wc").severe(" Problem bei Webservice Abruf\n" + url + "\n" + soapxml
" Problem bei Aufruf von " + url + "\n" + soapxml + swException.toString()
+ "\n" + swException.toString()); + (attempt < 4 ? " versuche erneut:\n" : " zu viele Fehlschlaege - gebe frustriert auf"));
attempt++; attempt++;
} }
@ -201,35 +286,140 @@ public class AbstractWebserviceClient {
return tmpF; return tmpF;
} }
private SOAPMessage getSoapMessageFromString(String xml) protected SOAPMessage getSoapMessageFromString(String xml) throws SOAPException, IOException {
throws SOAPException, IOException {
MessageFactory factory = MessageFactory.newInstance(); MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory SOAPMessage message = factory.createMessage(new MimeHeaders(),
.createMessage( new ByteArrayInputStream(xml.getBytes(Charset.forName("UTF-8"))));
new MimeHeaders(),
new ByteArrayInputStream(xml.getBytes(Charset
.forName("UTF-8"))));
return message; return message;
} }
protected String removeXmlHeader(String input) {
return input.replaceAll("<\\?xml.*\\?>", "");
}
/**
* High Surrogate Bereich durch ? ersetzen
* @param input
* @return
*/
public static String replaceHighSurrogates(String input)
{
StringBuffer buf=new StringBuffer(input);
final int codePointStringBegin = 3;
final boolean hex = true;
int pos = buf.indexOf("&#x");
String replacer="?";
while (pos > -1) {
int posSemikolon = buf.indexOf(";", pos);
if (posSemikolon > -1) {
String encodedString = buf.substring(pos, posSemikolon + 1);
// Hex-Wert bis zum Semikolon
String encodedHex = encodedString.substring(codePointStringBegin, encodedString.length() - 1);
//System.out.println("replace " + encodedHex);
try {
int decimalNumber = Integer.parseInt(encodedHex, hex ? 16 : 10);
if (decimalNumber>=55296) // high surrogate Bereich ersetzen
{
buf.replace(pos, posSemikolon+1, replacer);
//replacer = new String(Character.toChars(decimalNumber));
}
} catch (NumberFormatException e) {
}
}
else
{
//Sicherheitshalber aus while Schleife aussteigen, falls nach &#x
// kein darauf folgendes Semikolon gefunden wurde
break;
}
pos = buf.indexOf("&#x",pos+1);
}
return buf.toString();
}
/** /**
* Entferne unnötige Zeichen und EX_JEST Block * Entferne unnötige Zeichen und EX_JEST Block falls gewünscht
* *
* @param data * @param data
* @param removeJest
* @return * @return
*/ */
static String purge(String data) { static String purge(String data, boolean removeJest) {
data = XMLUtils.removeTroublesomeCharacters(data); data = XMLUtils.removeTroublesomeCharacters(data);
data = data.replaceAll("\u20AC", "EUR"); data = data.replaceAll("\u20AC", "EUR");
data = data.replaceAll("&#x20ac;", "EUR");
data = data.replaceAll("\u2013", "-");// dash data = data.replaceAll("&#x20AC;", "EUR");
// dash
data = data.replaceAll("\u2026", "...");// ... data = data.replaceAll("\u2013", "-");
data = data.replaceAll("&#x2013;", "-");
// horizontal elipse ...
data = data.replaceAll("\u2026", "...");
data = data.replaceAll("&#x2026;", "...");
// großes scharfes ß durch kleines ersetzen #324507
data = data.replaceAll("\u1e9e", "ß");
data = data.replaceAll("&#x1e9e;", "ß");
// MB 30.3.2022 Zeilenumbrüche,Tabs,typogr. Apostroph entfernen HS Karlsruhe
data = data.replace("´","'");
data = data.replaceAll("\t"," ");
data = data.replaceAll("\r\n"," ");
data = data.replaceAll("\n"," ");
data = StringUtils.decodeHexEncodingInString(data);
// typographische durch einfache Anführungszeichen #317130
data=StringUtils.removeTypographischeZeichen(data);
// bei ISO-Codierung Ligaturen wie Dach auf c entfernen, da diese teils damit
// nicht dargestellt werden können
// vergl. https://en.wikipedia.org/wiki/%C4%8C oder
// https://www.codetable.net/decimal/269 )
if (!SqlStringUtils.getEncoding().contentEquals("UTF-8")) {
data = StringUtils.removeAllButUmlauts(data);
// MB weitere Problematische Zeichen
data = data.replaceAll("¼","1/4");
data = data.replaceAll("½","1/2");
data = data.replaceAll("¾","3/4");
data = replaceInvalidChars(data);
}
data = data.replace('^', ' '); data = data.replace('^', ' ');
data = data.replaceAll("<EX_JEST>(?s).*</EX_JEST>", ""); // #324507 Entfernen von problematischen Zeichen
data = data.replaceAll("<EX_JEST></EX_JEST>", ""); //Teststring am Ende xDCB0/1 : PVC-U T-St&#xFC;ck 90&#xB0;, 3fach Klebemu&#xDBC0;&#xDC01;e";
data = data.replaceAll("<EX_JEST/>", ""); data=INVALID_XML_PATTERN.matcher(data).replaceAll("?");
if (removeJest) {
data = purge(data, "EX_JEST");
}
return data;
}
private static String replaceInvalidChars(String input) {
StringBuilder result = new StringBuilder();
for (char c : input.toCharArray()) {
if (isValidISO88591Char(c)) {
result.append(c);
} else {
result.append('?');
}
}
return result.toString();
}
private static boolean isValidISO88591Char(char c) {
// ISO-8859-1 enthält Zeichen von 0x00 bis 0xFF
return c >= 0x00 && c <= 0xFF;
}
static String purge(String data, String nodename) {
data = data.replaceAll("<" + nodename + ">(?s).*</" + nodename + ">", "");
data = data.replaceAll("<" + nodename + "></" + nodename + ">", "");
data = data.replaceAll("<" + nodename + "/>", "");
return data; return data;
} }
@ -240,18 +430,79 @@ public class AbstractWebserviceClient {
return result; return result;
} }
private StringBuffer readFile(File f) throws IOException { protected void addAuthentification(SOAPMessage sr) {
if (auth != null) {
sr.getMimeHeaders().addHeader("Authorization", "Basic " + auth);
}
}
protected StringBuffer readFile(File f) throws IOException {
FileReader fr = new FileReader(f); FileReader fr = new FileReader(f);
BufferedReader bfr = new BufferedReader(fr); BufferedReader bfr = new BufferedReader(fr);
String line; String line;
StringBuffer result = new StringBuffer(); StringBuffer result = new StringBuffer();
while ((line = bfr.readLine()) != null) { while ((line = bfr.readLine()) != null) {
result.append(line + "\n"); result.append(line + "\n");
} }
bfr.close(); bfr.close();
fr.close(); fr.close();
return result; return result;
} }
protected boolean isReplyOk(File f) throws XMLStreamException, IOException {
InputStream in = new FileInputStream(f);
XMLStreamReader parser = factory.createXMLStreamReader(in);
boolean checkReturn = false;
String result = "";
while (parser.hasNext()) {
switch (parser.getEventType()) {
case XMLStreamConstants.START_ELEMENT:
if (parser.getLocalName().equals("RETURN")) {
checkReturn = true;
}
break;
case XMLStreamConstants.CHARACTERS:
if (checkReturn && !parser.isWhiteSpace()) {
result = parser.getText();
checkReturn = false;
}
break;
case XMLStreamConstants.END_DOCUMENT:
parser.close();
break;
}
parser.next();
}
in.close();
return result.equals("I");
}
protected void initLogging() throws SecurityException, IOException {
//hier bewusst separates java.util.Logging für Shellaufrufe
Handler handler = new FileHandler("WebserviceClient.log",100000*1024,1,true);
handler.setFormatter(new SimpleFormatter()
{
@Override
public String format(LogRecord l) {
String result =
DateUtils.getTodayString() + " " + DateUtils.getNowString()
+ ":" + l.getMessage() + "\n";
return result;
}
@Override
public String formatMessage(LogRecord l) {
return format(l);
}
});
Logger.getLogger("wc").addHandler(handler);
logger.setLevel(Level.FINEST);
}
} }

510
src/de/superx/bin/ComponentAdminCLI.java

@ -0,0 +1,510 @@
package de.superx.bin;
import static de.superx.servlet.SxSQL_Server.DEFAULT_MANDANTEN_ID;
import java.io.File;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.batch.core.ExitStatus;
import org.springframework.beans.BeansException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import de.superx.job.ContainerNode;
import de.superx.rest.EtlJobApi;
import de.superx.rest.model.job.Component;
import de.superx.rest.model.job.JobExecutionStatus;
import de.superx.rest.model.job.StepExecutionStatus;
import de.superx.servlet.SuperXManager;
import de.superx.servlet.SxPools;
import de.superx.spring.HisInOneConfiguration;
import de.superx.spring.batch.His1DataSources;
import de.superx.spring.cli.config.CLIConfig;
import de.superx.spring.config.BatchConfig;
import de.superx.spring.config.DataJdbcConfiguration;
import de.superx.spring.config.ServiceConfig;
import de.superx.spring.service.BatchJobDescriptionAdapter;
import de.superx.spring.service.EntityJobDescriptionSource;
import de.superx.util.PathAndFileUtils;
/***
* This class provides functionality to run the component actions of the
* 'modernized component administration'
* of the HISinOne-BI via command line. That includes
* - listing ETL jobs
* - installing components
* - updating components
* - deinstalling components
* - running "Hauptladeroutine" ETL jobs
* - running "Unterladeroutine" ETL jobs
* The class is just meant to be a frontend, so it uses the same implementation as the web application
* (which happens to be the "EtlJobApi" bean)
* However, there are to be some things to be considered:
* - The "jobLauncher" bean from the "BatchConfig" class works asynchronously, which is fine for the
* web application context, but in the CLI context, it is overridden by a synchronous implementation
* (in fact the tweaks to get the configurations ready for the CLI context, are placed in the
* "CLIConfig" class).
* - In the web application context, the HISinOne-BI code in the HISinOne web application writes the
* database configuration to a file, which is then consumed by the "superx" application (the actual
* HISinOne-BI application). The command line application needs this file too, so before using it, you
* should start the web application one time, in order to have the file in place.
* @author witt
*
*/
public class ComponentAdminCLI {
private static GenericApplicationContext APPLICATION_CONTEXT = null;
private static String HELP_STRING = "Use this tool to run component actions via command line. "
+ "It needs the config file 'his1_databases.properties' inside the classpath; "
+ "this file gets written automatically when starting the web application.";
private static boolean FILESYSTEM = false;
static Logger logger = Logger.getLogger(ComponentAdminCLI.class);
public static void main(String[] args) {
BasicConfigurator.configure(); // initializes console logging to stdout
System.setProperty(SuperXManager.SUPER_X_HISINONE_VERSION, "non-empty-value");
Options options = createOptions();
CommandLine parsedArgs = parseArgs(args, options);
logOptions(parsedArgs);
if (parsedArgs.hasOption("h")) {
printHelp(options);
System.exit(0);
}
if(parsedArgs.hasOption("f")) {
FILESYSTEM = true;
}
initSuperXManager();
if(parsedArgs.hasOption("s")) {
initTablesForEmptyDB();
}
if(parsedArgs.hasOption("lg")) {
setBatchLoggerToOneFile();
}
SuperXManager.initKettleEnv(createContext());
if (parsedArgs.hasOption("la")) {
printAllJobs();
} else if (parsedArgs.hasOption("li")) {
printInstallableJobs();
} else if (parsedArgs.hasOption("le")) {
printEtlJobs();
} else if (parsedArgs.hasOption("i")) {
installComponents(parsedArgs);
} else if (parsedArgs.hasOption("d")) {
deinstallComponent(parsedArgs);
} else if (parsedArgs.hasOption("u")) {
upgradeComponents(parsedArgs);
} else if (parsedArgs.hasOption("ua")) {
upgradeAll();
} else if (parsedArgs.hasOption("e")) {
etlJobs(parsedArgs);
} else if (parsedArgs.hasOption("r")) {
reloadModule();
} else if (parsedArgs.hasOption("if")) {
installFunctions(parsedArgs);
} else {
printHelp(options);
}
}
private static void logOptions(CommandLine parsedArgs) {
logger.info("Starting with the following options:");
for (Option opt : parsedArgs.getOptions()) {
logger.info(opt);
if(opt.getValues() != null && opt.getValues().length > 0) {
logger.info("Values for option " + opt.getOpt() + ": " + Arrays.asList(opt.getValues()));
}
}
}
private static void initTablesForEmptyDB() {
try {
GenericApplicationContext context = createContext();
EtlJobApi componentApi = context.getBean(EtlJobApi.class);
ContainerNode root = EntityJobDescriptionSource.getPreKernInstallJob();
componentApi.executeJob("eduetl", root);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void setBatchLoggerToOneFile() {
try {
GenericApplicationContext context = createContext();
BatchJobDescriptionAdapter bjda = context.getBean(BatchJobDescriptionAdapter.class);
bjda.setLogJobToFile(false);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void installComponents(CommandLine parsedArgs) {
String[] components = parsedArgs.getOptionValues("i");
String currentComp = null;
try (GenericApplicationContext context = createContext()) {
initSxPools();
EtlJobApi componentApi = context.getBean(EtlJobApi.class);
for (String comp : components) {
try {
currentComp = comp;
Long jobStartStatus = Long.valueOf(-1);
if(!FILESYSTEM) {
logger.info("EXECUTING: install job from database");
jobStartStatus = componentApi.executeInstall(comp);
} else {
// disable mondrian step
logger.info("EXECUTING: install job from filesystem for " + currentComp);
jobStartStatus = componentApi.executeInstallForQAMuster(comp);
logger.info("EXECUTING: workaround upgrade job from filesystem for " + currentComp);
jobStartStatus = componentApi.executeUpgradeForQAMuster(comp);
}
handleStartResult(jobStartStatus, componentApi);
if(comp.equals("kern") && FILESYSTEM) {
DataSource dataSource = context.getBean(His1DataSources.class).get("eduetl");
SuperXManager.setWebInfFilePath(dataSource);
}
} catch (Exception e) {
logger.error("ERROR installing component " + comp, e);
}
}
} catch (BeansException be) {
handleBeansException(be);
} catch (Exception e) {
handleJobException(e, currentComp);
}
}
private static void reloadModule() {
try (GenericApplicationContext context = createContext()){
initSxPools();
initSuperXManager();
EtlJobApi componentApi = context.getBean(EtlJobApi.class);
componentApi.writeJobsToDb();
}
}
private static void printHelp(Options options) {
HelpFormatter help = new HelpFormatter();
help.printHelp(HELP_STRING, options);
}
private static void printInstallableJobs() {
try (GenericApplicationContext context = createContext()) {
EtlJobApi componentApi = context.getBean(EtlJobApi.class);
List<Component> installJobs = componentApi.getInstallJobs();
for (Component comp : installJobs) {
printDetails(comp);
System.out.println();
}
}
}
private static void printEtlJobs() {
try (GenericApplicationContext context = createContext()) {
EtlJobApi componentApi = context.getBean(EtlJobApi.class);
List<Component> etlJobs = componentApi.getEtlJobs();
for (Component etlJob : etlJobs) {
printDetails(etlJob);
System.out.println();
}
}
}
private static void printDetails(Component comp) {
System.out.println("abbrev: " + comp.getAbbreviation());
System.out.println("name: " + comp.getName());
System.out.println("database: " + comp.getDatabase());
System.out.println("systeminfo_id: " + comp.getSysteminfoId());
System.out.println("installed: " + comp.isInstalled());
}
private static void deinstallComponent(CommandLine parsedArgs) {
String comp = parsedArgs.getOptionValue("d");
System.out.println(comp);
try (GenericApplicationContext context = createContext()) {
initSxPools();
EtlJobApi componentApi = context.getBean(EtlJobApi.class);
Long jobStartStatus = componentApi.executeUninstall(comp);
handleStartResult(jobStartStatus, componentApi);
} catch (BeansException be) {
handleBeansException(be);
} catch (Exception e) {
handleJobException(e, comp);
}
}
private static void upgradeComponents(CommandLine parsedArgs) {
String[] components = parsedArgs.getOptionValues("u");
String currentComp = null;
try (GenericApplicationContext context = createContext()) {
initSxPools();
EtlJobApi componentApi = context.getBean(EtlJobApi.class);
for (String comp : components) {
currentComp = comp;
Long jobStartStatus = componentApi.executeUpgrade(comp);
if (jobStartStatus.longValue() == -1) {
logger.warn(comp + " not installed. Skipping upgrade.");
continue;
}
handleStartResult(jobStartStatus, componentApi);
}
} catch (BeansException be) {
handleBeansException(be);
} catch (Exception e) {
handleJobException(e, currentComp);
}
}
private static void installFunctions(CommandLine parsedArgs) {
String[] components = parsedArgs.getOptionValues("if");
try (GenericApplicationContext context = createContext()) {
initSxPools();
EtlJobApi componentApi = context.getBean(EtlJobApi.class);
// No components given: install
// functions for all installed components
if (components.length == 1 && "all".equals(components[0])) {
List<Component> installedComponents = componentApi.getInstallJobs();
components = installedComponents.stream().map(
c -> c.getAbbreviation()).collect(Collectors.toList()).toArray(new String[] {});
}
boolean exitFailure = false;
for (String comp : components) {
componentApi.installModuleFunctions(comp);
}
if(exitFailure) {
System.out.println(("Beim Ausführen einer Aktion ist ein Fehler aufgetreten:"));
System.exit(1);
}
} catch (BeansException be) {
handleBeansException(be);
}
}
private static void upgradeAll() {
try (GenericApplicationContext context = createContext()) {
initSxPools();
EtlJobApi componentApi = context.getBean(EtlJobApi.class);
Long jobStartStatus = componentApi.executeUpgradeAll();
handleStartResult(jobStartStatus, componentApi);
} catch (BeansException be) {
handleBeansException(be);
} catch (Exception e) {
handleJobException(e, null);
}
}
private static void etlJobs(CommandLine parsedArgs) {
String[] jobIds = parsedArgs.getOptionValues("e");
String currentJobId = null;
try (GenericApplicationContext context = createContext()) {
initSxPools();
EtlJobApi componentApi = context.getBean(EtlJobApi.class);
Long jobStartStatus;
for (String jobId : jobIds) {
try {
currentJobId = jobId;
if (isHauptladeroutine(jobId, componentApi)) {
jobStartStatus = componentApi.complete(jobId);
} else if (isLoadTransform(jobId, componentApi)) {
jobStartStatus = componentApi.load(jobId);
} else {
jobStartStatus = componentApi.executeJob(null, jobId);
}
handleStartResult(jobStartStatus, componentApi);
} catch (Exception e) {
logger.error("ERROR executing job " + jobId, e);
}
}
} catch (BeansException be) {
handleBeansException(be);
} catch (Exception e) {
handleJobException(e, currentJobId);
}
}
private static void handleStartResult(Long jobStartStatus, EtlJobApi componentApi) {
if (jobStartStatus.intValue() == -1) {
System.err.println("Aktion konnte nicht gestartet werden: Es läuft bereits eine Aktion");
}
try {
JobExecutionStatus es = componentApi.getStatus(jobStartStatus);
if ("FAILED".equals(es.exitStatus.getExitCode())) {
EtlJobApi.outputErrorSummary(es, System.err);
}
} catch (Exception e) {
System.err.println(("Beim Ausführen der Aktion ist ein Fehler aufgetreten:"));
e.printStackTrace();
}
}
private static void handleJobException(Exception e, String jobName) {
System.err.println("error while executing the job '" + jobName + "'");
e.printStackTrace();
}
private static void handleBeansException(BeansException be) {
System.err.println("configuration error or error with resolving the bean '" + EtlJobApi.class.getCanonicalName() + "'");
be.printStackTrace();
}
private static boolean isHauptladeroutine(String comp, EtlJobApi etlJob) {
List<Component> installJobs = etlJob.getEtlJobs();
for (Component comp_meta : installJobs) {
if (comp_meta != null && comp_meta.getAbbreviation().equals(comp) && comp_meta.isDatabaseConnected()) {
return true;
}
}
return false;
}
private static boolean isLoadTransform(String comp, EtlJobApi etlJob) {
List<Component> installJobs = etlJob.getEtlJobs();
for (Component comp_meta : installJobs) {
if (comp_meta != null && comp_meta.getAbbreviation().equals(comp) && !comp_meta.isDatabaseConnected()) {
return true;
}
}
return false;
}
private static void printAllJobs() {
try (GenericApplicationContext context = createContext()) {
EtlJobApi etlJob = context.getBean(EtlJobApi.class);
List<ContainerNode> allJobs = etlJob.getAllJobs();
for (ContainerNode cn : allJobs) {
printDetails(cn);
System.out.println();
}
}
}
private static GenericApplicationContext createContext() {
/*
* https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/AnnotationConfigApplicationContext.html
* quote:
* "In case of multiple @Configuration classes, @Bean methods defined in later classes will override those defined in earlier classes.
* This can be leveraged to deliberately override certain bean definitions via an extra @Configuration class."
* - so it's alright to override some beans via "CLIConfig"
*/
if (APPLICATION_CONTEXT == null) {
APPLICATION_CONTEXT = new AnnotationConfigApplicationContext(BatchConfig.class, DataJdbcConfiguration.class, CLIConfig.class, ServiceConfig.class);
HisInOneConfiguration.configSuperXDbformsXML("pg", SuperXManager.getWEB_INFPfad() + File.separator + "..");
}
// Override the JobDescriptionSource Bean if the -f flag is passed.
if(FILESYSTEM) {
EtlJobApi etlJob = APPLICATION_CONTEXT.getBean(EtlJobApi.class);
EntityJobDescriptionSource entityJobDescriptionSource = APPLICATION_CONTEXT.getBean(EntityJobDescriptionSource.class);
etlJob.setJobDescriptionSource(entityJobDescriptionSource);
}
return APPLICATION_CONTEXT;
}
private static void printDetails(ContainerNode cn) {
System.out.println("id: " + cn.id);
System.out.println("name: " + cn.name);
System.out.println("systeminfo_id: " + cn.systemInfoId);
System.out.println("tid: " + cn.tid);
System.out.println("type: " + cn.type);
}
private static Options createOptions() {
Options options = new Options();
Option opt;
opt = new Option("h", "help", false, "get help");
options.addOption(opt);
opt = new Option("f", "filesystem", false, "load jobs from filesystem");
options.addOption(opt);
opt = new Option("s", "setup", false, "setup minimal list of tables necessary for kern install");
options.addOption(opt);
opt = new Option("la", "list-all", false, "list all available components");
options.addOption(opt);
opt = new Option("li", "list-installables", false, "list all installable components");
options.addOption(opt);
opt = new Option("le", "list-etl", false, "list all etl components");
options.addOption(opt);
opt = new Option("i", "install", true, "install components");
opt.setArgs(Option.UNLIMITED_VALUES);
options.addOption(opt);
opt = new Option("if", "install-functions", true, "install database functions for components (use 'all' to install functions for all installed components)");
options.addOption(opt);
opt.setArgs(Option.UNLIMITED_VALUES);
opt = new Option("d", "deinstall", true, "de-/uninstall component");
options.addOption(opt);
opt = new Option("u", "upgrade", true, "upgrade components");
opt.setArgs(Option.UNLIMITED_VALUES);
options.addOption(opt);
opt = new Option("ua", "upgrade-all", false, "upgrade all installed components");
options.addOption(opt);
opt = new Option("e", "etl", true, "run etl jobs");
opt.setArgs(Option.UNLIMITED_VALUES);
options.addOption(opt);
opt = new Option("r", "reload-modules", false, "reload modules");
options.addOption(opt);
//opt = new Option("re", "reload-module-etl", true, "reload module etl");
//options.addOption(opt);
opt = new Option("db", "database", true, "database system");
options.addOption(opt);
opt = new Option("lg", "log-to-stdout", false, "log only to stdout and not to individual job files");
options.addOption(opt);
return options;
}
private static CommandLine parseArgs(String[] args, Options options) {
CommandLineParser parser = new GnuParser();
try {
return parser.parse(options, args, false);
} catch (ParseException e) {
System.out.println("error while reading the command line parameters:");
e.printStackTrace();
System.exit(1);
}
return null;
}
// some actions require the SuperXManager, this is the place for initializing its static class attributes when needed
private static void initSuperXManager() {
try {
SuperXManager.setWEB_INFPfad(PathAndFileUtils.getWebinfPath());
SuperXManager.setModuleDir(PathAndFileUtils.getWebinfPath() + File.separator + PathAndFileUtils.MODULE_PATH);
} catch(Exception e) {
System.out.println("error while initialising the SuperXManger:");
e.printStackTrace();
System.exit(1);
}
}
// sxPools need to be initialized, because spring batch ETL uses them to look up the database connections
private static void initSxPools() {
try {
List<String> mandantenNamen = new LinkedList<String>();
mandantenNamen.add(DEFAULT_MANDANTEN_ID);
SxPools.closeAll();
SxPools.init(mandantenNamen);
SxPools.get(DEFAULT_MANDANTEN_ID).init();
SxPools.get(DEFAULT_MANDANTEN_ID).initLogging(true, Level.DEBUG);
// also init kettle env, set plugin dir
SuperXManager.initKettleEnv(APPLICATION_CONTEXT);
} catch (Exception e) {
System.out.println("error while initialising the SuperX pools:");
e.printStackTrace();
System.exit(1);
}
}
}

674
src/de/superx/bin/DataProfiler.java

@ -0,0 +1,674 @@
package de.superx.bin;
import static de.superx.servlet.SxSQL_Server.DEFAULT_MANDANTEN_ID;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.JDBCType;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import javax.sql.DataSource;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFDataFormat;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.RowMapper;
import de.superx.servlet.SuperXManager;
import de.superx.servlet.SxPools;
import de.superx.spring.batch.His1DataSources;
import de.superx.spring.cli.config.CLIConfig;
import de.superx.spring.config.BatchConfig;
import de.superx.spring.config.DataJdbcConfiguration;
import de.superx.spring.config.ServiceConfig;
/**
* A utility for creating data profiling statistics for tables in a database
* to be used in Data Warehouse Design.
* This can be used as a command line utility or embedded in an application.
*/
public class DataProfiler {
private final static String SQL_COUNT_NULL = "select count(*) from %s where %s is null";
private final static String SQL_PERCENT_UNIQUE = "select\n"
+ " count(distinct %s) as unique_anz,\n"
+ " count(distinct %s)::float / count(*) * 100 as unique_percentage\n"
+ "from\n"
+ " %s;";
private final static String SQL_RANKING = "select %s, count(*) as anz from %s where %s is not null group by %s order by 2 desc limit 10;";
private final static String SQL_MIN_MAX_LEN = "select min(length(%s)) as min_length, max(length(%s)) as max_length\n"
+ "from %s\n"
+ "where %s is not null";
private final static String SQL_COUNT_VALUE = "select count(*) from %s where %s = %s";
private final static String SQL_MIN_MAX_AVG = "select min(%s), max(%s), avg(%s) from %s where %s is not null;";
private final static String SQL_START_END = "select min(%s), max(%s) from %s where %s is not null";
private static GenericApplicationContext APPLICATION_CONTEXT = null;
private static String HELP_STRING = "Use this tool to profile database tables for dwh design. "
+ "It needs the config file 'his1_databases.properties' inside the classpath; "
+ "this file gets written automatically when starting the web application.";
static Logger logger = Logger.getLogger(DataProfiler.class);
private DataSource dataSource;
private String database;
private String schema;
private String[] tables;
/**
* Instantiate a new DataProfiler.
* @param dataSource The DataSource from which to read the table statistics.
* @param schema The schema from which to read. If null public is assumed.
* @param tables An Array of the names of the tables for which statistics should be created.
*/
public DataProfiler(DataSource dataSource, String schema, String[] tables) {
try (Connection con = dataSource.getConnection()) {
this.database = con.getCatalog();
} catch (SQLException e) {
logger.error("Couldn't read catalog", e);
}
this.schema = schema != null ? schema : "public";
List<String> tableList = Arrays.asList(tables);
// TODO: Make sorting configurable?
tableList.sort(null);
this.tables = tableList.toArray(new String[] {});
this.dataSource = dataSource;
}
public static void main(String[] args) {
System.setProperty(SuperXManager.SUPER_X_HISINONE_VERSION, "non-empty-value");
Options options = createOptions();
CommandLine parsedArgs = parseArgs(args, options);
if (parsedArgs.hasOption("h")) {
printHelp(options);
System.exit(0);
}
String database = null;
String schema = "public";
String[] tables = null;
if (parsedArgs.hasOption("d")) {
database = parsedArgs.getOptionValue('d');
}
if (parsedArgs.hasOption("s")) {
schema = parsedArgs.getOptionValue('s');
}
if (parsedArgs.hasOption("t")) {
tables = parsedArgs.getOptionValues('t');
}
if (!parsedArgs.hasOption('d') || !parsedArgs.hasOption('t')) {
printHelp(options);
System.exit(0);
}
try (GenericApplicationContext context = createContext()) {
initSxPools();
DataSource dataSource = context.getBean(His1DataSources.class).get(database);
DataProfiler profiler = new DataProfiler(dataSource, schema, tables);
profiler.outputExcel(profiler.createStatistics(), null);
}
}
/**
* Create the List of TableStatistics.
* @return List of TableStatistics.
*/
public List<TableStatistic> createStatistics() {
List<TableStatistic> tableStats = new ArrayList<>();
try {
JdbcTemplate jt = new JdbcTemplate(dataSource);
logger.info("Database: " + database);
logger.info("Schema: " + schema);
logger.info("Tables: " + Arrays.asList(tables));
try (Connection con = dataSource.getConnection()) {
jt.execute("set search_path to " + schema);
DatabaseMetaData meta = con.getMetaData();
for (String table : tables) {
long rowCount = jt.queryForObject("select count(*) from " + table, Long.class).longValue();
TableStatistic tableStat = new TableStatistic(table, rowCount);
logger.info("Table " + table);
try(ResultSet columns = meta.getColumns(null, schema, table, null);
ResultSet exported = meta.getExportedKeys(null, schema, table);
ResultSet imported = meta.getImportedKeys(null, schema, table);
ResultSet pks = meta.getPrimaryKeys(null, schema, table)) {
while(columns.next()) {
ColumnStatistic columnStat = new ColumnStatistic();
columnStat.name = columns.getString("COLUMN_NAME");
columnStat.size = columns.getInt("COLUMN_SIZE");
columnStat.decimalDigits = columns.getInt("DECIMAL_DIGITS");
columnStat.type = JDBCType.valueOf(columns.getInt("DATA_TYPE"));
columnStat.comment = columns.getString("REMARKS");
columnStat.isNullable = columns.getString("IS_NULLABLE").equalsIgnoreCase("yes");
columnStat.isAutoincrement = columns.getString("IS_AUTOINCREMENT").equalsIgnoreCase("yes");
columnStat.countNull = jt.queryForObject(String.format(SQL_COUNT_NULL, tableStat.name, columnStat.name), Long.class).longValue();
columnStat.percentNull = (double) columnStat.countNull / (double) tableStat.rowCount * 100.0;
jt.query(String.format(SQL_PERCENT_UNIQUE, columnStat.name, columnStat.name, tableStat.name), new RowCallbackHandler() {
@Override
public void processRow(ResultSet rs) throws SQLException {
columnStat.uniqueCount = rs.getLong(1);
columnStat.uniquePercent = rs.getDouble(2);
}
});
columnStat.ranking = jt.query(String.format(SQL_RANKING, columnStat.name, tableStat.name, columnStat.name, columnStat.name), new RowMapper<RankingEntry>() {
@Override
public RankingEntry mapRow(ResultSet rs, int rowNum) throws SQLException {
return new RankingEntry(rs.getString(1), rs.getInt(2));
}
});
switch (columnStat.type) {
case CHAR:
case NCHAR:
case VARCHAR:
case NVARCHAR:
case LONGVARCHAR:
case LONGNVARCHAR:
jt.query(String.format(SQL_MIN_MAX_LEN, columnStat.name, columnStat.name, tableStat.name, columnStat.name), new RowCallbackHandler() {
@Override
public void processRow(ResultSet rs) throws SQLException {
columnStat.minLen = Optional.of(Integer.valueOf(rs.getInt(1)));
columnStat.maxLen = Optional.of(Integer.valueOf(rs.getInt(2)));
}
});
columnStat.min_count = Optional.of(jt.queryForObject(String.format(SQL_COUNT_VALUE, tableStat.name,
"length(" + columnStat.name + ")", columnStat.minLen.get()), Integer.class));
columnStat.max_count = Optional.of(jt.queryForObject(String.format(SQL_COUNT_VALUE, tableStat.name,
"length(" + columnStat.name + ")", columnStat.maxLen.get()), Integer.class));
break;
case BIGINT:
case DECIMAL:
case DOUBLE:
case FLOAT:
case INTEGER:
case REAL:
case NUMERIC:
case SMALLINT:
case TINYINT:
jt.query(String.format(SQL_MIN_MAX_AVG, columnStat.name, columnStat.name, columnStat.name, tableStat.name, columnStat.name), new RowCallbackHandler() {
@Override
public void processRow(ResultSet rs) throws SQLException {
columnStat.min = Optional.of(Double.valueOf(rs.getDouble(1)));
columnStat.max = Optional.of(Double.valueOf(rs.getDouble(2)));
columnStat.avg = Optional.of(Double.valueOf(rs.getDouble(3)));
}
});
columnStat.min_count = Optional.of(jt.queryForObject(String.format(SQL_COUNT_VALUE, tableStat.name, columnStat.name, columnStat.min.get()), Integer.class));
columnStat.max_count = Optional.of(jt.queryForObject(String.format(SQL_COUNT_VALUE, tableStat.name, columnStat.name, columnStat.max.get()), Integer.class));
break;
case DATE:
jt.query(String.format(SQL_START_END, columnStat.name, columnStat.name, tableStat.name, columnStat.name), new RowCallbackHandler() {
@Override
public void processRow(ResultSet rs) throws SQLException {
columnStat.earliestDate = Optional.ofNullable(rs.getDate(1));
columnStat.latestDate = Optional.ofNullable(rs.getDate(2));
}
});
if (columnStat.earliestDate.isPresent()) {
columnStat.min_count = Optional.of(jt.queryForObject(String.format(SQL_COUNT_VALUE, tableStat.name, columnStat.name, quote(columnStat.earliestDate.get())), Integer.class));
}
if (columnStat.latestDate.isPresent()) {
columnStat.max_count = Optional.of(jt.queryForObject(String.format(SQL_COUNT_VALUE, tableStat.name, columnStat.name, quote(columnStat.latestDate.get())), Integer.class));
}
break;
case TIMESTAMP:
case TIMESTAMP_WITH_TIMEZONE:
jt.query(String.format(SQL_START_END, columnStat.name, columnStat.name, tableStat.name, columnStat.name), new RowCallbackHandler() {
@Override
public void processRow(ResultSet rs) throws SQLException {
columnStat.earliestTimestamp = Optional.ofNullable(rs.getTimestamp(1));
columnStat.latestTimestamp = Optional.ofNullable(rs.getTimestamp(2));
}
});
if (columnStat.earliestTimestamp.isPresent()) {
columnStat.min_count = Optional.of(jt.queryForObject(String.format(SQL_COUNT_VALUE, tableStat.name, columnStat.name, quote(columnStat.earliestTimestamp.get())), Integer.class));
}
if (columnStat.latestTimestamp.isPresent()) {
columnStat.max_count = Optional.of(jt.queryForObject(String.format(SQL_COUNT_VALUE, tableStat.name, columnStat.name, quote(columnStat.latestTimestamp.get())), Integer.class));
}
break;
case TIME:
case TIME_WITH_TIMEZONE:
jt.query(String.format(SQL_START_END, columnStat.name, columnStat.name, tableStat.name, columnStat.name), new RowCallbackHandler() {
@Override
public void processRow(ResultSet rs) throws SQLException {
columnStat.earliestTime = Optional.ofNullable(rs.getTime(1));
columnStat.latestTime = Optional.ofNullable(rs.getTime(2));
}
});
if (columnStat.earliestTime.isPresent()) {
columnStat.min_count = Optional.of(jt.queryForObject(String.format(SQL_COUNT_VALUE, tableStat.name, columnStat.name, quote(columnStat.earliestTime.get())), Integer.class));
}
if (columnStat.latestTime.isPresent()) {
columnStat.max_count = Optional.of(jt.queryForObject(String.format(SQL_COUNT_VALUE, tableStat.name, columnStat.name, quote(columnStat.latestTime.get())), Integer.class));
}
break;
default:
}
tableStat.columns.add(columnStat);
}
while (exported.next()) {
String fromColumn = exported.getString("PKCOLUMN_NAME");
String toTable = exported.getString("FKTABLE_NAME");
String toColumn = exported .getString("FKCOLUMN_NAME");
tableStat.exportedKeys.add(new ForeignKey(fromColumn, toTable, toColumn));
}
while (imported.next()) {
String fromColumn = imported.getString("FKCOLUMN_NAME");
String toTable = imported.getString("PKTABLE_NAME");
String toColumn = imported .getString("PKCOLUMN_NAME");
tableStat.importedKeys.add(new ForeignKey(fromColumn, toTable, toColumn));
}
while (pks.next()) {
String column = pks.getString("COLUMN_NAME");
tableStat.primaryKeys.add(column);
}
}
tableStats.add(tableStat);
}
}
} catch (SQLException e) {
logger.error("SQL Fehler", e);
}
return tableStats;
}
/**
* Output statistic for a list of tables to an Excel file.
* The statistics of each table are written to a separate sheet.
* @param tableStats The list of TableStats
* @param outputFile The File to output to. If null output to current dir with a default file name.
*/
public void outputExcel(List<TableStatistic> tableStats, File outputFile) {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFDataFormat dataFormat = workbook.createDataFormat();
XSSFCellStyle cellStyleDouble = workbook.createCellStyle();
cellStyleDouble.setDataFormat(dataFormat.getFormat("0.##"));
XSSFCellStyle headerStyle = workbook.createCellStyle();
XSSFFont bold = workbook.createFont();
bold.setBold(true);
headerStyle.setFont(bold);
for (TableStatistic tableStat : tableStats) {
XSSFSheet sheet = workbook.createSheet("Table " + tableStat.name);
XSSFRow header = sheet.createRow(0);
XSSFCell cell = header.createCell(0);
cell.setCellValue("Database: " + database);
cell.setCellStyle(headerStyle);
cell = header.createCell(1);
cell.setCellStyle(headerStyle);
cell.setCellValue("Schema: " + schema);
XSSFRow first = sheet.createRow(2);
first.createCell(0).setCellValue("Table");
first.getCell(0).setCellStyle(headerStyle);
first.createCell(1).setCellValue("Row Count");
first.getCell(1).setCellStyle(headerStyle);
first.createCell(2).setCellValue("Column");
first.getCell(2).setCellStyle(headerStyle);
first.createCell(3).setCellValue("Type");
first.getCell(3).setCellStyle(headerStyle);
first.createCell(4).setCellValue("Size");
first.getCell(4).setCellStyle(headerStyle);
first.createCell(5).setCellValue("Not Null");
first.getCell(5).setCellStyle(headerStyle);
first.createCell(6).setCellValue("Autoincrement");
first.getCell(6).setCellStyle(headerStyle);
first.createCell(7).setCellValue("Count NULL");
first.getCell(7).setCellStyle(headerStyle);
first.createCell(8).setCellValue("% NULL");
first.getCell(8).setCellStyle(headerStyle);
first.createCell(9).setCellValue("Count Unique");
first.getCell(9).setCellStyle(headerStyle);
first.createCell(10).setCellValue("% Unique");
first.getCell(10).setCellStyle(headerStyle);
first.createCell(11).setCellValue("Min Len");
first.getCell(11).setCellStyle(headerStyle);
first.createCell(12).setCellValue("Max Len");
first.getCell(12).setCellStyle(headerStyle);
first.createCell(13).setCellValue("Min");
first.getCell(13).setCellStyle(headerStyle);
first.createCell(14).setCellValue("Max");
first.getCell(14).setCellStyle(headerStyle);
first.createCell(15).setCellValue("Avg");
first.getCell(15).setCellStyle(headerStyle);
first.createCell(16).setCellValue("Min Count");
first.getCell(16).setCellStyle(headerStyle);
first.createCell(17).setCellValue("Max Count");
first.getCell(17).setCellStyle(headerStyle);
first.createCell(18).setCellValue("Earliest");
first.getCell(18).setCellStyle(headerStyle);
first.createCell(19).setCellValue("Latest");
first.getCell(19).setCellStyle(headerStyle);
first.createCell(20).setCellValue("Comment");
first.getCell(20).setCellStyle(headerStyle);
int row = 3;
XSSFRow tableRow = sheet.createRow(row);
tableRow.createCell(0).setCellValue(tableStat.name);
tableRow.getCell(0).setCellStyle(headerStyle);
tableRow.createCell(1).setCellValue(tableStat.rowCount);
tableRow.getCell(1).setCellStyle(headerStyle);
for (ColumnStatistic columnStat : tableStat.columns) {
row += 1;
XSSFRow descRow = sheet.createRow(row);
descRow.createCell(2).setCellValue(columnStat.name);
if (tableStat.primaryKeys.contains(columnStat.name)) {
descRow.getCell(2).setCellValue(columnStat.name + " (PK)");
descRow.getCell(2).setCellStyle(headerStyle);
}
descRow.createCell(3).setCellValue(columnStat.type.getName());
descRow.createCell(4).setCellValue(columnStat.size);
if (columnStat.decimalDigits != 0) {
descRow.getCell(4).setCellValue(
Double.valueOf(columnStat.size + "." + columnStat.decimalDigits).doubleValue()
);
descRow.getCell(4).setCellStyle(cellStyleDouble);
}
descRow.createCell(5).setCellValue(!columnStat.isNullable);
descRow.createCell(6).setCellValue(columnStat.isAutoincrement);
descRow.createCell(7).setCellValue(columnStat.countNull);
descRow.createCell(8).setCellValue(columnStat.percentNull);
descRow.getCell(8).setCellStyle(cellStyleDouble);
descRow.createCell(9).setCellValue(columnStat.uniqueCount);
descRow.createCell(10).setCellValue(columnStat.uniquePercent);
descRow.getCell(10).setCellStyle(cellStyleDouble);
if (columnStat.minLen.isPresent()) {
descRow.createCell(11).setCellValue(columnStat.minLen.get().doubleValue());
}
if (columnStat.maxLen.isPresent()) {
descRow.createCell(12).setCellValue(columnStat.maxLen.get().doubleValue());
}
if (columnStat.min.isPresent()) {
descRow.createCell(13).setCellValue(columnStat.min.get().doubleValue());
descRow.getCell(13).setCellStyle(cellStyleDouble);
}
if (columnStat.max.isPresent()) {
descRow.createCell(14).setCellValue(columnStat.max.get().doubleValue());
descRow.getCell(14).setCellStyle(cellStyleDouble);
}
if (columnStat.avg.isPresent()) {
descRow.createCell(15).setCellValue(columnStat.avg.get().doubleValue());
descRow.getCell(15).setCellStyle(cellStyleDouble);
}
if (columnStat.min_count.isPresent()) {
descRow.createCell(16).setCellValue(columnStat.min_count.get().doubleValue());
descRow.getCell(16).setCellStyle(cellStyleDouble);
}
if (columnStat.max_count.isPresent()) {
descRow.createCell(17).setCellValue(columnStat.max_count.get().doubleValue());
descRow.getCell(17).setCellStyle(cellStyleDouble);
}
if (columnStat.earliestDate.isPresent()) {
descRow.createCell(18).setCellValue(columnStat.earliestDate.get().toString());
}
if (columnStat.latestDate.isPresent()) {
descRow.createCell(19).setCellValue(columnStat.latestDate.get().toString());
}
if (columnStat.earliestTime.isPresent()) {
descRow.createCell(18).setCellValue(columnStat.earliestTime.get().toString());
}
if (columnStat.latestTime.isPresent()) {
descRow.createCell(19).setCellValue(columnStat.latestTime.get().toString());
}
if (columnStat.earliestTimestamp.isPresent()) {
descRow.createCell(18).setCellValue(columnStat.earliestTimestamp.get().toString());
}
if (columnStat.latestTimestamp.isPresent()) {
descRow.createCell(19).setCellValue(columnStat.latestTimestamp.get().toString());
}
descRow.createCell(20).setCellValue(columnStat.comment);
}
for (int i = 0; i < 20; i++) {
sheet.autoSizeColumn(i);
}
XSSFRow frequHeader1 = sheet.createRow(row + 2);
XSSFRow frequHeader2 = sheet.createRow(row + 3);
frequHeader1.createCell(0).setCellValue("Frequency");
frequHeader1.getCell(0).setCellStyle(headerStyle);
frequHeader2.createCell(0).setCellValue("Column");
frequHeader2.getCell(0).setCellStyle(headerStyle);
for (int n = 1; n <= 10; n++) {
frequHeader1.createCell(n).setCellValue(n);
frequHeader1.getCell(n).setCellStyle(headerStyle);
}
for (int colNr = 0; colNr < tableStat.columns.size(); colNr++) {
XSSFRow frequRowLabel = sheet.createRow(row + 4 + 2 * colNr);
XSSFRow frequRowCount = sheet.createRow(row + 5 + 2 * colNr);
frequRowLabel.createCell(0).setCellValue(tableStat.columns.get(colNr).name);
for (int rankNr = 0; rankNr < tableStat.columns.get(colNr).ranking.size(); rankNr++) {
frequRowLabel.createCell(rankNr + 1).setCellValue(tableStat.columns.get(colNr).ranking.get(rankNr).label);
frequRowCount.createCell(rankNr + 1).setCellValue(tableStat.columns.get(colNr).ranking.get(rankNr).count);
}
}
row = row + 2 * tableStat.columns.size() + 5;
XSSFRow exHeader1 = sheet.createRow(row);
exHeader1.createCell(0).setCellValue("Exported Keys");
exHeader1.getCell(0).setCellStyle(headerStyle);
XSSFRow exHeader2 = sheet.createRow(row + 1);
exHeader2.createCell(0).setCellValue("From Column");
exHeader2.getCell(0).setCellStyle(headerStyle);
exHeader2.createCell(1).setCellValue("To Table");
exHeader2.getCell(1).setCellStyle(headerStyle);
exHeader2.createCell(2).setCellValue("To Column");
exHeader2.getCell(2).setCellStyle(headerStyle);
for (int fkNr = 0; fkNr < tableStat.exportedKeys.size(); fkNr++) {
XSSFRow fkRow = sheet.createRow(row + 2 + fkNr);
fkRow.createCell(0).setCellValue(tableStat.exportedKeys.get(fkNr).fromColumn);
fkRow.createCell(1).setCellValue(tableStat.exportedKeys.get(fkNr).toTable);
fkRow.createCell(2).setCellValue(tableStat.exportedKeys.get(fkNr).toColumn);
}
row = row + 3 + tableStat.exportedKeys.size();
XSSFRow imHeader1 = sheet.createRow(row);
imHeader1.createCell(0).setCellValue("Imported Keys");
imHeader1.getCell(0).setCellStyle(headerStyle);
XSSFRow imHeader2 = sheet.createRow(row + 1);
imHeader2.createCell(0).setCellValue("From Table");
imHeader2.getCell(0).setCellStyle(headerStyle);
imHeader2.createCell(1).setCellValue("From Column");
imHeader2.getCell(1).setCellStyle(headerStyle);
imHeader2.createCell(2).setCellValue("To Column");
imHeader2.getCell(2).setCellStyle(headerStyle);
for (int fkNr = 0; fkNr < tableStat.importedKeys.size(); fkNr++) {
XSSFRow fkRow = sheet.createRow(row + 2 + fkNr);
fkRow.createCell(0).setCellValue(tableStat.importedKeys.get(fkNr).toTable);
fkRow.createCell(1).setCellValue(tableStat.importedKeys.get(fkNr).toColumn);
fkRow.createCell(2).setCellValue(tableStat.importedKeys.get(fkNr).fromColumn);
}
}
File currDir = new File(".");
String path = currDir.getAbsolutePath();
String fileLocation = path.substring(0, path.length() - 1) + "db_profile_" + database + ".xlsx";
if (outputFile != null) {
fileLocation = outputFile.getAbsolutePath();
}
logger.info("Writing to " + fileLocation);
FileOutputStream outputStream;
try {
outputStream = new FileOutputStream(fileLocation);
workbook.write(outputStream);
workbook.close();
} catch (IOException e) {
logger.error("Couldn't write excel file", e);
}
}
private static Options createOptions() {
Options options = new Options();
Option opt;
opt = new Option("h", "help", false, "get help");
options.addOption(opt);
opt = new Option("t", "tables", true, "tables");
opt.setArgs(Option.UNLIMITED_VALUES);
// opt.setRequired(true);
options.addOption(opt);
opt = new Option("s", "schema", true, "schema");
options.addOption(opt);
opt = new Option("d", "database", true, "database");
// opt.setRequired(true);
options.addOption(opt);
return options;
}
private static CommandLine parseArgs(String[] args, Options options) {
CommandLineParser parser = new GnuParser();
try {
return parser.parse(options, args, false);
} catch (ParseException e) {
System.out.println("error while reading the command line parameters:");
e.printStackTrace();
System.exit(1);
}
return null;
}
private static void initSxPools() {
try {
List<String> mandantenNamen = new LinkedList<String>();
mandantenNamen.add(DEFAULT_MANDANTEN_ID);
SxPools.closeAll();
SxPools.init(mandantenNamen);
SxPools.get(DEFAULT_MANDANTEN_ID).init();
SxPools.get(DEFAULT_MANDANTEN_ID).initLogging(true, Level.DEBUG);
// also init kettle env, set plugin dir
SuperXManager.initKettleEnv(APPLICATION_CONTEXT);
} catch (Exception e) {
System.out.println("error while initialising the SuperX pools:");
e.printStackTrace();
System.exit(1);
}
}
private static void printHelp(Options options) {
HelpFormatter help = new HelpFormatter();
help.printHelp(HELP_STRING, options);
}
private static GenericApplicationContext createContext() {
/*
* https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/AnnotationConfigApplicationContext.html
* quote:
* "In case of multiple @Configuration classes, @Bean methods defined in later classes will override those defined in earlier classes.
* This can be leveraged to deliberately override certain bean definitions via an extra @Configuration class."
* - so it's alright to override some beans via "CLIConfig"
*/
if (APPLICATION_CONTEXT == null) {
APPLICATION_CONTEXT = new AnnotationConfigApplicationContext(BatchConfig.class, DataJdbcConfiguration.class, CLIConfig.class, ServiceConfig.class);
}
return APPLICATION_CONTEXT;
}
private static String quote(Object o) {
return "'" + o + "'";
}
}
class TableStatistic {
public String name;
public long rowCount;
public List<ColumnStatistic> columns;
public List<ForeignKey> exportedKeys;
public List<ForeignKey> importedKeys;
public List<String> primaryKeys;
public TableStatistic(String name, long rowCount) {
this.name = name;
this.rowCount = rowCount;
this.columns = new ArrayList<>();
this.exportedKeys = new ArrayList<>();
this.importedKeys = new ArrayList<>();
this.primaryKeys = new ArrayList<>();
}
}
class ColumnStatistic {
public String name;
public JDBCType type;
public int size;
public int decimalDigits;
public boolean isNullable;
public boolean isAutoincrement;
public String comment;
public long countNull;
public double percentNull;
public long uniqueCount;
public double uniquePercent;
public Optional<Integer> max_count = Optional.empty();
public Optional<Integer> min_count = Optional.empty();
public List<RankingEntry> ranking;
public Optional<Integer> minLen = Optional.empty();
public Optional<Integer> maxLen = Optional.empty();
public Optional<Double> min = Optional.empty();
public Optional<Double> max = Optional.empty();
public Optional<Double> avg = Optional.empty();
public Optional<Date> earliestDate = Optional.empty();
public Optional<Date> latestDate = Optional.empty();
public Optional<Time> earliestTime = Optional.empty();
public Optional<Time> latestTime = Optional.empty();
public Optional<Timestamp> earliestTimestamp = Optional.empty();
public Optional<Timestamp> latestTimestamp = Optional.empty();
}
class RankingEntry {
public RankingEntry(String label, int count) {
this.label = label;
this.count = count;
}
public String label;
public int count;
}
class ForeignKey {
public ForeignKey(String fromColumn, String toTable, String toColumn) {
this.fromColumn = fromColumn;
this.toTable = toTable;
this.toColumn = toColumn;
}
public String fromColumn;
public String toTable;
public String toColumn;
}

583
src/de/superx/bin/DelEndChar.java

@ -1,308 +1,277 @@
package de.superx.bin; package de.superx.bin;
import java.io.BufferedReader;
import java.io.BufferedWriter; import java.io.BufferedReader;
import java.io.File; import java.io.BufferedWriter;
import java.io.FileInputStream; import java.io.File;
import java.io.FileOutputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.FileOutputStream;
import java.io.InputStreamReader; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts;
public class DelEndChar { import de.memtext.util.GetOpts.Options;
/* Klassenvariablen */ public class DelEndChar {
private static String _dateiPfad = "";
private static String DELIMITER = "^"; /* Klassenvariablen */
private static String _outDateiPfad=""; private static String _dateiPfad = "";
private static String _tabelle="";
/** private static String DELIMITER = "^";
* Diese Klasse bereinigt die Zeilen der angegebenen ASCII-Dateien<br>
* Es wird der letzte Delimiter-Zeichen aus jeder Zeile entfernt.<br> private static String _outDateiPfad = "";
* Parameter:<br>
* 1. Eingabe-Dateiname mit Pfadangabe <br> private static String _tabelle = "";
* 2. Ausgabe-Dateiname mit Pfadangabe<br>
* 3. Delimiter-Zeichen(optional).<br> /**
* 4. Tabellenname in der Datenbank, der auf Übereistimmung der Felderanzahl geprüft werden soll (optional).<br> * Diese Klasse bereinigt die Zeilen der angegebenen ASCII-Dateien<br>
* Defaultwert für Delimiter ist ^. * Es wird der letzte Delimiter-Zeichen aus jeder Zeile entfernt.<br>
* Aufruf: java -cp .:../lib/superx-db.jar:../lib/<<jdbc-Treiber>>.jar delEndChar <Dateiname> <Zieldateiname> <opt. Delimiter-Zeichen> <opt. Tabellenname> * Parameter:<br>
* @version 0.1 4.7.2003 * 1. Eingabe-Dateiname mit Pfadangabe <br>
* @author Eugen Ermantraut */ * 2. Ausgabe-Dateiname mit Pfadangabe<br>
public DelEndChar() { * 3. Delimiter-Zeichen(optional).<br>
} * 4. Tabellenname in der Datenbank, der auf Übereistimmung der Felderanzahl geprüft werden soll (optional).<br>
public static void main(String[] args) * Defaultwert für Delimiter ist ^.
{ * Aufruf: java -cp .:../lib/superx-db.jar:../lib/<<jdbc-Treiber>>.jar delEndChar <Dateiname> <Zieldateiname> <opt. Delimiter-Zeichen> <opt. Tabellenname>
DelEndChar r = new DelEndChar(); * @version 0.1 4.7.2003
GetOpts.setOpts(args); * @author Eugen Ermantraut */
String isdrin= GetOpts.isAllRequiredOptionsPresent("-IN"); public DelEndChar() {
if(isdrin != null) }
{
System.err.println("Datei-Pfade werden als Parameter erwartet. Folgende Optionen fehlen: " + isdrin); public static void main(String[] args) {
r.zeige_hilfe(); DelEndChar r = new DelEndChar();
System.exit(1); GetOpts.setOpts(args);
} String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[] {Options.opt_in});
if (isdrin != null) {
//GetOpts myOpts=new GetOpts(); System.err.println("Datei-Pfade werden als Parameter erwartet. Folgende Optionen fehlen: " + isdrin);
if (GetOpts.isPresent("-IN")) r.zeige_hilfe();
_dateiPfad=GetOpts.getValue("-IN" ); System.exit(1);
if (GetOpts.isPresent("-OUT")) }
_outDateiPfad=GetOpts.getValue("-OUT" );
if (GetOpts.isPresent("-delim")) //GetOpts myOpts=new GetOpts();
DELIMITER=GetOpts.getValue("-delim" ); if (GetOpts.isPresent(Options.opt_in)) _dateiPfad = GetOpts.getValue(Options.opt_in);
if (GetOpts.isPresent("-table")) if (GetOpts.isPresent(Options.opt_out)) _outDateiPfad = GetOpts.getValue(Options.opt_out);
_tabelle=GetOpts.getValue("-table" ); if (GetOpts.isPresent(Options.opt_delim)) DELIMITER = GetOpts.getValue(Options.opt_delim);
if (args[0].toString().equals("?") || if (GetOpts.isPresent(Options.opt_table)) _tabelle = GetOpts.getValue(Options.opt_table);
args[0].toString().equals("/?") || if (args[0].toString().equals("?") || args[0].toString().equals("/?") || args[0].toString().equals("\\?") || args[0].toString().toLowerCase().equals("-h")
args[0].toString().equals("\\?") || || args[0].toString().toLowerCase().equals("--h")) {
args[0].toString().toLowerCase().equals("-h") || r.zeige_hilfe();
args[0].toString().toLowerCase().equals("--h") ) System.exit(1);
{ }
r.zeige_hilfe();
System.exit(1);
} //if (r.check_param_ok(args))
//{
try {
//if (r.check_param_ok(args)) r.updateFile(r._dateiPfad, r._outDateiPfad);
//{ System.out.println("Datei: " + r._dateiPfad + " nach " + r._outDateiPfad + " umgesetzt");
try } catch (Exception e) {
{ System.err.println(e.toString());
r.updateFile(r._dateiPfad, r._outDateiPfad); }
System.out.println("Datei: " + r._dateiPfad + " nach " + r._outDateiPfad+ " umgesetzt"); //}
}
catch (Exception e) } // Ende der Methode
{ System.err.println(e.toString());
}
//} private void updateFile(String inDateiPfad, String outDateiPfad) throws IOException, Exception {
File f = new File(inDateiPfad);
} // Ende der Methode if (!f.exists()) {
throw new Exception("Datei nicht gefunden: " + inDateiPfad);
}
private void updateFile(String inDateiPfad, String outDateiPfad) throws IOException, Exception BufferedReader in;
{ BufferedWriter out;
File f = new File(inDateiPfad); //--- File-Instanz für temporäre Ergebnis-Datei anlegen ---//
if (!f.exists()) File out_tmp;
{ throw new Exception("Datei nicht gefunden: " + inDateiPfad); out_tmp = new File(inDateiPfad + ".tmp2");
} //--- IputStream und OutputStream generieren ---//
BufferedReader in; in = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
BufferedWriter out; //--- Output-Stream der tämporere Datei erzeugen ---//
//--- File-Instanz für temporäre Ergebnis-Datei anlegen ---// out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(out_tmp)));
File out_tmp;
out_tmp = new File(inDateiPfad+".tmp2"); //--- Verarbeiten der Datei ---//
//--- IputStream und OutputStream generieren ---// String text;
in = new BufferedReader(new InputStreamReader( String tt;
new FileInputStream(f) )); text = in.readLine();
//--- Output-Stream der tämporere Datei erzeugen ---// if (text != null) { //Datei nicht leer
out = new BufferedWriter( new OutputStreamWriter( if (text.endsWith("\\")) {
new FileOutputStream(out_tmp) ));
tt = in.readLine();
//--- Verarbeiten der Datei ---// if (tt != null) {
String text; text += tt;
String tt; while (tt.endsWith("\\")) {
text = in.readLine(); tt = in.readLine();
if(text!=null) if (tt != null) text += tt + "\n"; //(tt.substring(0,tt.length()));
{ //Datei nicht leer }
if(text.endsWith("\\")) }
{ }
if (!_tabelle.equals("") && !_tabelle.equals("null")) {
tt=in.readLine(); //Die Datei ist eine entladene Tabelle
if(tt!=null) //int start=_dateiPfad.indexOf("_",_dateiPfad.length()-4);
{ //if(start <0 )
text+=tt; // start=0;
while(tt.endsWith( "\\")) // String tabname=_dateiPfad.substring(start,_dateiPfad.length()-4);
{ int numFelder = 0;
tt= in.readLine(); //System.out.println("Tabelle "+_tabelle+ " DELIM " + DELIMITER);
if(tt != null) text +=tt+"\n"; //(tt.substring(0,tt.length())); try {
} numFelder = SxDBUtils.fieldCount(_tabelle);
} //System.out.println("Felderanzahl:"+numFelder);
} } catch (Exception e) {
if(!_tabelle.equals("") && !_tabelle.equals("null") ) System.err.println("Fehler beim Abfragen der Tabellen-Metadaten: " + e.toString());
{ }
//Die Datei ist eine entladene Tabelle int k = 0;
//int start=_dateiPfad.indexOf("_",_dateiPfad.length()-4); int i = 0;
//if(start <0 ) int p = 0;
// start=0; do {
// String tabname=_dateiPfad.substring(start,_dateiPfad.length()-4); p = text.indexOf(DELIMITER, i);
int numFelder=0; if (p > 0) {
//System.out.println("Tabelle "+_tabelle+ " DELIM " + DELIMITER); k++;
try { i = p + 1;
numFelder= SxDBUtils.fieldCount(_tabelle); }
//System.out.println("Felderanzahl:"+numFelder);
} } while (p > 0);
catch (Exception e) if (k != numFelder) {
{ throw new Exception("unl-Datei entspricht nicht der Tabelle in der Datenbank;\nDie Tabelle hat " + numFelder + " Felder, die unl-Datei hat " + k + " Felder ");
System.err.println("Fehler beim Abfragen der Tabellen-Metadaten: " + e.toString()); }
}
int k=0; } //Wenn Tabelle gecheckt werden sollte
int i=0; do {
int p=0; if (text == null) break;
do if (text.endsWith("\\")) {
{
p=text.indexOf(DELIMITER,i); tt = in.readLine();
if(p>0) if (tt != null) {
{ text += tt;
k++; while (tt != null && tt.endsWith("\\")) { //Umbrüche aus Informix-Lognvarchars abfangen
i=p+1; tt = in.readLine();
} if (tt != null) text += tt + "\n"; //(tt.substring(0,tt.length()));
}
} }
while (p>0); }
if(k!=numFelder)
{ throw new Exception("unl-Datei entspricht nicht der Tabelle in der Datenbank;\nDie Tabelle hat "+numFelder+" Felder, die unl-Datei hat "+k +" Felder "); text = reorgString(text.trim());
} if (text == "-0") // Rohdatendatei Formatfehler
{
} //Wenn Tabelle gecheckt werden sollte throw new Exception("Datei: " + inDateiPfad + " hat falsches Format: ");
do }
{ out.write(text, 0, text.length());
if (text == null) out.write("\n"); // muss NeuLine schreiben das die Zeile ohne eingelesen wird
break; out.flush();
if(text.endsWith("\\"))
{ text = in.readLine();
tt= in.readLine(); } while (text != null);
if(tt != null) } //Wenn Datei nicht leer war.
{ in.close();
text += tt; out.close();
while(tt != null && tt.endsWith( "\\")) //--- Umbenennen Quell-Dateien ---//
{ //Umbrüche aus Informix-Lognvarchars abfangen /*String alt = inDateiPfad + ".in";
tt= in.readLine(); File altFile = new File(alt);
if(tt != null) text +=tt+"\n"; //(tt.substring(0,tt.length())); if (altFile.exists())
} altFile.delete();
}
} f.renameTo(altFile);*/
text = reorgString(text.trim()); //--- Umformatierte temporäre Datei unter dem ursprünglichen Namen ablegen ---//
if (text == "-0") // Rohdatendatei Formatfehler File neuFile = new File(outDateiPfad);
{ throw new Exception("Datei: " + inDateiPfad + " hat falsches Format: "); out_tmp.renameTo(neuFile);
}
out.write(text,0,text.length()); //--- Berechtigung für die neu angelegete Datei neu Vergeben ---//
out.write("\n"); // muss NeuLine schreiben das die Zeile ohne eingelesen wird if (!chmode("u=rw,g=rw,o=rw", outDateiPfad)) {
out.flush(); System.out.println("Kann Berechtigung nicht ändern " + outDateiPfad);
}
text = in.readLine(); //--- Schliessen der Streams und Löschen der temporären Datei ---//
in.close();
}while (text!=null); out.close();
} //Wenn Datei nicht leer war. out_tmp.delete();
in.close(); out.close();
//--- Umbenennen Quell-Dateien ---// }//Ende der Methode
/*String alt = inDateiPfad + ".in";
File altFile = new File(alt); private boolean chmode(String inBerechtigung, String inDat) {
if (altFile.exists()) String befehl = "chmod " + inBerechtigung + " " + inDat;
altFile.delete(); try {
Runtime r = Runtime.getRuntime();
f.renameTo(altFile);*/ Process p = r.exec(befehl);
int exitCode = p.waitFor();
//--- Umformatierte temporäre Datei unter dem ursprünglichen Namen ablegen ---// } catch (Exception e) {
File neuFile = new File(outDateiPfad); System.out.println("Error: " + e.toString());
out_tmp.renameTo(neuFile); return false;
}
//--- Berechtigung für die neu angelegete Datei neu Vergeben ---//
if (!chmode("u=rw,g=rw,o=rw", outDateiPfad)) return true;
{ System.out.println("Kann Berechtigung nicht ändern " + outDateiPfad); }//Ende der Methode
}
//--- Schliessen der Streams und Löschen der temporären Datei ---// /**
in.close(); out.close(); * Liefert den Teilsstring von 0 bis zu letzten Delimiterzeichen(Exclusive)
out_tmp.delete(); * @param inS
* @return String
}//Ende der Methode */
private String reorgString(String inS) throws Exception {
private boolean chmode(String inBerechtigung,String inDat) int ldPos = inS.lastIndexOf(DELIMITER);
{ //--- Wenn Delimiter-Zeichen nicht letztes Zeichen im String ist,
String befehl = "chmod "+ inBerechtigung + " " + inDat; //--- muss die Verarbeitung abgebrochen werden---//
try
{ if ((ldPos + 1) < inS.length() || ldPos == -1)
Runtime r = Runtime.getRuntime(); //throw new Exception("Datei ist bereits umgesetzt!");
Process p = r.exec(befehl); return inS;
int exitCode = p.waitFor(); else
} return inS.substring(0, ldPos);
catch(Exception e)
{ System.out.println("Error: " + e.toString()); }//Ende der Methode
return false;
} public boolean check_param_ok(String[] inTab) { //--- Anzahl der übergebenen Parameter prüfen ---//
//System.out.println(inTab.length);
return true; if (inTab.length < 2) {
}//Ende der Methode System.out.println("Mindestens 2 Parameter erwartet! Mit -h oder ? rufen sie Hilfe auf.");
return false;
/** }
* Liefert den Teilsstring von 0 bis zu letzten Delimiterzeichen(Exclusive) //--- Dateinpfad übernehmen ---//
* @param inS _dateiPfad = inTab[0].trim();
* @return String _outDateiPfad = inTab[1].trim();
*/
private String reorgString(String inS) throws Exception if (inTab.length >= 3) DELIMITER = inTab[2].trim();
{ //---Wenn Delimiter-Zeichen übergeben wurde dann übernehmen ---//
int ldPos = inS.lastIndexOf(DELIMITER); if (inTab.length > 3) _tabelle = inTab[3].toString().trim();
//--- Wenn Delimiter-Zeichen nicht letztes Zeichen im String ist,
//--- muss die Verarbeitung abgebrochen werden---// return true;
}//Ende der Methode
if ((ldPos + 1) < inS.length() || ldPos== -1)
//throw new Exception("Datei ist bereits umgesetzt!"); /**
return inS; * Prüfen der Datei auf Vorhandensein und Leseberechrigung
else * @param inFile
return inS.substring(0,ldPos); */
private boolean check_Directory(File inFile) {
}//Ende der Methode if (inFile.exists()) {
if (!inFile.isDirectory()) {
public boolean check_param_ok(String[] inTab) System.out.println(inFile + " ist kein Verzeichnis!");
{ //--- Anzahl der übergebenen Parameter prüfen ---// return false;
//System.out.println(inTab.length); }
if (inTab.length < 2 ) } else {
{ System.out.println("Mindestens 2 Parameter erwartet! Mit -h oder ? rufen sie Hilfe auf."); System.out.println(inFile + " Verzeichniss nicht gefunden!");
return false; return false;
} }
//--- Dateinpfad übernehmen ---//
_dateiPfad = inTab[0].trim(); return true;
_outDateiPfad = inTab[1].trim(); }//Ende der Methode
if (inTab.length >=3 ) private void progEnde() {
DELIMITER = inTab[2].trim(); System.runFinalization();
//---Wenn Delimiter-Zeichen übergeben wurde dann übernehmen ---// System.exit(0);
if (inTab.length >3 ) }//Ende der Methode
_tabelle = inTab[3].toString().trim();
return true; private void zeige_hilfe() {
}//Ende der Methode System.out.println("\n Diese Klasse bereinigt die Zeilen der angegebenen ASCII-Dateien.");
System.out.println(" Es wird der letzte Delimeter-Zeichen aus jeder Zeile entfernt.");
/** System.out.println("\n Parameter: ");
* Prüfen der Datei auf Vorhandensein und Leseberechrigung System.out.println("1. Eingabe-Dateiname mit Pfadangabe ");
* @param inFile System.out.println("2. Ausgabe-Dateiname mit Pfadangabe");
*/ System.out.println("3. Delimiter-Zeichen(optional)");
private boolean check_Directory(File inFile) System.out.println("4. Tabellenname in der Datenbank, der auf Übereistimmung der Felderanzahl geprüft werden soll (optional, wenn keine Überprüfung, dann 'none').");
{ //System.out.println(" Wenn in einer Zeile Zeichen hinter dem letzten Delimiter-Zeichen ");
if (inFile.exists()) //System.out.println(" wird die Bearbeitung abgebrochen, da es anzunehmen ist daß diese Datei");
{ if (!inFile.isDirectory()) //System.out.println(" bereits umgesetzt ist!");
{ System.out.println(inFile + " ist kein Verzeichnis!"); System.out.println(" Defaultwert fuer Delimiter ist ^. \n");
return false; }// Ende der Methode
}
}
else
{ System.out.println(inFile + " Verzeichniss nicht gefunden!");
return false;
}
return true;
}//Ende der Methode
private void progEnde()
{
System.runFinalization();
System.exit(0);
}//Ende der Methode
private void zeige_hilfe()
{
System.out.println("\n Diese Klasse bereinigt die Zeilen der angegebenen ASCII-Dateien.");
System.out.println(" Es wird der letzte Delimeter-Zeichen aus jeder Zeile entfernt.");
System.out.println("\n Parameter: ");
System.out.println("1. Eingabe-Dateiname mit Pfadangabe ");
System.out.println("2. Ausgabe-Dateiname mit Pfadangabe");
System.out.println("3. Delimiter-Zeichen(optional)");
System.out.println("4. Tabellenname in der Datenbank, der auf Übereistimmung der Felderanzahl geprüft werden soll (optional, wenn keine Überprüfung, dann 'none').");
//System.out.println(" Wenn in einer Zeile Zeichen hinter dem letzten Delimiter-Zeichen ");
//System.out.println(" wird die Bearbeitung abgebrochen, da es anzunehmen ist daß diese Datei");
//System.out.println(" bereits umgesetzt ist!");
System.out.println(" Defaultwert fuer Delimiter ist ^. \n" );
}// Ende der Methode
}//Ende der Klasse }//Ende der Klasse

147
src/de/superx/bin/DialectCreator.java

@ -1,74 +1,73 @@
package de.superx.bin; package de.superx.bin;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.util.HashMap; import java.util.HashMap;
import de.memtext.util.DateUtils; import de.memtext.util.DateUtils;
import freemarker.template.Configuration; import freemarker.template.Configuration;
import freemarker.template.Template; import freemarker.template.Template;
import freemarker.template.TemplateException; import freemarker.template.TemplateException;
public class DialectCreator { public class DialectCreator {
private static String path, sourceFileName; private static String path, sourceFileName;
private static String source;
protected static Configuration cfg = new Configuration(); private static String source;
private static Template template;
protected static Configuration cfg = new Configuration();
public static void main(String[] args) {
checkArgs(args); private static Template template;
try {
cfg.setDirectoryForTemplateLoading(new File(path)); public static void main(String[] args) {
template = cfg.getTemplate(sourceFileName); checkArgs(args);
//source=StringUtils.readFile(f); try {
translate("Informix", "_ids"); cfg.setDirectoryForTemplateLoading(new File(path));
translate("Postgres", "_pg"); template = cfg.getTemplate(sourceFileName);
//source=StringUtils.readFile(f);
} catch (Exception e) { translate("Informix", "_ids");
e.printStackTrace(); translate("Postgres", "_pg");
}
} } catch (Exception e) {
e.printStackTrace();
private static void checkArgs(String[] args) { }
if (args.length != 2) { }
System.out
.println("Error: use: DialectCreator path sourcefilename"); private static void checkArgs(String[] args) {
System.exit(1); if (args.length != 2) {
} System.out.println("Error: use: DialectCreator path sourcefilename");
path = args[0]; System.exit(1);
sourceFileName = args[1]; }
File f = new File(path + File.separator + sourceFileName); path = args[0];
if (!f.exists() || !f.canRead()) { sourceFileName = args[1];
System.out.println("Error: can't read source file " + args[1]); File f = new File(path + File.separator + sourceFileName);
System.exit(1); if (!f.exists() || !f.canRead()) {
} System.out.println("Error: can't read source file " + args[1]);
} System.exit(1);
}
private static void translatePostgres() { }
HashMap map = new HashMap();
private static void translatePostgres() {
map.put("SQLdialect", "Postgres"); HashMap map = new HashMap();
} map.put("SQLdialect", "Postgres");
private static void translate(String dialect, String fileAppendix) }
throws TemplateException, IOException {
HashMap map = new HashMap(); private static void translate(String dialect, String fileAppendix) throws TemplateException, IOException {
map.put("SQLdialect", dialect); HashMap map = new HashMap();
map.put("current", DateUtils.getTodayString() + " um " map.put("SQLdialect", dialect);
+ DateUtils.getNowString()); map.put("current", DateUtils.getTodayString() + " um " + DateUtils.getNowString());
String fname = sourceFileName.substring(0, sourceFileName.length() - 4) String fname = sourceFileName.substring(0, sourceFileName.length() - 4) + fileAppendix + ".sql";
+ fileAppendix + ".sql";
Writer out = new FileWriter(path + File.separator + fname);
Writer out = new FileWriter(path + File.separator + fname);
// Merge the data-model and the template
// Merge the data-model and the template template.process(map, out);
template.process(map, out); out.close();
out.close(); System.out.println(" " + dialect + " variant created:" + fname);
System.out.println(" " + dialect + " variant created:" + fname); }
} }
}
//Created on 19.04.2005 at 10:22:09
//Created on 19.04.2005 at 10:22:09

246
src/de/superx/bin/DoShutdown.java

@ -1,4 +1,5 @@
package de.superx.bin; package de.superx.bin;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -10,9 +11,12 @@ import java.sql.Statement;
import java.util.logging.LogManager; import java.util.logging.LogManager;
import java.util.logging.Logger; import java.util.logging.Logger;
import de.memtext.util.ExceptionHandler;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
import de.superx.bin.Doschema.Format;
/** /**
* @author Daniel Quathamer Projektgruppe SuperX * @author Daniel Quathamer Projektgruppe SuperX
* doquery.java * doquery.java
@ -26,127 +30,121 @@ import de.memtext.util.GetOpts;
*/ */
public class DoShutdown { public class DoShutdown {
Connection myDb; Connection myDb;
Statement st; // Our statement to run queries with
DatabaseMetaData dbmd; // This defines the structure of the database Statement st; // Our statement to run queries with
boolean done = false; // Added by CWJ to permit \q command
String delim = "\t"; DatabaseMetaData dbmd; // This defines the structure of the database
String header = "false";
String outFormat = "txt"; boolean done = false; // Added by CWJ to permit \q command
String logfile = "../conf/logging.properties";
String tabelle = ""; String delim = "\t";
String dbpropfile = "../conf/db.properties";
String outfile = ""; String header = "false";
Logger logger = (Logger) Logger.getLogger(DoShutdown.class.toString());
private ExceptionHandler exceptionHandler = new ExceptionHandler(false); Format outFormat = Format.txt;
private static String usage="-------------------------------------\n"+
"Gebrauch: java de.superx.bin DoShutdown -logger:<<Pfad zu logging.properties>> -dbproperties:<<Pfad zu den db.properties>> -cancel=<<Abbrechen bei Fehler (true/false)>>(optional) \n" String logfile = "../conf/logging.properties";
+"drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties erforderlich"
+"---------------------------------------------------"; String tabelle = "";
public DoShutdown(String args[]) String dbpropfile = "../conf/db.properties";
throws
ClassNotFoundException, String outfile = "";
FileNotFoundException,
IOException, Logger logger = (Logger) Logger.getLogger(DoShutdown.class.toString());
SQLException
{
String cancel="";
GetOpts.setOpts(args); private static String usage = "-------------------------------------\n"
String isdrin= GetOpts.isAllRequiredOptionsPresent("-logger,-dbproperties"); + "Gebrauch: java de.superx.bin DoShutdown -logger:<<Pfad zu logging.properties>> -dbproperties:<<Pfad zu den db.properties>> -cancel=<<Abbrechen bei Fehler (true/false)>>(optional) \n"
if(isdrin != null) + "drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties erforderlich"
{ + "---------------------------------------------------";
System.err.println("Folgende Optionen fehlen: " + isdrin);
System.err.println(usage); public DoShutdown(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException {
System.exit(1); String cancel = "";
} GetOpts.setOpts(args);
String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[]{Options.opt_logger,Options.opt_dbprops});
//GetOpts myOpts=new GetOpts(); if (isdrin != null) {
if (GetOpts.isPresent("-logger")) System.err.println("Folgende Optionen fehlen: " + isdrin);
logfile=GetOpts.getValue("-logger" ); System.err.println(usage);
if (GetOpts.isPresent("-dbproperties")) System.exit(1);
dbpropfile=GetOpts.getValue("-dbproperties" ); }
if (GetOpts.isPresent("-cancel"))
cancel=GetOpts.getValue("-cancel" ); //GetOpts myOpts=new GetOpts();
if (GetOpts.isPresent(Options.opt_logger)) logfile = GetOpts.getValue(Options.opt_logger);
initLoggingSystem(); if (GetOpts.isPresent(Options.opt_dbprops)) dbpropfile = GetOpts.getValue(Options.opt_dbprops);
if (GetOpts.isPresent(Options.opt_cancel)) cancel = GetOpts.getValue(Options.opt_cancel);
//dbpropfile = args[1].trim(); initLoggingSystem();
boolean systemExitWanted=true;
if (cancel.equalsIgnoreCase("false")) systemExitWanted=false;
//dbpropfile = args[1].trim();
SxJdbcClient myClient = new SxJdbcClient(logger, dbpropfile, "checkpoint;"); boolean systemExitWanted = true;
//SxJdbcClient myClient = new SxJdbcClient(logger, dbpropfile, "shutdown immediately;"); if (cancel.equalsIgnoreCase("false")) systemExitWanted = false;
try {
myClient.execute(); SxJdbcClient myClient = new SxJdbcClient(logger, dbpropfile, "checkpoint;");
//SxJdbcClient myClient = new SxJdbcClient(logger, dbpropfile, "shutdown immediately;");
} catch (SQLException e) { try {
logger.severe("Fehler beim sql-Script: " + e.toString()); myClient.execute();
exceptionHandler.handle(e); myClient.sqlstmt = "shutdown immediately;";
} myClient.execute();
exceptionHandler.setExitWanted(systemExitWanted); logger.info("shutdown erfolgreich");
myClient.sqlstmt = "shutdown immediately;"; } catch (SQLException e) {
try { System.out.println("Fehler:" + e.toString());
logger.info("shutdown erfolgreich"); e.printStackTrace();
myClient.execute(); if (systemExitWanted) System.exit(-1);
}
} catch (SQLException e) {
if (systemExitWanted) logger.severe("Fehler beim sql-Script: " + e.toString()); }
exceptionHandler.handle(e);
private void initLoggingSystem() throws IOException, FileNotFoundException {
}
File f = new File(logfile);
} if (!f.exists()) {
private void initLoggingSystem() throw new IOException("Datei nicht gefunden: " + logfile);
throws IOException, FileNotFoundException { }
FileInputStream ins = new FileInputStream(logfile);
File f = new File(logfile); LogManager MyLogManager = java.util.logging.LogManager.getLogManager();
if (!f.exists()) { MyLogManager.readConfiguration(ins);
throw new IOException("Datei nicht gefunden: " + logfile); logfile = MyLogManager.getProperty(".level");
} logger.info("Using Loggging-Level " + logfile);
FileInputStream ins = new FileInputStream(logfile); }
LogManager MyLogManager = java.util.logging.LogManager.getLogManager();
MyLogManager.readConfiguration(ins); /*
logfile = MyLogManager.getProperty(".level"); * This processes a statement
logger.info("Using Loggging-Level " + logfile); */
}
/*
/* * Display some instructions on how to run the example
* This processes a statement */
*/ public static void instructions() {
System.out.println("SuperX @version@\n");
/* System.out.println("\nDieses Java-Programm beendet einen hsqldb-Datenbankserver\n");
* Display some instructions on how to run the example System.exit(1);
*/ }
public static void instructions() {
System.out.println("SuperX @version@\n"); /*
System.out.println( * This little lot starts the test
"\nDieses Java-Programm beendet einen hsqldb-Datenbankserver\n"); */
System.exit(1); public static void main(String args[]) {
} //System.out.println("PostgreSQL psql example v6.3 rev 1\n");
/* //if (args.length < 3)
* This little lot starts the test // instructions();
*/
public static void main(String args[]) { // This line outputs debug information to stderr. To enable this, simply
//System.out.println("PostgreSQL psql example v6.3 rev 1\n"); // add an extra parameter to the command line
//if (args.length > 3)
//if (args.length < 3) // DriverManager.setLogStream(System.err);
// instructions();
// Now run the tests
// This line outputs debug information to stderr. To enable this, simply try {
// add an extra parameter to the command line DoShutdown test = new DoShutdown(args);
//if (args.length > 3) } catch (Exception ex) {
// DriverManager.setLogStream(System.err); System.err.println("Exception caught.\n" + ex);
ex.printStackTrace();
// Now run the tests }
try { }
DoShutdown test = new DoShutdown(args);
} catch (Exception ex) {
System.err.println("Exception caught.\n" + ex);
ex.printStackTrace();
}
}
} }

559
src/de/superx/bin/Doquery.java

@ -1,4 +1,5 @@
package de.superx.bin; package de.superx.bin;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -6,15 +7,17 @@ import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.StringTokenizer;
import java.util.logging.LogManager; import java.util.logging.LogManager;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.StringTokenizer;
import de.superx.util.SqlStringUtils; import de.superx.bin.Doschema.Format;
/** /**
* @author Daniel Quathamer Projektgruppe SuperX * @author Daniel Quathamer Projektgruppe SuperX
* doquery.java * doquery.java
@ -30,297 +33,265 @@ import de.superx.util.SqlStringUtils;
* 19.1.2006 dq: Unload großer Tabellen unter Postgres ermöglicht. * 19.1.2006 dq: Unload großer Tabellen unter Postgres ermöglicht.
*/ */
public class Doquery { public class Doquery {
private static Connection myDb; private static Connection myDb;
private static Statement st; // Our statement to run queries with
private static DatabaseMetaData dbmd; private static Statement st; // Our statement to run queries with
// This defines the structure of the database
private static boolean done = false; // Added by CWJ to permit \q command private static DatabaseMetaData dbmd;
private static String delim = "^";
private static String header = "false"; // This defines the structure of the database
private static String outFormat = "txt"; private static boolean done = false; // Added by CWJ to permit \q command
private static String logfile = "../conf/logging.properties";
private static String tabelle = ""; private static String delim = "^";
private static String dbpropfile = "../conf/db.properties";
private static SxConnection myConnection = null; private static String header = "false";
private static String db_driver;
private static String outfile = ""; private static Format outFormat = Format.txt;
private static Logger logger =
(Logger) Logger.getLogger(Doquery.class.toString()); private static String logfile = "../conf/logging.properties";
private static String usage =
"-------------------------------------\nGebrauch: java de.superx.SimpleTransform -logger=<<Pfad zu logging.properties>> -IN=<<xml-Datei>> -XSL=<<xsl-Datei>> -method=<<xml |html|text>>(optional) -param=<<Parameter>>(optional) -OUT=<<Ausgabedatei>>(optional) \n---------------------------------------------------"; private static String tabelle = "";
public static void go(String args[]) private static String dbpropfile = "../conf/db.properties";
throws
ClassNotFoundException, private static SxConnection myConnection = null;
FileNotFoundException,
IOException, private static String db_driver;
SQLException {
if (args.length > 0) { private static String outfile = "";
logfile = args[0].trim();
} else { private static Logger logger = (Logger) Logger.getLogger(Doquery.class.toString());
throw new IllegalArgumentException("Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, sql-String) erfoderlich");
private static String usage = "-------------------------------------\nGebrauch: java de.superx.SimpleTransform -logger=<<Pfad zu logging.properties>> -IN=<<xml-Datei>> -XSL=<<xsl-Datei>> -method=<<xml |html|text>>(optional) -param=<<Parameter>>(optional) -OUT=<<Ausgabedatei>>(optional) \n---------------------------------------------------";
}
File f = new File(logfile); public static void go(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException, IllegalArgumentException {
if (!f.exists()) { if (args.length > 0) {
throw new IOException("Datei nicht gefunden: " + logfile); logfile = args[0].trim();
} } else {
throw new IllegalArgumentException("Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, sql-String) erfoderlich");
FileInputStream ins = new FileInputStream(logfile);
LogManager MyLogManager = java.util.logging.LogManager.getLogManager(); }
MyLogManager.readConfiguration(ins); File f = new File(logfile);
logfile = MyLogManager.getProperty(".level"); if (!f.exists()) {
logger.info("Using Loggging-Level " + logfile); throw new IOException("Datei nicht gefunden: " + logfile);
String _sql = ""; }
if (args.length > 1) {
dbpropfile = args[1].trim(); FileInputStream ins = new FileInputStream(logfile);
} else { LogManager MyLogManager = java.util.logging.LogManager.getLogManager();
logger.severe( MyLogManager.readConfiguration(ins);
"Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, sql-String) erfoderlich"); logfile = MyLogManager.getProperty(".level");
System.exit(1); logger.info("Using Loggging-Level " + logfile);
} String _sql = "";
if (args.length > 2) { if (args.length > 1) {
_sql = args[2].trim(); dbpropfile = args[1].trim();
//DOS produces unnecessary ".." around the stmt } else {
if (_sql.length() > 0) { logger.severe("Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, sql-String) erfoderlich");
System.exit(1);
if (_sql.startsWith("\"")) }
_sql = _sql.substring(1, _sql.length()); if (args.length > 2) {
if (_sql.endsWith("\"")) _sql = args[2].trim();
_sql = _sql.substring(0, _sql.length() - 1); //DOS produces unnecessary ".." around the stmt
} if (_sql.length() > 0) {
} else { if (_sql.startsWith("\"")) _sql = _sql.substring(1, _sql.length());
logger.severe( if (_sql.endsWith("\"")) _sql = _sql.substring(0, _sql.length() - 1);
"Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, sql-String) erfoderlich"); }
System.exit(1);
} } else {
if (args.length > 3) { logger.severe("Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, sql-String) erfoderlich");
outFormat = args[3].trim(); System.exit(1);
} }
if (args.length > 3) {
if (args.length > 4) { //outFormat = args[3].trim();
delim = args[4].trim(); outFormat = Format.valueOf(args[3].trim().toLowerCase());
} }
if (args.length > 5) {
header = args[5].trim(); if (args.length > 4) {
delim = args[4].trim();
} }
if (args.length > 6) { if (args.length > 5) {
outfile = args[6].trim(); header = args[5].trim();
} }
if (delim.equals("")) if (args.length > 6) {
delim = "^"; //default Delimiter outfile = args[6].trim();
if (!outfile.equals(""))
{ }
try { if (delim.equals("")) delim = "^"; //default Delimiter
FileWriter f1 = new FileWriter(outfile); if (!outfile.equals("")) {
f1.write(""); try {
f1.close(); FileWriter f1 = new FileWriter(outfile);
} catch (IOException e) { f1.write("");
logger.severe ("Fehler beim Erstellen der Datei "+outfile); f1.close();
} } catch (IOException e) {
} logger.severe("Fehler beim Erstellen der Datei " + outfile);
getConnection(logger, dbpropfile); }
SxTransformer myTransformer = null; }
if (myConnection.m_DriverClass.equals("org.postgresql.Driver") getConnection(logger, dbpropfile);
&& !outfile.equals("") SxTransformer myTransformer = null;
&& outFormat.equals("txt") if (myConnection.m_DriverClass == SxConnection.DriverClass.dc_postgre && !outfile.equals("") && outFormat == Format.txt && !header.equals("true")) {
&& !header.equals("true")) //Postgres-Boost-Mode
{ logger.info("Unload with Postgres Boost mode");
//Postgres-Boost-Mode PreparedStatement l_stmt = null;
logger.info("Unload with Postgres Boost mode"); PreparedStatement l_stmtFetch = null;
PreparedStatement l_stmt = null; PreparedStatement l_stmtClose = null;
PreparedStatement l_stmtFetch = null; ResultSet l_rset = null;
PreparedStatement l_stmtClose = null; ResultSetMetaData l_mdat = null;
ResultSet l_rset = null; int l_rows;
ResultSetMetaData l_mdat=null; try { //exception
int l_rows;
try { //exception st = myDb.createStatement();
st = myDb.createStatement(); if (_sql.indexOf(";") > 0) {
String einzelsql = "";
if(_sql.indexOf(";")>0 ) //mehrere Statements hintereinander
{ StringTokenizer tk = new StringTokenizer(_sql, ";");
String einzelsql=""; for (; tk.hasMoreTokens();) {
//mehrere Statements hintereinander einzelsql = tk.nextToken();
StringTokenizer tk = new StringTokenizer(_sql, ";"); if (tk.hasMoreTokens())
for (; tk.hasMoreTokens();) { //das letzte SQL wird unten ausgeführt:
einzelsql = tk.nextToken(); st.execute(einzelsql);
if(tk.hasMoreTokens()) }
//das letzte SQL wird unten ausgeführt: _sql = einzelsql;
st.execute(einzelsql); }
} logger.info("Print Result of: " + _sql);
_sql=einzelsql;
} st.execute("Begin;");
logger.info("Print Result of: " + _sql); try { //finally
//open the cursor
st.execute( "Begin;");
try { //finally l_stmt = myConnection.prepareStatement("DECLARE FOO CURSOR FOR " + _sql);
//open the cursor l_stmt.execute();
l_stmt = myConnection.prepareStatement("DECLARE FOO CURSOR FOR "+_sql); l_stmtFetch = myConnection.prepareStatement("FETCH FORWARD 10000 FROM FOO");
l_stmt.execute(); l_rset = l_stmtFetch.executeQuery();
l_mdat = l_rset.getMetaData();
l_stmtFetch =myConnection.prepareStatement("FETCH FORWARD 10000 FROM FOO"); while (true) {
l_rset = l_stmtFetch.executeQuery(); //perform a fetch from the cursor (possibly multiple fetches will be done)
l_mdat= l_rset.getMetaData();
while (true) { if (l_rset.next() == false) break;
//perform a fetch from the cursor (possibly multiple fetches will be done) //l_rset.beforeFirst() ;
if(l_rset.next()==false) if (outfile.equals("")) {
break; myTransformer = new SxTransformer(logger, System.out);
//l_rset.beforeFirst() ; //myClient.setLogAllResultSetsToConsole(true);
} else
if (outfile.equals("")) myTransformer = new SxTransformer(logger, new FileWriter(outfile, true));
{ myTransformer = new SxTransformer(logger, System.out);
//myClient.setLogAllResultSetsToConsole(true); myTransformer.setDelim(delim);
} myTransformer.setHeader(header);
else
myTransformer = new SxTransformer(logger, new FileWriter(outfile,true)); myTransformer.setOutrs(l_rset);
myTransformer.setOutrsmd(l_mdat);
myTransformer.setDelim(delim); myTransformer.printResult(outFormat.name());
myTransformer.setHeader(header); l_rset = l_stmtFetch.executeQuery();
myTransformer.setOutrs(l_rset); }
myTransformer.setOutrsmd(l_mdat);
myTransformer.printResult(outFormat);
l_rset = l_stmtFetch.executeQuery(); //don't forget to close the cursor
l_stmtClose = myConnection.prepareStatement("CLOSE FOO");
} l_stmtClose.execute();
} finally {
if (l_rset != null) {
//don't forget to close the cursor l_rset.close();
l_stmtClose = myConnection.prepareStatement("CLOSE FOO"); }
l_stmtClose.execute(); if (l_stmt != null) {
} finally { l_stmt.close();
if (l_rset != null) { }
l_rset.close(); if (l_stmtFetch != null) {
} l_stmtFetch.close();
if (l_stmt != null) { }
l_stmt.close(); if (l_stmtClose != null) {
} l_stmtClose.close();
if (l_stmtFetch != null) { }
l_stmtFetch.close(); }
} } catch (SQLException l_se) {
if (l_stmtClose != null) { //do something useful here
l_stmtClose.close(); logger.severe("Fehler beim SQL " + _sql);
} l_se.printStackTrace();
} }
} catch (SQLException l_se) { st = myDb.createStatement();
//do something useful here //if (myConnection.m_DriverClass.equals("org.postgresql.Driver"))
logger.severe("Fehler beim SQL "+_sql); st.execute("commit;");
l_se.printStackTrace(); myConnection.close();
} } else {
st = myDb.createStatement(); //normaler Modus für IDS, Access und andere Exportformate ausser txt
//if (myConnection.m_DriverClass.equals("org.postgresql.Driver"))
st.execute( "commit;"); SxJdbcClient myClient = new SxJdbcClient(logger, dbpropfile, _sql);
myConnection.close() ;
}
else //logger.info("Executing sql: " + _sql);
{ myClient.Rs_executeALL();
//normaler Modus für IDS, Access und andere Exportformate ausser txt logger.info("Getting resultset");
ResultSet myrs = myClient.getRs();
SxJdbcClient myClient = new SxJdbcClient(logger, dbpropfile, _sql); //logger.info("Starting output for: " + _sql);
if (myrs != null && myrs.next()) {
if (outfile.equals("")) {
//logger.info("Executing sql: " + _sql); myTransformer = new SxTransformer(logger, System.out);
myClient.Rs_executeALL(); myClient.setLogAllResultSetsToConsole(true);
logger.info("Getting resultset") ; } else
ResultSet myrs = myClient.getRs(); myTransformer = new SxTransformer(logger, new FileWriter(outfile));
//logger.info("Starting output for: " + _sql);
if(myrs != null && myrs.next()) myTransformer.setDelim(delim);
{ myTransformer.setHeader(header);
if (outfile.equals(""))
{ myTransformer = new SxTransformer(logger, System.out); myTransformer.setOutrs(myrs);
myClient.setLogAllResultSetsToConsole(true); myTransformer.setOutrsmd(myClient.getRsmd());
} logger.info("Print Result of: " + _sql);
else
myTransformer = new SxTransformer(logger, new FileWriter(outfile)); myTransformer.printResult(outFormat.name());
myTransformer.setDelim(delim); }
myTransformer.setHeader(header); //else
// logger.info("Keine Rückgabewerte aus SQL-Script");
myTransformer.setOutrs(myrs); myClient.close();
myTransformer.setOutrsmd(myClient.getRsmd()); }
logger.info("Print Result of: " + _sql); logger.info("doquery erfolgreich beendet");
myTransformer.printResult(outFormat); }
} /*
else * Display some instructions on how to run the example
{ */
if(outFormat.equals("xml")) public static void instructions() {
{ System.out.println("SuperX @version@\n");
//create "empty" XML file System.out.println("\nDieses Java-Programm führt einen SQL-Ausdruck aus und gibt das Ergebnis aus.\n");
try { System.out.println("Gebrauch:\n java doquery <Pfad zu logger-properties> <pfad zu db.properties> <sql-Ausdruck> <Ausgabeformat (txt | html | xml)>(optional) <delimiter> <mit Spaltenüberschriften (true | false)>(optional) <Ausgabedatei>(optional)\n");
FileWriter f1 = new FileWriter(outfile); System.exit(1);
f1.write("<?xml version='1.0' encoding='"+SqlStringUtils.getEncoding()+"'?><rs></rs>"); }
f1.close();
} catch (IOException e) { public static void main(String args[]) {
logger.severe ("Fehler beim Erstellen der Datei "+outfile); try {
} go(args);
} catch (Exception ex) {
} System.err.println("Doquery Aufruf fehlgeschlagen.\n" + ex);
ex.printStackTrace();
} System.exit(1);
myClient.close(); }
} }
logger.info("doquery erfolgreich beendet");
public static void getConnection(Logger logger, String propFile) throws SQLException {
} myConnection = new SxConnection();
myConnection.setPropfile(propFile);
/* logger.config("Starting Connection...");
* Display some instructions on how to run the example try {
*/ myDb = myConnection.getConnection();
public static void instructions() { st = myDb.createStatement();
System.out.println("SuperX @version@\n"); //st = myDb.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
System.out.println( // java.sql.ResultSet.CONCUR_READ_ONLY);
"\nDieses Java-Programm führt einen SQL-Ausdruck aus und gibt das Ergebnis aus.\n"); //st.setFetchSize(100);
System.out.println( dbmd = myDb.getMetaData();
"Gebrauch:\n java doquery <Pfad zu logger-properties> <pfad zu db.properties> <sql-Ausdruck> <Ausgabeformat (txt | html | xml)>(optional) <delimiter> <mit Spaltenüberschriften (true | false)>(optional) <Ausgabedatei>(optional)\n"); //st = myDb.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
System.exit(1); //ResultSet.CONCUR_UPDATABLE);
} } catch (Exception e) {
e.printStackTrace();
public static void main(String args[]) { logger.severe("Keine DB-Verbindung: " + e.toString());
//args=new String[7]; throw new SQLException("Keine DB-Verbindung: " + e.toString());
//args[0]="e:\\superx\\logging.properties"; }
//args[1]="e:/superx/db.properties"; db_driver = myConnection.m_DriverClass.stringValue();
//args[2]="select * from sos_stud_allg_cube";; ;
//args[3]="txt"; }
//args[4]="^";
//args[5]="false";
//args[6]="e:/superx/test.unl";
try {
go(args);
} catch (Exception ex) {
System.err.println("Doquery Aufruf fehlgeschlagen.\n" + ex);
ex.printStackTrace();
System.exit(1);
}
}
public static void getConnection(Logger logger,String propFile) throws SQLException {
myConnection = new SxConnection();
myConnection.setPropfile(propFile);
logger.config("Starting Connection...");
try {
myDb = myConnection.getConnection();
st = myDb.createStatement();
//st = myDb.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
// java.sql.ResultSet.CONCUR_READ_ONLY);
//st.setFetchSize(100);
dbmd = myDb.getMetaData();
//st = myDb.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
//ResultSet.CONCUR_UPDATABLE);
} catch (Exception e) {
e.printStackTrace();
logger.severe("Keine DB-Verbindung: " + e.toString());
throw new SQLException("Keine DB-Verbindung: " + e.toString());
}
db_driver = myConnection.m_DriverClass;
}
} }

254
src/de/superx/bin/Doschema.java

@ -1,4 +1,5 @@
package de.superx.bin; package de.superx.bin;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -13,8 +14,8 @@ import java.util.logging.Logger;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import de.memtext.util.ExceptionHandler;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
import de.superx.util.SqlStringUtils; import de.superx.util.SqlStringUtils;
/* /*
@ -31,163 +32,158 @@ import de.superx.util.SqlStringUtils;
* Die xsl-Stylesheets für HIS (tabschema_his.xsl), Postgres (tabschema_sql_pg.xsl) und Informix (tabschema_sql_ids.xsl) müssen im gleichen Verzeichnis wie die logger-properties stehen * Die xsl-Stylesheets für HIS (tabschema_his.xsl), Postgres (tabschema_sql_pg.xsl) und Informix (tabschema_sql_ids.xsl) müssen im gleichen Verzeichnis wie die logger-properties stehen
*/ */
public class Doschema public class Doschema {
{
public enum Format {
xml, ansi, his, pg, ids, txt, html;
}
Connection myDb; Connection myDb;
Statement st;
Statement st;
Statement updateSt; Statement updateSt;
DatabaseMetaData dbmd;
boolean done = false; DatabaseMetaData dbmd;
boolean done = false;
String delim = ""; String delim = "";
String header="false";
String logfile="../conf/logging.properties"; String header = "false";
String dbpropfile="./conf/db.properties";
String tabelle=""; String logfile = "../conf/logging.properties";
String outFormat="xml";
String dbpropfile = "./conf/db.properties";
Logger logger= (Logger) Logger.getLogger(Doschema.class.toString());
private ExceptionHandler exceptionHandler = new ExceptionHandler(false); String tabelle = "";
private static String usage="-------------------------------------\n"+
"Gebrauch: java de.superx.bin.Doschema -logger:<<Pfad zu logging.properties>> -dbproperties:<<Pfad zu db.properties>> " + Format outFormat = Format.xml;
"-table:<Tabelle> -outFormat:<Ausgabeformat (xml | HIS | pg | ids | ansi ) -outfile:<Ausgabedatei>(optional) \n---------------------------------------------------";
Logger logger = (Logger) Logger.getLogger(Doschema.class.toString());
public Doschema(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException
{ private static String usage = "-------------------------------------\n"
String outfile = ""; + "Gebrauch: java de.superx.bin.Doschema -logger:<<Pfad zu logging.properties>> -dbproperties:<<Pfad zu db.properties>> "
GetOpts.setOpts(args); + "-table:<Tabelle> -outFormat:<Ausgabeformat (xml | HIS | pg | ids | ansi ) -outfile:<Ausgabedatei>(optional) \n---------------------------------------------------";
String isdrin= GetOpts.isAllRequiredOptionsPresent("-logger,-dbproperties");
if(isdrin != null) public Doschema(String args[])
{ throws ClassNotFoundException, FileNotFoundException, IOException, SQLException, IllegalArgumentException {
String outfile = "";
GetOpts.setOpts(args);
String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[] { Options.opt_logger, Options.opt_dbprops });
if (isdrin != null) {
System.err.println("Folgende Optionen fehlen: " + isdrin); System.err.println("Folgende Optionen fehlen: " + isdrin);
System.err.println(usage); System.err.println(usage);
System.exit(1); System.exit(1);
} }
//GetOpts myOpts=new GetOpts(); // GetOpts myOpts=new GetOpts();
if (GetOpts.isPresent("-logger")) if (GetOpts.isPresent(Options.opt_logger))
logfile=GetOpts.getValue("-logger" ); logfile = GetOpts.getValue(Options.opt_logger);
if (GetOpts.isPresent("-dbproperties")) if (GetOpts.isPresent(Options.opt_dbprops))
dbpropfile=GetOpts.getValue("-dbproperties" ); dbpropfile = GetOpts.getValue(Options.opt_dbprops);
if (GetOpts.isPresent("-table")) if (GetOpts.isPresent(Options.opt_table))
tabelle=GetOpts.getValue("-table" ); tabelle = GetOpts.getValue(Options.opt_table);
if (GetOpts.isPresent("-outFormat")) // if (GetOpts.isPresent("-outFormat")) outFormat =
outFormat=GetOpts.getValue("-outFormat" ); // GetOpts.getValue("-outFormat");
if (GetOpts.isPresent("-outfile")) if (GetOpts.isPresent(Options.opt_outFile))
outfile=GetOpts.getValue("-outfile" ); outfile = GetOpts.getValue(Options.opt_outFile);
File f = new File(logfile); if (GetOpts.isPresent(Options.opt_outFormat)) {
String confPath=f.getParent() ; outFormat = Format.valueOf(GetOpts.getValue(Options.opt_outFormat).toLowerCase());
if (!f.exists())
{ throw new IOException("Datei nicht gefunden: " + logfile);
}
FileInputStream ins = new FileInputStream(logfile);
LogManager MyLogManager = java.util.logging.LogManager.getLogManager();
MyLogManager.readConfiguration(ins);
logfile=MyLogManager.getProperty(".level");
logger.info("Using Loggging-Level " + logfile);
logger.config("Getting Schema.");
SxJdbcClient myClient=new SxJdbcClient(logger, dbpropfile);
//OutputStream out=new OutputStream();
//OutputStreamWriter Outwriter=new OutputStreamWriter(out);
logger.config("Tabellenkatalog für " + tabelle);
String zs ="";
zs= "<?xml version='1.0' encoding='"+SqlStringUtils.getEncoding()+"'?>"+ "\n";
//zs+="<table name=\""+tabelle+"\">\n";
zs += myClient.getTableSchema (tabelle) + "\n";
SxTransformer myTransformer=null;
if(outfile.equals(""))
myTransformer = new SxTransformer(logger,System.out);
else
myTransformer = new SxTransformer(logger,new FileWriter(outfile));
myTransformer.quellstring=zs;
if(outFormat.equals("his"))
{
myTransformer.stylesheet=confPath+System.getProperty("file.separator")+"tabschema_his.xsl";
try
{
myTransformer.transformString("xml") ;
}
catch (TransformerException e)
{
logger.severe("XSL-Transformation fehlgeschlagen:" + e.toString());
exceptionHandler.handle( e);
}
catch (Exception e)
{
logger.severe("XSL-Transformation fehlgeschlagen:" + e.toString());
exceptionHandler.handle( e);
} }
} File f = new File(logfile);
else String confPath = f.getParent();
{ if (!f.exists()) {
if(outFormat.equals("pg") || outFormat.equals("ids") || outFormat.equals("ansi")) throw new IOException("Datei nicht gefunden: " + logfile);
{ }
myTransformer.stylesheet=confPath+System.getProperty("file.separator")+"tabschema_sql_"+outFormat+".xsl"; FileInputStream ins = new FileInputStream(logfile);
myTransformer.format=outFormat; LogManager MyLogManager = java.util.logging.LogManager.getLogManager();
try MyLogManager.readConfiguration(ins);
{ logfile = MyLogManager.getProperty(".level");
myTransformer.transformString("text") ; logger.info("Using Loggging-Level " + logfile);
logger.config("Getting Schema.");
SxJdbcClient myClient = new SxJdbcClient(logger, dbpropfile);
// OutputStream out=new OutputStream();
// OutputStreamWriter Outwriter=new OutputStreamWriter(out);
logger.config("Tabellenkatalog für " + tabelle);
String zs = "";
zs = "<?xml version='1.0' encoding='" + SqlStringUtils.getEncoding() + "'?>" + "\n";
// zs+="<table name=\""+tabelle+"\">\n";
zs += myClient.getTableSchema(tabelle) + "\n";
SxTransformer myTransformer = null;
if (outfile.equals(""))
myTransformer = new SxTransformer(logger, System.out);
else
myTransformer = new SxTransformer(logger, new FileWriter(outfile));
myTransformer.quellstring = zs;
if (outFormat == Format.his) {
myTransformer.stylesheet = confPath + System.getProperty("file.separator") + "tabschema_his.xsl";
try {
myTransformer.transformString(Format.xml.name());
} catch (TransformerException e) {
System.out.println("XSL-Transformation fehlgeschlagen:" + e.toString());
e.printStackTrace();
System.exit(-1);
} }
catch (TransformerException e)
{ } else {
logger.severe("XSL-Transformation nach sql fehlgeschlagen:" + e.toString()); if (outFormat == Format.pg || outFormat == Format.ids || outFormat == Format.ansi) {
exceptionHandler.handle( e); myTransformer.stylesheet = confPath + System.getProperty("file.separator") + "tabschema_sql_"
+ outFormat.name() + ".xsl";
myTransformer.format = outFormat.name();
try {
myTransformer.transformString(Format.txt.name());
} catch (Exception e) {
System.out.println("XSL-Transformation nach sql fehlgeschlagen:" + e.toString());
e.printStackTrace();
System.exit(-1);
}
} }
catch (Exception e)
{ else {
logger.severe("XSL-Transformation nach sql fehlgeschlagen:" + e.toString()); // simple xml-Output
exceptionHandler.handle( e); myTransformer.outputString();
} }
} }
logger.info("Now closing the connection");
else // st.close();
{ myClient.close();
//simple xml-Output
myTransformer.outputString();
}
}
logger.info("Now closing the connection");
//st.close();
myClient.close();
}
}
/* /*
* Display some instructions on how to run the example * Display some instructions on how to run the example
*/ */
public static void instructions() public static void instructions() {
{
System.out.println("SuperX @version@\n"); System.out.println("SuperX @version@\n");
System.out.println("\nDieses Javaprogramm gibt des Schema einer Tabelle aus"); System.out.println("\nDieses Javaprogramm gibt des Schema einer Tabelle aus");
System.out.println("Im Classpath muss superx-db.jar,sowie der zugehörige jdbc-Treiber sein."); System.out.println("Im Classpath muss superx-db.jar,sowie der zugehörige jdbc-Treiber sein.");
System.out.println("Befehl:\n java doschema <Tabellenname> <Ausgabeformat (txt|xml)>(optional) <delimiter>(optional) <Ausgabe der Feldüberschriften (optional, true oder false). <Ausgabedatei>(optional)"); System.out.println(
System.out.println("Der Logging-Level wird in ../conf/logging.properties konfiguriert, der DB-Zugriff in ../conf/db.properties "); "Befehl:\n java doschema <Tabellenname> <Ausgabeformat (txt|xml)>(optional) <delimiter>(optional) <Ausgabe der Feldüberschriften (optional, true oder false). <Ausgabedatei>(optional)");
System.out.println(
System.out.println("Default:\n java -cp .:$JDBC_CLASSPATH de.superx.bin.Doschema $LOGGER_PROPERTIES $DB_PROPERTIES $tabelle ansi"); "Der Logging-Level wird in ../conf/logging.properties konfiguriert, der DB-Zugriff in ../conf/db.properties ");
System.out.println(
"Default:\n java -cp .:$JDBC_CLASSPATH de.superx.bin.Doschema $LOGGER_PROPERTIES $DB_PROPERTIES $tabelle ansi");
System.exit(1); System.exit(1);
} }
/* /*
* This little lot starts the test * This little lot starts the test
*/ */
public static void main(String args[]) public static void main(String args[]) {
{ // System.out.println("SuperX-Tool DoSchema V.2.03\n");
//System.out.println("SuperX-Tool DoSchema V.2.03\n");
if (args.length < 1) if (args.length < 1) {
instructions(); instructions();
}
try {
try
{
Doschema test = new Doschema(args); Doschema test = new Doschema(args);
} } catch (Exception ex) {
catch (Exception ex)
{
System.err.println("Exception caught.\n" + ex); System.err.println("Exception caught.\n" + ex);
ex.printStackTrace(); ex.printStackTrace();

453
src/de/superx/bin/Dosql.java

@ -1,236 +1,217 @@
package de.superx.bin; package de.superx.bin;
import java.io.BufferedReader;
import java.io.File; import java.io.BufferedReader;
import java.io.FileInputStream; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileInputStream;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.Statement;
import java.sql.Statement; import java.util.StringTokenizer;
import java.util.StringTokenizer; import java.util.logging.LogManager;
import java.util.logging.LogManager; import java.util.logging.Logger;
import java.util.logging.Logger;
import de.memtext.util.GetOpts;
import de.memtext.util.ExceptionHandler; import de.memtext.util.GetOpts.Options;
import de.memtext.util.GetOpts; import de.superx.bin.Doschema.Format;
/** /**
* @author Daniel Quathamer Projektgruppe SuperX * @author Daniel Quathamer Projektgruppe SuperX
* Dosql.java * Dosql.java
* @ * @
* Dieses Javaprogramm führt einen oder mehrere SQL-Ausdrück in einer Datei aus und gibt das Ergebnis aus.<br> * Dieses Javaprogramm führt einen oder mehrere SQL-Ausdrück in einer Datei aus und gibt das Ergebnis aus.<br>
* Gebrauch:<br> java dosql <Pfad zu logger-properties> <pfad zu db.properties> <Datei mit sql-Ausdrücken> <Ausgabeformat (txt | html | xml)>(optional) <delimiter> <mit Spaltenüberschriften (true | false)>(optional) <Ausgabedatei>(optional) * Gebrauch:<br> java dosql <Pfad zu logger-properties> <pfad zu db.properties> <Datei mit sql-Ausdrücken> <Ausgabeformat (txt | html | xml)>(optional) <delimiter> <mit Spaltenüberschriften (true | false)>(optional) <Ausgabedatei>(optional)
* *
*/ */
/* Änderungen /* Änderungen
15.4.2004 MB wenn keine Ausgabedatei und Ausgabeformat txt, alle selects von SxJdbcClient 15.4.2004 MB wenn keine Ausgabedatei und Ausgabeformat txt, alle selects von SxJdbcClient
loggen lassen loggen lassen
6.4.2004 MB Code static main verlegt - nach erfolgreicher Durchführung ein system.out 6.4.2004 MB Code static main verlegt - nach erfolgreicher Durchführung ein system.out
**/ **/
public class Dosql { public class Dosql {
private static Connection myDb; private static Connection myDb;
private static Statement st; // Our statement to run queries with
private static boolean done = false; // Added by CWJ to permit \q command private static Statement st; // Our statement to run queries with
private static String delim = "^";
private static String header = "false"; private static boolean done = false; // Added by CWJ to permit \q command
private static String logfile = "../conf/logging.properties";
private static String tabelle = ""; private static String delim = "^";
private static String dbpropfile = "../conf/db.properties";
private static String outfile = ""; private static String header = "false";
private static String outFormat = "txt";
private static String _dateiPfad = ""; private static String logfile = "../conf/logging.properties";
//LogUtils logger=null;
private static Logger logger = private static String tabelle = "";
(Logger) Logger.getLogger(Dosql.class.toString());
//static Logger logger = Logger.getLogger(dosql.class); private static String dbpropfile = "../conf/db.properties";
private static ExceptionHandler exceptionHandler =
new ExceptionHandler(false); private static String outfile = "";
private static String usage =
"-------------------------------------\n" private static Format outFormat = Format.txt;
+ "Gebrauch: java de.superx.bin.Dosql -logger=<<Pfad zu logging.properties>> -dbproperties=<<Pfad zu db.properties>> "
+ "-sqlfile:<Datei mit sql-Ausdrücken> -params:<Parameter, die in sql- oder Script-Dateien ersetzt werden; Syntax:param1=wert1,param2=wert2 etc> -outFormat:<Ausgabeformat (txt | html | xml)>(optional) -delim:<delimiter> -header:<mit Spaltenüberschriften (true | false)>(optional) -outfile:<Ausgabedatei>(optional) \n---------------------------------------------------"; private static String _dateiPfad = "";
/* //LogUtils logger=null;
* Display some instructions on how to run the example private static Logger logger = (Logger) Logger.getLogger(Dosql.class.toString());
*/
public static void instructions() { //static Logger logger = Logger.getLogger(dosql.class);
System.out.println("SuperX @version@\n");
System.out.println(
"\nDieses Javaprogramm führt ein beliebiges sql-Script mit einer oder mehr sql-Anweisungen aus"); private static String usage = "-------------------------------------\n"
System.out.println( + "Gebrauch: java de.superx.bin.Dosql -logger=<<Pfad zu logging.properties>> -dbproperties=<<Pfad zu db.properties>> "
"Im Classpath muss superx@version@.jar sowie der zugehörige jdbc-Treiber sein."); + "-sqlfile:<Datei mit sql-Ausdrücken> -params:<Parameter, die in sql- oder Script-Dateien ersetzt werden; Syntax:param1=wert1,param2=wert2 etc> -outFormat:<Ausgabeformat (txt | html | xml)>(optional) -delim:<delimiter> -header:<mit Spaltenüberschriften (true | false)>(optional) -outfile:<Ausgabedatei>(optional) \n---------------------------------------------------";
System.out.println(
"Befehl:\n java dosql <Dateipfad sql-Script> <delimiter>(optional) <Ausgabe der Feldüberschriften (optional, true oder false)."); /*
System.out.println( * Display some instructions on how to run the example
"Default:\n java dosql <Dateipfad sql-Script> <TAB> true"); */
System.exit(1); public static void instructions() {
} System.out.println("SuperX @version@\n");
System.out.println("\nDieses Javaprogramm führt ein beliebiges sql-Script mit einer oder mehr sql-Anweisungen aus");
public static void main(String args[]) { System.out.println("Im Classpath muss superx@version@.jar sowie der zugehörige jdbc-Treiber sein.");
try { System.out.println("Befehl:\n java dosql <Dateipfad sql-Script> <delimiter>(optional) <Ausgabe der Feldüberschriften (optional, true oder false).");
execute(args); System.out.println("Default:\n java dosql <Dateipfad sql-Script> <TAB> true");
} catch (Exception e) { System.exit(1);
logger.severe( }
"Fehler beim sql-Script: " + _dateiPfad + " " + e.toString());
e.printStackTrace(); public static void main(String args[]) {
System.exit(1); try {
} execute(args);
} catch (Exception e) {
} logger.severe("Fehler beim sql-Script: " + _dateiPfad + " " + e.toString());
e.printStackTrace();
public static void execute(String[] args) System.exit(1);
throws Exception { }
String params = ""; }
GetOpts.setOpts(args);
String isdrin = public static void execute(String[] args) throws Exception {
GetOpts.isAllRequiredOptionsPresent(
"-logger,-dbproperties,-sqlfile"); String params = "";
if (isdrin != null) { GetOpts.setOpts(args);
System.err.println("Folgende Optionen fehlen: " + isdrin); String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[]{Options.opt_logger,Options.opt_dbprops,Options.opt_sql});
System.err.println(usage); if (isdrin != null) {
System.exit(1); System.err.println("Folgende Optionen fehlen: " + isdrin);
} System.err.println(usage);
System.exit(1);
//GetOpts myOpts=new GetOpts(); }
if (GetOpts.isPresent("-logger"))
logfile = GetOpts.getValue("-logger"); //GetOpts myOpts=new GetOpts();
if (GetOpts.isPresent("-dbproperties")) if (GetOpts.isPresent(Options.opt_logger)) logfile = GetOpts.getValue(Options.opt_logger);
dbpropfile = GetOpts.getValue("-dbproperties"); if (GetOpts.isPresent(Options.opt_dbprops)) dbpropfile = GetOpts.getValue(Options.opt_dbprops);
if (GetOpts.isPresent("-sqlfile")) if (GetOpts.isPresent(Options.opt_sql)) _dateiPfad = GetOpts.getValue(Options.opt_sql);
_dateiPfad = GetOpts.getValue("-sqlfile"); //if (GetOpts.isPresent("-outFormat")) outFormat = GetOpts.getValue("-outFormat");
if (GetOpts.isPresent("-outFormat")) if (GetOpts.isPresent(Options.opt_delim)) delim = GetOpts.getValue(Options.opt_delim);
outFormat = GetOpts.getValue("-outFormat"); if (GetOpts.isPresent(Options.opt_header)) header = GetOpts.getValue(Options.opt_header);
if (GetOpts.isPresent("-delim")) if (GetOpts.isPresent(Options.opt_outFile)) outfile = GetOpts.getValue(Options.opt_outFile);
delim = GetOpts.getValue("-delim"); if (GetOpts.isPresent(Options.opt_params)) params = GetOpts.getValue(Options.opt_params);
if (GetOpts.isPresent("-header"))
header = GetOpts.getValue("-header"); if(GetOpts.isPresent(Options.opt_outFormat)) {
if (GetOpts.isPresent("-outfile")) outFormat = Format.valueOf(GetOpts.getValue(Options.opt_outFormat).toLowerCase());
outfile = GetOpts.getValue("-outfile"); }
if (GetOpts.isPresent("-params"))
params = GetOpts.getValue("-params"); if (delim.equals("")) delim = "^"; //default Delimiter
if (delim.equals("")) //logger.initRaw(dosql.class)
delim = "^"; //default Delimiter //PropertyConfigurator.configure(logfile);
File f = new File(logfile);
//logger.initRaw(dosql.class) if (!f.exists()) {
//PropertyConfigurator.configure(logfile); throw new IOException("Datei nicht gefunden: " + logfile);
File f = new File(logfile); }
if (!f.exists()) { FileInputStream ins = new FileInputStream(logfile);
throw new IOException("Datei nicht gefunden: " + logfile); LogManager MyLogManager = java.util.logging.LogManager.getLogManager();
} MyLogManager.readConfiguration(ins);
FileInputStream ins = new FileInputStream(logfile); logfile = MyLogManager.getProperty(".level");
LogManager MyLogManager = java.util.logging.LogManager.getLogManager(); logger.info("Using Loggging-Level " + logfile);
MyLogManager.readConfiguration(ins);
logfile = MyLogManager.getProperty(".level"); f = new File(_dateiPfad);
logger.info("Using Loggging-Level " + logfile); if (!f.exists()) {
throw new IOException("Datei nicht gefunden: " + _dateiPfad);
f = new File(_dateiPfad); }
if (!f.exists()) { BufferedReader in;
throw new IOException("Datei nicht gefunden: " + _dateiPfad); //--- InputStream generieren ---//
} in = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
BufferedReader in;
//--- InputStream generieren ---// //--- Verarbeiten der Datei ---//
in = new BufferedReader(new InputStreamReader(new FileInputStream(f))); String sql = "";
String text = "";
//--- Verarbeiten der Datei ---// while ((text = in.readLine()) != null) {
String sql = ""; //MB auskommentiert 27.4.05
String text = ""; //löschte ( in
while ((text = in.readLine()) != null) { //insert into
//MB auskommentiert 27.4.05 //(
//löschte ( in //tid,...
//insert into //if (text.length() > 1)
//( sql += System.getProperty("line.separator") + text.trim();
//tid,... }
//if (text.length() > 1) in.close();
sql += System.getProperty("line.separator") + text.trim(); if (sql.toLowerCase().indexOf("<xupdate>") > -1) {
} SxConnection myConnection = new SxConnection();
in.close(); myConnection.setPropfile(dbpropfile);
if (sql.toLowerCase().indexOf("<xupdate>")>-1) Connection con = myConnection.getConnection();
{
SxConnection myConnection = new SxConnection(); new XUpdater().execute(con, myConnection.getDatabaseAbbr(), sql, logger);
myConnection.setPropfile(dbpropfile); } else {
Connection con = myConnection.getConnection(); if (sql.toLowerCase().indexOf("--freemarker template") > -1) {
new XUpdater().execute(con, myConnection.getDatabaseAbbr(), sql,logger); try {
} sql = de.superx.bin.FMParser.simpleParser(dbpropfile, sql);
else } catch (Exception e) {
{
if(sql.toLowerCase().indexOf("--freemarker template")>-1) e.printStackTrace();
{ }
}
try { sql = sql.trim();
sql=de.superx.bin.FMParser.simpleParser(dbpropfile, sql); if (sql.startsWith("\"")) sql = sql.substring(1, sql.length());
} catch (Exception e) { if (sql.endsWith("\"")) sql = sql.substring(0, sql.length() - 1);
e.printStackTrace(); logger.config("Inhalt der sql-Datei: \n--" + sql + "--");
} //First the params are replaced:
} if (!params.equals("")) {
sql = sql.trim(); if (!params.endsWith("|")) params += "|";
if (sql.startsWith("\"")) StringTokenizer st = new StringTokenizer(params, "|");
sql = sql.substring(1, sql.length()); for (; st.hasMoreTokens();) {
if (sql.endsWith("\"")) String param = st.nextToken();
sql = sql.substring(0, sql.length() - 1); if (!param.equals("")) {
String paramname = param.substring(0, param.indexOf("="));
logger.config("Inhalt der sql-Datei: \n--" + sql + "--"); String paramvalue = param.substring(param.indexOf("=") + 1, param.length());
//First the params are replaced: sql = de.superx.bin.SxDBUtils.replaceString(sql, paramname, paramvalue);
if (!params.equals("")) { }
if (!params.endsWith("|")) }
params += "|"; }
StringTokenizer st = new StringTokenizer(params, "|"); SxJdbcClient myClient = new SxJdbcClient(logger, dbpropfile, sql);
for (; st.hasMoreTokens();) { if (outfile.equals("") && outFormat == Format.txt) myClient.setLogAllResultSetsToConsole(true);
String param = st.nextToken(); SxTransformer myTransformer = null;
if (!param.equals("")) {
String paramname = param.substring(0, param.indexOf("=")); myClient.Rs_executeALL();
String paramvalue = ResultSet myrs = myClient.getRs();
param.substring(param.indexOf("=") + 1, param.length());
sql = if (myrs != null) {
de.superx.bin.SxDBUtils.replaceString( if (outfile.equals("")) {
sql, myTransformer = new SxTransformer(logger, System.out);
paramname, } else
paramvalue); myTransformer = new SxTransformer(logger, new FileWriter(outfile));
}
} if (!outfile.equals("") || outFormat != Format.txt) {
}
SxJdbcClient myClient = new SxJdbcClient(logger, dbpropfile, sql); myTransformer.setDelim(delim);
if (outfile.equals("")&&outFormat.equalsIgnoreCase("txt")) myTransformer.setHeader(header);
myClient.setLogAllResultSetsToConsole(true);
SxTransformer myTransformer = null; myTransformer.setOutrs(myrs);
myTransformer.setOutrsmd(myClient.getRsmd());
myClient.Rs_executeALL(); myTransformer.printResult(outFormat.name());
ResultSet myrs = myClient.getRs(); }
} else
if (myrs != null) { logger.info("Keine Rückgabewerte aus SQL-Script");
if (outfile.equals("")) { myClient.close();
myTransformer = new SxTransformer(logger, System.out); }
} else System.out.println("Dosql hat das Script " + _dateiPfad + " erfolgreich durchgeführt");
myTransformer = logger.info("dosql erfolgreich beendet");
new SxTransformer(logger, new FileWriter(outfile));
}
if (!outfile.equals("")||!outFormat.equalsIgnoreCase("txt")) }
{
myTransformer.setDelim(delim);
myTransformer.setHeader(header);
myTransformer.setOutrs(myrs);
myTransformer.setOutrsmd(myClient.getRsmd());
myTransformer.printResult(outFormat);
}
} else
logger.info("Keine Rückgabewerte aus SQL-Script");
myClient.close();
}
System.out.println(
"Dosql hat das Script " + _dateiPfad + " erfolgreich durchgeführt");
logger.info("dosql erfolgreich beendet");
}
}

298
src/de/superx/bin/Dostmt.java

@ -1,4 +1,5 @@
package de.superx.bin; package de.superx.bin;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -13,7 +14,7 @@ import java.sql.Statement;
import java.util.logging.LogManager; import java.util.logging.LogManager;
import java.util.logging.Logger; import java.util.logging.Logger;
import de.memtext.util.ExceptionHandler; import de.superx.bin.Doschema.Format;
/** /**
@ -24,159 +25,146 @@ import de.memtext.util.ExceptionHandler;
* Gebrauch:<br> java dostmt <Pfad zu logger-properties> <pfad zu db.properties> <Datwei mit sql-Ausdruck> * Gebrauch:<br> java dostmt <Pfad zu logger-properties> <pfad zu db.properties> <Datwei mit sql-Ausdruck>
* Für mehrere SQL-Ausdrücke führen sie bitte dosql aus. * Für mehrere SQL-Ausdrücke führen sie bitte dosql aus.
*/ */
public class Dostmt public class Dostmt {
{ Connection myDb;
Connection myDb;
Statement st; // Our statement to run queries with Statement st; // Our statement to run queries with
boolean done = false; // Added by CWJ to permit \q command
String delim = "\n"; boolean done = false; // Added by CWJ to permit \q command
String header="false";
String logfile="../conf/logging.properties"; String delim = "\n";
String tabelle="";
String dbpropfile="../conf/db.properties"; String header = "false";
String outfile="";
String outFormat="txt"; String logfile = "../conf/logging.properties";
//LogUtils logger=null;
Logger logger= (Logger) Logger.getLogger(Dostmt.class.toString()); String tabelle = "";
//static Logger logger = Logger.getLogger(dosql.class);
private ExceptionHandler exceptionHandler = new ExceptionHandler(false); String dbpropfile = "../conf/db.properties";
public Dostmt(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException String outfile = "";
{
Format outFormat = Format.txt;
if (args.length > 0)
{ //LogUtils logger=null;
logfile=args[0].trim(); Logger logger = (Logger) Logger.getLogger(Dostmt.class.toString());
}
else //static Logger logger = Logger.getLogger(dosql.class);
{ //private ExceptionHandler exceptionHandler = new ExceptionHandler(false);
System.err.println("Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, Pfad zur SQL-Datei) erfoderlich");
System.exit(1); public Dostmt(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException {
}
//logger.initRaw(dosql.class) if (args.length > 0) {
//PropertyConfigurator.configure(logfile); logfile = args[0].trim();
File f = new File(logfile); } else {
if (!f.exists()) System.err.println("Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, Pfad zur SQL-Datei) erfoderlich");
{ throw new IOException("Datei nicht gefunden: " + logfile); System.exit(1);
} }
FileInputStream ins = new FileInputStream(logfile); //logger.initRaw(dosql.class)
LogManager MyLogManager = java.util.logging.LogManager.getLogManager(); //PropertyConfigurator.configure(logfile);
MyLogManager.readConfiguration(ins); File f = new File(logfile);
logfile=MyLogManager.getProperty(".level"); if (!f.exists()) {
logger.info("Using Loggging-Level " + logfile); throw new IOException("Datei nicht gefunden: " + logfile);
}
String _dateiPfad = ""; FileInputStream ins = new FileInputStream(logfile);
if (args.length > 1) LogManager MyLogManager = java.util.logging.LogManager.getLogManager();
{ MyLogManager.readConfiguration(ins);
dbpropfile=args[1].trim(); logfile = MyLogManager.getProperty(".level");
} logger.info("Using Loggging-Level " + logfile);
else
{ String _dateiPfad = "";
logger.severe("Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, Pfad zur SQL-Datei) erfoderlich"); if (args.length > 1) {
System.exit(1); dbpropfile = args[1].trim();
} } else {
if (args.length > 2) logger.severe("Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, Pfad zur SQL-Datei) erfoderlich");
{ System.exit(1);
_dateiPfad=args[2].trim(); }
} if (args.length > 2) {
else _dateiPfad = args[2].trim();
{ } else {
logger.severe("Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, Pfad zur SQL-Datei) erfoderlich"); logger.severe("Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, Pfad zur SQL-Datei) erfoderlich");
System.exit(1); System.exit(1);
} }
f = new File(_dateiPfad); f = new File(_dateiPfad);
if (!f.exists()) if (!f.exists()) {
{ throw new IOException("Datei nicht gefunden: " + _dateiPfad); throw new IOException("Datei nicht gefunden: " + _dateiPfad);
} }
BufferedReader in; BufferedReader in;
//--- InputStream generieren ---// //--- InputStream generieren ---//
in = new BufferedReader(new InputStreamReader( in = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
new FileInputStream(f) ));
//--- Verarbeiten der Datei ---//
//--- Verarbeiten der Datei ---// String sql = "";
String sql=""; String text = "";
String text=""; while ((text = in.readLine()) != null) {
while ((text = in.readLine()) != null) if (text.length() > 1) sql += System.getProperty("line.separator") + text.trim();
{ }
if(text.length()>1) in.close();
sql+=System.getProperty("line.separator")+ text.trim(); logger.config("Inhalt von sql-Datei: \n" + sql);
SxJdbcClient myClient = new SxJdbcClient(logger, dbpropfile, sql);
try {
SxTransformer myTransformer = null;
myClient.execute();
ResultSet myrs = myClient.getRs();
if (myrs != null) {
if (outfile.equals(""))
myTransformer = new SxTransformer(logger, System.out);
else
myTransformer = new SxTransformer(logger, new FileWriter(outfile));
myTransformer.setDelim(delim);
myTransformer.setHeader(header);
myTransformer.setOutrs(myrs);
myTransformer.setOutrsmd(myClient.getRsmd());
myTransformer.printResult(outFormat.name());
} else
logger.info("Keine Rückgabewerte aus SQL-Script");
myClient.close();
} catch (SQLException e) {
logger.severe("Fehler beim sql-Script: " + e.toString());
System.exit(-1);
}
logger.info("dosql erfolgreich beendet");
}
/*
* Display some instructions on how to run the example
*/
public static void instructions() {
System.out.println("\nDieses Javaprogramm führt ein beliebiges sql-Script mit einer oder mehr sql-Anweisungen aus");
System.out.println("Im Classpath muss superx-db.jar sowie der zugehörige jdbc-Treiber sein.");
System.out.println("Befehl:\n java dosql <Dateipfad sql-Script> <delimiter>(optional) <Ausgabe der Feldüberschriften (optional, true oder false).");
System.out.println("Default:\n java dosql <Dateipfad sql-Script> <TAB> true");
System.exit(1);
}
/*
* This little lot starts the test
*/
public static void main(String args[]) {
//System.out.println("PostgreSQL psql example v6.3 rev 1\n");
//if (args.length < 3)
// instructions();
// This line outputs debug information to stderr. To enable this, simply
// add an extra parameter to the command line
//if (args.length > 3)
// DriverManager.setLogStream(System.err);
// Now run the tests
try {
Dostmt test = new Dostmt(args);
} catch (Exception ex) {
System.err.println("Exception caught.\n" + ex);
ex.printStackTrace();
} }
in.close(); }
logger.config("Inhalt von sql-Datei: \n"+sql);
SxJdbcClient myClient=new SxJdbcClient(logger, dbpropfile,sql);
try
{
SxTransformer myTransformer=null;
myClient.execute();
ResultSet myrs=myClient.getRs();
if(myrs != null)
{
if(outfile.equals(""))
myTransformer = new SxTransformer(logger,System.out);
else
myTransformer = new SxTransformer(logger,new FileWriter(outfile));
myTransformer.setDelim(delim);
myTransformer.setHeader(header);
myTransformer.setOutrs( myrs);
myTransformer.setOutrsmd(myClient.getRsmd());
myTransformer.printResult(outFormat);
}
else
logger.info("Keine Rückgabewerte aus SQL-Script");
myClient.close();
}
catch (SQLException e)
{
logger.severe("Fehler beim sql-Script: "+e.toString());
exceptionHandler.handle(e);
}
logger.info("dosql erfolgreich beendet");
}
/*
* Display some instructions on how to run the example
*/
public static void instructions()
{
System.out.println("\nDieses Javaprogramm führt ein beliebiges sql-Script mit einer oder mehr sql-Anweisungen aus");
System.out.println("Im Classpath muss superx-db.jar sowie der zugehörige jdbc-Treiber sein.");
System.out.println("Befehl:\n java dosql <Dateipfad sql-Script> <delimiter>(optional) <Ausgabe der Feldüberschriften (optional, true oder false).");
System.out.println("Default:\n java dosql <Dateipfad sql-Script> <TAB> true");
System.exit(1);
}
/*
* This little lot starts the test
*/
public static void main(String args[])
{
//System.out.println("PostgreSQL psql example v6.3 rev 1\n");
//if (args.length < 3)
// instructions();
// This line outputs debug information to stderr. To enable this, simply
// add an extra parameter to the command line
//if (args.length > 3)
// DriverManager.setLogStream(System.err);
// Now run the tests
try
{
Dostmt test = new Dostmt(args);
}
catch (Exception ex)
{
System.err.println("Exception caught.\n" + ex);
ex.printStackTrace();
}
}
} }

927
src/de/superx/bin/EtlFuzzer.java

@ -0,0 +1,927 @@
package de.superx.bin;
import static de.superx.servlet.SxSQL_Server.DEFAULT_MANDANTEN_ID;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.sql.DataSource;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.batch.core.ExitStatus;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowCallbackHandler;
import de.superx.rest.EtlJobApi;
import de.superx.rest.model.job.Component;
import de.superx.rest.model.job.JobExecutionStatus;
import de.superx.rest.model.job.StepExecutionStatus;
import de.superx.servlet.SuperXManager;
import de.superx.servlet.SxPools;
import de.superx.spring.batch.His1DataSources;
import de.superx.spring.cli.config.CLIConfig;
import de.superx.spring.config.BatchConfig;
import de.superx.spring.config.DataJdbcConfiguration;
public class EtlFuzzer {
private static String HELP = "Use this tool to check for problems with incongruencies, "
+ "which may occur "
+ "while running etljobs. Note that Tomcat should not be running,"
+ " due to resulting interferences. Additionally, "
+ "the usage of the latest version of the data sample in the source systems is recommended"
+ "WARNING: you can only run either all of the mbs modules at once or on of them, before you"
+ "must reset your mbs database. It will crash otherwise.";
private static Logger log = Logger.getLogger(EtlFuzzer.class.getName());
private static int EXTREME_INT = 2100000000;
private static Random random = new Random();
private static final String COLNAME_NULLABLE = "is_nullable";
private static final String COLNAME_COLUMN = "column_name";
private static final String COLNAME_DATATYPE = "data_type";
private static final String COLNAME_CHAR_MAX = "character_maximum_length";
private static final String COLNAME_PRECISION = "numeric_precision";
private static final String COLNAME_SCALE = "numeric_scale";
private static final String COLNAME_TABLE = "table_name";
private static final String COLNAME_RELNAME = "relname";
private static final String DB_MBS = "mbs";
private static final String DB_H1 = "hisinone";
private static int extreme_int_puffer = 10000;
private static String SQL_GET_ACCESSED_TABLES_H1 = "Select * from pg_stat_all_tables where "
+ "(seq_scan > 0 or seq_tup_read > 0 or idx_scan > 0) and schemaname = 'hisinone'";
private static String SQL_GET_ACCESSED_TABLES_MBS = "Select * from pg_stat_all_tables where "
+ "(seq_scan > 0 or seq_tup_read > 0 or idx_scan > 0) and schemaname = 'mbs'";
private static String SQL_GET_TABLE_METADATA_BASE = "select column_name, data_type,"
+ " is_nullable, numeric_precision, numeric_scale, character_maximum_length from information_schema.columns where table_name =";
private static String SQL_RESET_STATISTICS = "Select pg_stat_reset()";
private static String[] modulesH1 = {"kern", "cob", "prom", "sos", "res", "zul"};
private static String[] modulesMBS = {"fin","ivs","bau"};
private static final int MODULES_KERN_INDEX = 0;
private static final int MODULES_COB_INDEX = 1;
private static final int MODULES_PROM_INDEX = 2;
private static final int MODULES_SOS_INDEX = 3;
private static final int MODULES_RES_INDEX = 4;
private static final int MODULES_ZUL_INDEX = 5;
private static final int MODULES_FIN_INDEX = 0;
private static final int MODULES_IVS_INDEX = 1;
private static final int MODULES_BAU_INDEX = 2;
private static int next_id = 0;
private static int next_join_nr = 0;
private static ArrayList<String> errors = new ArrayList<>();
private static void setNext_join_nr(int next_nr) {
EtlFuzzer.next_join_nr = next_nr;
}
private static void setNext_id(int next_id) {
EtlFuzzer.next_id = next_id;
}
static HashMap<String, String> error_tables_columns = new HashMap<String, String>();
private static ArrayList<String> error_keys = new ArrayList<>();
private static ApplicationContext applicationContext;
private static GenericApplicationContext APPLICATION_CONTEXT = null;
/**
* Generiert einen String, bestehend aus dem Zeichen x, mit einer bestimmten Länge.
* @param length gewollte Stringlänge
*/
private static String StringGenerator(int length) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append("x");
}
return sb.toString();
}
/**
* generiert einen numerischen Wert mit precision Stellen vor dem Komma und scale Nachkommastellen.
* @param precision
* @param scale
* @return
*/
private static String NumGen(int precision, int scale) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < precision; i++) {
sb.append("9");
}
String num = sb.toString();
String firstPart = num.substring(0, precision-scale);
String secondPart = num.substring(precision-scale);
return firstPart + "." + secondPart;
}
/**
* Gibt alle Tabellen aus, auf die durch ein Entladeskript zugegriffen wurde.
* @param stmt Statement
* @param tables ArrayListe, in die die Tabellennamen gespeichert werden sollen.
* @return ArrayList mit den Tabellennamen
* @throws SQLException
*/
private static ArrayList<String> getAccessedTablesH1(JdbcTemplate jt, ArrayList<String> tables) throws SQLException {
ResultSetExtractor<Void> extractor = new ResultSetExtractor<Void>() {
@Override
public Void extractData(ResultSet rs) throws SQLException {
while(rs.next()) {
tables.add(rs.getString(COLNAME_RELNAME));
}
return null;
}
};
jt.query(SQL_GET_ACCESSED_TABLES_H1, extractor);
return tables;
}
/**
* gibt alle durch ETL Laderoutinen zugegriffenen Tabellen für das mbs Vorsystem aus.
* @return
* @throws SQLException
*/
private static ArrayList<String> getAccessedTablesMBS(JdbcTemplate jt, ArrayList<String> tables) throws SQLException {
ResultSetExtractor<Void> extractor = new ResultSetExtractor<Void>() {
@Override
public Void extractData(ResultSet rs) throws SQLException {
while(rs.next()) {
tables.add(rs.getString(COLNAME_RELNAME));
}
return null;
}
};
jt.query(SQL_GET_ACCESSED_TABLES_MBS, extractor);
return tables;
}
/**
* Gibt den SQL Befehl für die Metadaten einer Tabelle aus dem hisinone Vorsystem zurück.
* @param table Tabellenname
* @return SQL Befehl
*/
private static String sqlTableMetaDataH1(String table) {
return SQL_GET_TABLE_METADATA_BASE + "'" + table + "'";
}
/**
* Gibt den SQL Befehl für die Metadaten einer Tabelle aus dem mbs Vorsystem zurück.
* @param table
* @return
*/
private static String sqlTableMetaDataMBS(String table) {
return String.format("%s '%s' and table_schema='mbs'",SQL_GET_TABLE_METADATA_BASE, table);
}
/**
* für HLR.
* @param <T>
* @param beanName
* @param requiredType
* @return
*/
public static <T> T getBean(String beanName, Class<T> requiredType) {
if (applicationContext != null) {
return applicationContext.getBean(beanName, requiredType);
}
return null;
}
/**
* für HLR.
*/
private static void initSxPools() {
try {
List<String> mandantenNamen = new LinkedList<String>();
mandantenNamen.add(DEFAULT_MANDANTEN_ID);
SxPools.closeAll();
SxPools.init(mandantenNamen);
SxPools.get(DEFAULT_MANDANTEN_ID).init();
SxPools.get(DEFAULT_MANDANTEN_ID).initLogging(true, Level.DEBUG);
} catch (Exception e) {
System.out.println("error while initialising the SuperX pools:");
e.printStackTrace();
System.exit(1);
}
}
/**
* für HLR.
* @return
*/
private static GenericApplicationContext createContext() {
/*
* https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/AnnotationConfigApplicationContext.html
* quote:
* "In case of multiple @Configuration classes, @Bean methods defined in later classes will override those defined in earlier classes.
* This can be leveraged to deliberately override certain bean definitions via an extra @Configuration class."
* - so it's alright to override some beans via "CLIConfig"
*/
if (APPLICATION_CONTEXT == null) {
APPLICATION_CONTEXT = new AnnotationConfigApplicationContext(BatchConfig.class, DataJdbcConfiguration.class, CLIConfig.class);
}
return APPLICATION_CONTEXT;
}
/**
* für HLR.
* @param comp
* @param etlJob
* @return
*/
private static boolean isHauptladeroutine(String comp, EtlJobApi etlJob) {
List<Component> installJobs = etlJob.getEtlJobs();
for (Component comp_meta : installJobs) {
if (comp_meta != null && comp_meta.getAbbreviation().equals(comp)) {
return true;
}
}
return false;
}
/**
* Erstellt einen Timestamp, in einem bestimmten Format.
* @param d
* @return
*/
private static String timestampMaker(String d) {
Date date = new Date();
Timestamp ts=new Timestamp(date.getTime());
SimpleDateFormat formatterNow = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat formatterDay = new SimpleDateFormat("yyyy-MM-dd");
String time = "";
switch(d) {
case "day":
time = formatterDay.format(ts);
break;
case "now":
time = formatterNow.format(ts);
break;
}
return time;
}
/**
* für HLR.
* @param job_id
* @param context
*/
private static void etlJob(String job_id, GenericApplicationContext context, String db) {
System.out.println(job_id);
try {
EtlJobApi componentApi = context.getBean(EtlJobApi.class);
String database = db;
Long jobStartStatus;
if (isHauptladeroutine(job_id, componentApi)) {
jobStartStatus = componentApi.complete(job_id);
} else {
jobStartStatus = componentApi.executeJob(database, job_id);
}
handleStartResult(jobStartStatus, componentApi);
} catch (BeansException be) {
handleBeansException(be);
} catch (Exception e) {
handleJobException(e, job_id);
}
}
private static void unload(String job_id, GenericApplicationContext context, String db) {
System.out.println(job_id);
try {
EtlJobApi componentApi = context.getBean(EtlJobApi.class);
String database = db;
Long jobStartStatus;
if (isHauptladeroutine(job_id, componentApi)) {
jobStartStatus = componentApi.unload(job_id);
} else {
jobStartStatus = componentApi.executeJob(database, job_id);
}
handleStartResult(jobStartStatus, componentApi);
} catch (BeansException be) {
handleBeansException(be);
} catch (Exception e) {
handleJobException(e, job_id);
}
}
/**
* Findet in einem String den ersten Integer Wert der innerhalb dieser Zeichen "»«" liegt. Die Zeichen sind relevant für die Fehlermeldung.
* @param input
* @return
*/
public static String findInt(String input) {
Pattern pattern = Pattern.compile("»\\d+«");
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
String match = matcher.group();
return match.substring(1, match.length() - 1);
}
return null;
}
/**
* Gibt die gefundenen fehler aus.
* @param ses
*/
private static void collectErrors(StepExecutionStatus ses) {
for (StepExecutionStatus sec : ses.getChildren()) {
if(sec.getChildren() != null) {
for(StepExecutionStatus sec2 : sec.getChildren()) {
if (sec2.getExitStatus().getExitCode().equals("FAILED")) {
errors.add(sec2.getName());
String etl_error = sec2.getExitStatus().getExitDescription();
errors.add(etl_error);
if(error_tables_columns.containsKey(findInt(etl_error))) {
error_keys.add(findInt(etl_error));
}
}
}
}
}
}
/**
* für HLR.
* @param jobStartStatus
* @param componentApi
*/
private static void handleStartResult(Long jobStartStatus, EtlJobApi componentApi) {
if (jobStartStatus.intValue() == -1) {
System.out.println("Aktion konnte nicht gestartet werden: Es läuft bereits eine Aktion");
System.exit(1);
}
try {
JobExecutionStatus es = componentApi.getStatus(jobStartStatus);
for(StepExecutionStatus ses : es.getStepExecutions()) {
collectErrors(ses);
}
ExitStatus exst = es.exitStatus;
if (exst.equals(ExitStatus.FAILED)) {
System.out.println(("Beim Ausführen der Aktion ist ein Fehler aufgetreten; Bitte prüfen Sie die Logdatei."));
}
} catch (Exception e) {
System.out.println(("Beim Ausführen der Aktion ist ein Fehler aufgetreten:"));
e.printStackTrace();
}
}
/**
* für HRL.
* @param e
* @param jobName
*/
private static void handleJobException(Exception e, String jobName) {
System.out.println("error while executing the job '" + jobName + "'");
e.printStackTrace();
}
/**
* für HLR.
* @param be
*/
private static void handleBeansException(BeansException be) {
System.out.println("configuration error or error with resolving the bean '" + EtlJobApi.class.getCanonicalName() + "'");
be.printStackTrace();
}
/**
* gibt den Inhalt einer ArrayList aus.
* @param list
*/
private static void printList(ArrayList<String> list) {
for(int i = 0; i<list.size();i++) {
String text = list.get(i);
log.info(String.format(" %s", text));
}
}
/**
* gibt die Tabellen- und Spaltennamen von den Fehlern aus, die durch die Ints entstehen.
*/
private static void printIntErrors() {
for(String key : error_keys) {
String intError = String.format("Der Wert: %s wurde initial in die Tabelle.Spalte: %s eingetragen.", key, error_tables_columns.get(key));
log.info(intError);
}
}
/**
* Findet für ein ID Attribut, den nächstgrößeren Wert.
* @param jt
* @param table
* @param column_name
*/
private static void nextID(JdbcTemplate jt, String table, String column_name, String db) {
ResultSetExtractor<Void> extractor = new ResultSetExtractor<Void>() {
@Override
public Void extractData(ResultSet rs) throws SQLException {
while(rs.next()) {
setNext_id(rs.getInt(1)+1);
}
return null;
}
};
if (db.equals(DB_H1)) {
String SQL_highest_id = String.format("Select max(%s) from %s", column_name, table);
jt.query(SQL_highest_id, extractor);
} else {
String SQL_highest_id = String.format("Select max(%s) from mbs.%s", column_name, table);
jt.query(SQL_highest_id, extractor);
}
}
private static void next_nr(JdbcTemplate jt, String table, String column_name) {
ResultSetExtractor<Void> extractor = new ResultSetExtractor<Void>() {
@Override
public Void extractData(ResultSet rs) throws SQLException {
while(rs.next()) {
setNext_join_nr(rs.getInt(1)+1);
}
return null;
}
};
String SQL_highest_nr = String.format("select max(%s) from mbs.%s", column_name, table);
jt.query(SQL_highest_nr, extractor);
}
public static String separateWithComma(ArrayList<String> array) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < array.size(); i++) {
sb.append(array.get(i));
if (i < array.size() - 1) {
sb.append(", ");
}
}
return sb.toString();
}
/**
* Erzeugt ein INSERT SQL Befehl.
* @param traps
* @param id
* @param table
* @return
*/
private static String createTrap(ArrayList<String> traps, String table, String db) {
String trap = "";
ArrayList<String> columns = new ArrayList<>();
ArrayList<String> values = new ArrayList<>();
for (int i = 0;i<traps.size();i++) {
if (i % 2 == 0) {
columns.add(traps.get(i));
} else {
values.add(traps.get(i));
}
}
if (db.equals(DB_H1)) {
trap = String.format("Insert into %s (%s) values (%s)", table, separateWithComma(columns), separateWithComma(values));
} else if (db.equals(DB_MBS)) {
trap = String.format("Insert into mbs.%s (%s) values (%s)", table, separateWithComma(columns), separateWithComma(values));
}
return trap;
}
/**
*
* fügt die Extremwerte in die Datenbank.
* @param jt
* @param table
*/
private static void insertTraps(JdbcTemplate jt, String table, String db) {
ResultSetExtractor<Void> extractor = new ResultSetExtractor<Void>() {
@Override
public Void extractData(ResultSet rs) throws SQLException {
ArrayList<String> traps = new ArrayList<>();
while(rs.next()) {
//firstly, checks if nullable
if(rs.getString(COLNAME_NULLABLE).equals("YES")) {
traps.add(rs.getString(COLNAME_COLUMN));
traps.add("null");
continue;
//else generate extreme values
} else if (rs.getString(COLNAME_NULLABLE).equals("NO")) {
//IDs
if (rs.getString(COLNAME_COLUMN).equals("id") || rs.getString(COLNAME_COLUMN).endsWith("_id") ||
rs.getString(COLNAME_COLUMN).equals("lid") || rs.getString(COLNAME_COLUMN).endsWith("_lid")) {
nextID(jt, table, rs.getString(COLNAME_COLUMN), db);
traps.add(rs.getString(COLNAME_COLUMN));
traps.add(String.valueOf(next_id));
continue;
//Join_Nr
} else if (rs.getString(COLNAME_COLUMN).equals("join_nr")) {
next_nr(jt, table, rs.getString(COLNAME_COLUMN));
traps.add(rs.getString(COLNAME_COLUMN));
traps.add(String.valueOf(next_join_nr));
//Int
} else if (rs.getString(COLNAME_DATATYPE).equals("integer")) {
int randomNumber = EXTREME_INT + random.nextInt(extreme_int_puffer);
//String number = String.format("%d", Integer.valueOf(randomNumber));
String number = Integer.toString(randomNumber);
traps.add(rs.getString(COLNAME_COLUMN));
traps.add(number);
error_tables_columns.put(number, String.format("%s.%s", table, rs.getString(COLNAME_COLUMN)));
continue;
//String
} else if (rs.getString(COLNAME_DATATYPE).equals("character varying")) {
int max_length = rs.getInt(COLNAME_CHAR_MAX);
String col = rs.getString(COLNAME_COLUMN);
if (rs.getObject(COLNAME_CHAR_MAX) != null) {
int length = max_length-table.length()-col.length()-2;
//falls tabelle schon länger als max erlaubt
if (max_length <= table.length()) {
traps.add(rs.getString(COLNAME_COLUMN));
traps.add(String.format("'%s'",StringGenerator(max_length)));
continue;
}
//falls tabelle+spalte länger ist als max erlaubt
if((table.length() + col.length()) >= max_length) {
length = max_length-table.length()-1;
traps.add(rs.getString(COLNAME_COLUMN));
traps.add(String.format("'%s:%s'",table, StringGenerator(length)));
continue;
}
String longString = StringGenerator(length);
traps.add(rs.getString(COLNAME_COLUMN));
traps.add(String.format("'%s.%s%s'",table,col, longString));
continue;
}
int string_length = random.nextInt(501) + 2500;
String longString = StringGenerator(string_length);
traps.add(rs.getString(COLNAME_COLUMN));
traps.add(String.format("'%s.%s:%s'",table,col, longString));
continue;
//Timestamp
} else if (rs.getString(COLNAME_DATATYPE).equals("timestamp without time zone")) {
traps.add(rs.getString(COLNAME_COLUMN));
traps.add("'" + timestampMaker("now") + "'");
continue;
//NUMERIC
} else if (rs.getString(COLNAME_DATATYPE).equals("numeric")) {
int precision = rs.getInt(COLNAME_PRECISION);
int scale = rs.getInt(COLNAME_SCALE);
traps.add(rs.getString(COLNAME_COLUMN));
traps.add(String.format("%s", NumGen(precision, scale)));
continue;
//Timestamp day only
} else if (rs.getString(COLNAME_DATATYPE).equals("date")) {
traps.add(rs.getString(COLNAME_COLUMN));
traps.add("'" + timestampMaker("day") + "'");
continue;
}
}
}
if (db.equals(DB_H1)) {
String trap = createTrap(traps, table, db);
log.info(trap);
String disableTrigger = String.format("alter table %s disable trigger all;", table);
String enableTrigger = String.format("alter table %s enable trigger all;", table);
jt.update(disableTrigger);
jt.update(trap);
jt.update(enableTrigger);
} else if (db.equals(DB_MBS)) {
String trap = createTrap(traps, table, db);
log.info(trap);
String disableTrigger = String.format("alter table mbs.%s disable trigger all;", table);
String enableTrigger = String.format("alter table mbs.%s enable trigger all;", table);
jt.update(disableTrigger);
jt.update(trap);
jt.update(enableTrigger);
}
return null;
}
};
if (db.equals(DB_H1)) {
String query = sqlTableMetaDataH1(table);
try {
jt.query(query, extractor);
} catch(Exception e) {
log.error("Fehler bei Statement (Vorbereitung/Setup):\n" + query + "\n" + e.getMessage());
}
} else if (db.equals(DB_MBS)) {
String query = sqlTableMetaDataMBS(table);
try {
jt.query(query, extractor);
} catch(Exception e) {
log.error("Fehler bei Statement (Vorbereitung/Setup):\n" + query + "\n" + e.getMessage());
}
}
}
/**
* Setzt die Postgres Statistiken zurück.
* @param jt
*/
private static void resetStats(JdbcTemplate jt) {
log.info("Zurücksetzung der Statistiken gestartet...");
RowCallbackHandler handler = new RowCallbackHandler() {
@Override
public void processRow(ResultSet rs) throws SQLException {
//nothing
}
};
jt.query(SQL_RESET_STATISTICS, handler);
log.info("Statistiken erfolgreich zurückgesetzt");
}
/**
* Entfernt die Extremwerte aus der Datenbank.
* @param jt
* @param tables
*/
@SuppressWarnings("unused")
private static void removeTraps(JdbcTemplate jt, ArrayList<String> tables) {
for (int i = 0; i<tables.size();i++){
String table = tables.get(i);
if (!table.startsWith("tmp")) {
String deleteEntry = String.format("ALTER TABLE %s DISABLE TRIGGER ALL; delete from %s where id in (select max(id) from %s); alter table %s enable trigger all;", table,table,table,table);
jt.update(deleteEntry);
}
}
}
/**
* Findet Inkongruenzen zwischen der hisinone und eduetl Datenbank.
*/
public static void checkH1(String[] checked_modules) {
ArrayList<String> tables = new ArrayList<>();
JdbcTemplate jt = new JdbcTemplate();
try (GenericApplicationContext context = createContext()){
initSxPools();
//Datenbankzugriff erstellen
His1DataSources hds = context.getBean(His1DataSources.class);
DataSource ds = hds.get(DB_H1);
jt.setDataSource(ds);
//Statistiken zurücksetzen
resetStats(jt);
//Hauptladeroutine durchführen
log.info("Unloadscript (Analysedurchlauf) gestartet...");
for(String m : checked_modules) {
unload(m,context, DB_H1);
}
log.info("Unloadscript (Analysedurchlauf) erfolgreich abgeschlossen.");
//Zugegriffene Tabellen abfangen
tables = getAccessedTablesH1(jt, tables);
printList(tables);
log.info("zugegriffene Tabellen erfolgreich abgefangen");
//Extremwerte einfügen
log.info("Einfügen von Extremwerten gestartet...");
for(int i = 0; i<tables.size();i++) {
insertTraps(jt, tables.get(i), DB_H1);
}
log.info("Extremwerte erfolgreich eingefügt");
//nochmal Hauptladeroutine durchführen
log.info("Hauptladeroutine (Fuzzingtestdurchlauf) gestartet...");
for(String m : checked_modules) {
etlJob(m,context, DB_H1);
}
log.info("Hauptladeroutine (Fuzzingtestdurchlauf) erfolgreich.");
printList(errors);
printIntErrors();
} catch (SQLException e) {
e.printStackTrace();
} catch (DataIntegrityViolationException e) {
e.printStackTrace();
} catch (BadSqlGrammarException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
} finally {
errors.clear();
error_keys.clear();
//removeTraps(jt,tables);
//log.info("Einträge erfolgreich entfernt.");
}
}
public static void checkMBS(String[] checked_modules) {
ArrayList<String> tables = new ArrayList<>();
JdbcTemplate jt = new JdbcTemplate();
try (GenericApplicationContext context = createContext()){
initSxPools();
//Datenbankzugriff erstellen
His1DataSources hds = context.getBean(His1DataSources.class);
DataSource ds = hds.get(DB_MBS);
jt.setDataSource(ds);
//Statistiken zurücksetzen
resetStats(jt);
//Hauptladeroutine durchführen
log.info("Unloadscript (Analysedurchlauf) gestartet...");
for(String m : checked_modules) {
unload(m, context, DB_MBS);
}
log.info("Unloadscript (Analysedurchlauf) erfolgreich abgeschlossen.");
//Zugegriffene Tabellen abfangen
tables = getAccessedTablesMBS(jt, tables);
printList(tables);
log.info("zugegriffene Tabellen erfolgreich abgefangen");
//Extremwerte einfügen
log.info("Einfügen von Extremwerten gestartet...");
for(int i = 0; i<tables.size();i++) {
insertTraps(jt, tables.get(i), DB_MBS);
}
log.info("Extremwerte erfolgreich eingefügt");
//nochmal Hauptladeroutine durchführen
log.info("Hauptladeroutine (Fuzzingtestdurchlauf) gestartet...");
for(String m : checked_modules) {
etlJob(m,context, DB_MBS);
}
log.info("Hauptladeroutine (Fuzzingtestdurchlauf) erfolgreich.");
printList(errors);
printIntErrors();
} catch (SQLException e) {
e.printStackTrace();
} catch (DataIntegrityViolationException e) {
e.printStackTrace();
} catch (BadSqlGrammarException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
} finally {
errors.clear();
error_keys.clear();
//removeTraps(jt,tables);
//log.info("Einträge erfolgreich entfernt.");
}
}
/**
* Für CommandLine Skript.
* @param args
* @param options
* @return
*/
private static CommandLine parseArgs(String[] args, Options options) {
CommandLineParser parser = new GnuParser();
try {
return parser.parse(options, args, false);
} catch (ParseException e) {
System.out.println("error while reading the command line parameters:");
e.printStackTrace();
System.exit(1);
}
return null;
}
/**
* Für CommandLine Skript.
* @return
*/
private static Options createOptions() {
Options options = new Options();
Option opt;
opt = new Option("h", "help", false, "get help");
options.addOption(opt);
opt = new Option("rh1", "run-h1", false, "runs the script for all h1 modules");
options.addOption(opt);
opt = new Option("rmbs", "run-mbs", false, "runs the script for all mbs modules");
options.addOption(opt);
opt = new Option("rk", "run-kern", false, "runs the script for kern module");
options.addOption(opt);
opt = new Option("rc", "run-cob", false, "runs the script for cob module");
options.addOption(opt);
opt = new Option("rf", "run-fin", false, "runs the script for fin module");
options.addOption(opt);
opt = new Option("ri", "run-ivs", false, "runs the script for ivs module");
options.addOption(opt);
opt = new Option("rb", "run-bau", false, "runs the script for bau module");
options.addOption(opt);
opt = new Option("rs", "run-sos", false, "runs the script for sos module");
options.addOption(opt);
opt = new Option("rp", "run-prom", false, "runs the script for prom module");
options.addOption(opt);
opt = new Option("rz", "run-zul", false, "runs the script for zul module");
options.addOption(opt);
opt = new Option("rr", "run-res", false, "runs the script for res module");
options.addOption(opt);
return options;
}
/**
* Für CommandLine Skript.
* @param options
*/
private static void printHelp(Options options) {
HelpFormatter help = new HelpFormatter();
help.printHelp(HELP, options);
}
public static void main(String[] args) {
System.setProperty(SuperXManager.SUPER_X_HISINONE_VERSION, "non-empty-value");
Options options = createOptions();
CommandLine parsedArgs = parseArgs(args, options);
if (parsedArgs.hasOption("h")) {
printHelp(options);
} else if (parsedArgs.hasOption("rh1")) {
checkH1(modulesH1);
} else if (parsedArgs.hasOption("rmbs")) {
checkMBS(modulesMBS);
} else if (parsedArgs.hasOption("rk")) {
String[] module = new String[1];
module[0] = modulesH1[MODULES_KERN_INDEX];
checkH1(module);
} else if (parsedArgs.hasOption("rc")) {
String[] module = new String[1];
module[0] = modulesH1[MODULES_COB_INDEX];
checkH1(module);
} else if (parsedArgs.hasOption("rf")) {
String[] module = new String[1];
module[0] = modulesMBS[MODULES_FIN_INDEX];
checkMBS(module);
} else if (parsedArgs.hasOption("ri")) {
String[] module = new String[1];
module[0] = modulesMBS[MODULES_IVS_INDEX];
checkMBS(module);
} else if (parsedArgs.hasOption("rb")) {
String[] module = new String[1];
module[0] = modulesMBS[MODULES_BAU_INDEX];
checkMBS(module);
} else if (parsedArgs.hasOption("rs")) {
String[] module = new String[1];
module[0] = modulesH1[MODULES_SOS_INDEX];
checkH1(module);
} else if (parsedArgs.hasOption("rp")) {
String[] module = new String[1];
module[0] = modulesH1[MODULES_PROM_INDEX];
checkH1(module);
} else if (parsedArgs.hasOption("rz")) {
String[] module = new String[1];
module[0] = modulesH1[MODULES_ZUL_INDEX];
checkH1(module);
} else if (parsedArgs.hasOption("rr")) {
String[] module = new String[1];
module[0] = modulesH1[MODULES_RES_INDEX];
checkH1(module);
} else {
printHelp(options);
}
}
}

11
src/de/superx/bin/ExcelPdfCreator.java

@ -3,6 +3,7 @@ package de.superx.bin;
import java.io.File; import java.io.File;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
import de.memtext.util.StringUtils; import de.memtext.util.StringUtils;
import de.memtext.util.TransletUtils; import de.memtext.util.TransletUtils;
import de.superx.servlet.XmlTransformer; import de.superx.servlet.XmlTransformer;
@ -17,7 +18,7 @@ public class ExcelPdfCreator {
System.out.println("Wenn Grafiken in PDF eingebunden werden sollen, muss in <xsl:template name=\"kopf_zeile\"> (tabelle_fo_pdf_kopffusszeile.xsl)\n"+ System.out.println("Wenn Grafiken in PDF eingebunden werden sollen, muss in <xsl:template name=\"kopf_zeile\"> (tabelle_fo_pdf_kopffusszeile.xsl)\n"+
"Richtige Pfade für Standalonebetrieb eingestellt werden, beispielweise in eigener pageComponents_html_final.xsl"); "Richtige Pfade für Standalonebetrieb eingestellt werden, beispielweise in eigener pageComponents_html_final.xsl");
GetOpts.setOpts(args); GetOpts.setOpts(args);
String isdrin = GetOpts.isAllRequiredOptionsPresent("-in,-xsl,-out"); String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[]{Options.opt_in, Options.opt_xsl, Options.opt_out});
if (isdrin != null) { if (isdrin != null) {
System.err.println("-fopxconf (Pfad dazu - optional) -in -xsl -out Endung auf .xsl=Excel .pdf=PDF"); System.err.println("-fopxconf (Pfad dazu - optional) -in -xsl -out Endung auf .xsl=Excel .pdf=PDF");
@ -25,9 +26,9 @@ System.out.println("Wenn Grafiken in PDF eingebunden werden sollen, muss in <xsl
} }
System.out.println("Lokalisierung per sx_captions derzeit nicht unterstuetzt!"); System.out.println("Lokalisierung per sx_captions derzeit nicht unterstuetzt!");
String in = GetOpts.getValue("-in"); String in = GetOpts.getValue(Options.opt_in);
String xsl = GetOpts.getValue("-xsl"); String xsl = GetOpts.getValue(Options.opt_xsl);
String out = GetOpts.getValue("-out"); String out = GetOpts.getValue(Options.opt_out);
TransletUtils.initFactory("net.sf.saxon.TransformerFactoryImpl", "org.apache.xalan.xsltc.trax.TransformerFactoryImpl"); TransletUtils.initFactory("net.sf.saxon.TransformerFactoryImpl", "org.apache.xalan.xsltc.trax.TransformerFactoryImpl");
@ -41,7 +42,7 @@ System.out.println("Wenn Grafiken in PDF eingebunden werden sollen, muss in <xsl
} }
if (out.endsWith(".pdf")) { if (out.endsWith(".pdf")) {
File conf=null; File conf=null;
if (GetOpts.isPresent("-fopxconf")) conf=new File(GetOpts.getOpt("-fopxconf").replaceAll("-fopxconf:", "")); if (GetOpts.isPresent(Options.opt_fopxconf)) conf=new File(GetOpts.getOpt(Options.opt_fopxconf).replaceAll("-fopxconf:", ""));
xt.createPdfStandalone(conf,StringUtils.readFile(new File(in)), xsl, out); xt.createPdfStandalone(conf,StringUtils.readFile(new File(in)), xsl, out);
System.out.println("Datei erzeugt"); System.out.println("Datei erzeugt");
} }

203
src/de/superx/bin/ExecuteMask.java

@ -1,5 +1,8 @@
package de.superx.bin; package de.superx.bin;
import static de.superx.servlet.ServletBasics.getParamChecked;
import static de.superx.servlet.SxSQL_Server.DEFAULT_MANDANTEN_ID;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -10,39 +13,52 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.sql.Connection;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.logging.ConsoleHandler; import java.util.logging.ConsoleHandler;
import java.util.logging.LogManager; import java.util.logging.LogManager;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletConfig; import org.springframework.mock.web.MockServletConfig;
import de.memtext.baseobjects.coll.NamedIdObjectList; import de.memtext.baseobjects.coll.NamedIdObjectList;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
import de.memtext.util.ServletHelper; import de.memtext.util.ServletHelper;
import de.memtext.util.StringUtils; import de.memtext.util.StringUtils;
import de.memtext.util.TimeUtils; import de.memtext.util.TimeUtils;
import de.memtext.util.TransletUtils; import de.memtext.util.TransletUtils;
import de.superx.common.FieldContainer;
import de.superx.common.Maske; import de.superx.common.Maske;
import de.superx.common.SxResultRow; import de.superx.common.SxResultRow;
import de.superx.common.SxResultSet; import de.superx.common.SxResultSet;
import de.superx.common.SxUser; import de.superx.common.SxUser;
import de.superx.sec.InputCheckRegistry; import de.superx.sec.InputCheckRegistry;
import de.superx.servlet.RequestParameter;
import de.superx.servlet.ServletUtils; import de.superx.servlet.ServletUtils;
import de.superx.servlet.StatisticExporter;
import de.superx.servlet.SuperXManager; import de.superx.servlet.SuperXManager;
import de.superx.servlet.SxPools; import de.superx.servlet.SxPools;
import de.superx.servlet.UserInitializer; import de.superx.servlet.UserInitializer;
import de.superx.servlet.XmlTransformer; import de.superx.servlet.XmlTransformer;
import de.superx.spring.cli.config.CLIConfig;
import de.superx.spring.config.BatchConfig;
import de.superx.spring.config.DataJdbcConfiguration;
import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRException;
public class ExecuteMask { public class ExecuteMask {
//Ausgabe als PDF nicht möglich? -> Korrupte Datei 30/10/2020 Jan Malte Hientzsch
/** /**
* Kommandozeilen-Interface für Ausführung von Masken und Export des Ergebnis * Kommandozeilen-Interface für Ausführung von Masken und Export des Ergebnis
@ -58,7 +74,6 @@ public class ExecuteMask {
* @param -params:Parameter für die Maske, jeweils mit "&" getrennt in * @param -params:Parameter für die Maske, jeweils mit "&" getrennt in
* einem String * einem String
* *
* Sollte im Arbeitsverzeichnis webapps/superx/WEB-INF laufen
* *
* Beispiele: HTML Druckversion (Default): java * Beispiele: HTML Druckversion (Default): java
* de.superx.bin.ExecuteMask -tid:16000 -out:test.htm -user:admin * de.superx.bin.ExecuteMask -tid:16000 -out:test.htm -user:admin
@ -73,6 +88,9 @@ public class ExecuteMask {
* ?=1=1&Stichtag=1&stylesheet=tabelle_xls.xsl&contenttype=application/vnd.ms-excel" * ?=1=1&Stichtag=1&stylesheet=tabelle_xls.xsl&contenttype=application/vnd.ms-excel"
* -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties * -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties
*/ */
private static GenericApplicationContext APPLICATION_CONTEXT = null;
private static String mandantenID = "default"; private static String mandantenID = "default";
private static TimeUtils tutil = new TimeUtils(); private static TimeUtils tutil = new TimeUtils();
@ -85,8 +103,6 @@ public class ExecuteMask {
private static Integer userid; private static Integer userid;
private static FieldContainer myFieldContainer;
private static String myWEBINFFilePath = System.getProperty("user.dir"); private static String myWEBINFFilePath = System.getProperty("user.dir");
private static Logger log; private static Logger log;
@ -103,9 +119,8 @@ public class ExecuteMask {
+ " java de.superx.bin.ExecuteMask -tid:16000 -out:test.pdf -user:admin \"-params:Köpfe oder Fälle ?=1=1&Stichtag=1&stylesheet=tabelle_fo_pdf.xsl&contenttype=application/pdf\" -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties\n" + " java de.superx.bin.ExecuteMask -tid:16000 -out:test.pdf -user:admin \"-params:Köpfe oder Fälle ?=1=1&Stichtag=1&stylesheet=tabelle_fo_pdf.xsl&contenttype=application/pdf\" -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties\n"
+ " Excel-Datei\n" + " Excel-Datei\n"
+ " java de.superx.bin.ExecuteMask -tid:16000 -out:test.xls -user:admin \"-params:Köpfe oder Fälle ?=1=1&Stichtag=1&stylesheet=tabelle_xls.xsl&contenttype=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\" -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties\n" + " java de.superx.bin.ExecuteMask -tid:16000 -out:test.xls -user:admin \"-params:Köpfe oder Fälle ?=1=1&Stichtag=1&stylesheet=tabelle_xls.xsl&contenttype=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\" -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties\n"
+ " java de.superx.bin.ExecuteMask -tid:16000 -out:test.xls -user:admin \"-params:Köpfe oder Fälle ?=1=1&Stichtag=1&stylesheet=tabelle_xls.xsl&contenttype=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\" -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties\n"
+ " CSV-Datei\n" + " CSV-Datei\n"
+ " java de.superx.bin.ExecuteMask -tid:16000 -out:test.csv -user:admin \"-params:Köpfe oder Fälle ?=1=1&Stichtag=1&contenttype=test/csv\" -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties\n" + " java de.superx.bin.ExecuteMask -tid:16000 -out:test.csv -user:admin \"-params:Köpfe oder Fälle ?=1=1&Stichtag=1&contenttype=text/csv\" -logger:/home/superx/git/superx/superx/WEB-INF/conf/edustore/db/conf/logging.properties\n"
+ " -fopxconf (Pfad dazu - optional)"; + " -fopxconf (Pfad dazu - optional)";
static MockHttpServletRequest mock ; static MockHttpServletRequest mock ;
@ -116,32 +131,64 @@ public class ExecuteMask {
static SxUser user; static SxUser user;
private static File fopxconfFile = null; private static File fopxconfFile = null;
public static void main(String[] args) {
try {
GenericApplicationContext context = createContext();
SxPools.closeAll();
SxPools.init();
SxPools.get(mandantenID).init();
SxPools.get(mandantenID).initLogging(true, org.apache.log4j.Level.DEBUG);
execute(args);
} catch (Exception e) {
System.err.println("Could not init SxPools!");
e.printStackTrace(System.err);
System.exit(1);
}
System.exit(0);
}
public static void main(String[] args) throws IllegalArgumentException, SecurityException { public static void execute(String[] args) throws Exception {
//SuperXManager.initKettleEnv();
// mock muss neu intialisiert werden, sonst Fehlschläge bei mehreren Aufrufen // mock muss neu intialisiert werden, sonst Fehlschläge bei mehreren Aufrufen
// von ExecuteMaske in JUnitTest Batterie mittels ant // von ExecuteMaske in JUnitTest Batterie mittels ant
mock = new MockHttpServletRequest(); mock = new MockHttpServletRequest();
GetOpts.setOpts(args); GetOpts.setOpts(args);
String isdrin = GetOpts.isAllRequiredOptionsPresent("-logger,-tid,-out,-user"); String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[]{Options.opt_logger,
Options.opt_tid,
Options.opt_out,
Options.opt_user});
if (isdrin != null) { if (isdrin != null) {
System.err.println(usage); System.err.println(usage);
System.exit(1); return;
} }
String userName = GetOpts.getValue("-user"); String userName = GetOpts.getValue(Options.opt_user);
String loggingProperties = GetOpts.getValue("-logger"); String loggingProperties = GetOpts.getValue(Options.opt_logger);
myWEBINFFilePath= de.superx.util.PathAndFileUtils.getWebinfDirectory();
if (GetOpts.isPresent("-fopxconf")) { try {
fopxconfFile = new File(GetOpts.getOpt("-fopxconf").replaceAll("-fopxconf:", "")); myWEBINFFilePath= de.superx.util.PathAndFileUtils.getWebinfDirectory();
} catch (URISyntaxException e1) {
// Default ist user.dir:
myWEBINFFilePath=getMyWEBINFFilePath();
} //
if (GetOpts.isPresent(Options.opt_fopxconf)) {
fopxconfFile = new File(GetOpts.getOpt(Options.opt_fopxconf).replaceAll(Options.opt_fopxconf.stringValue()+":", ""));
} else { } else {
fopxconfFile = new File(myWEBINFFilePath+ File.separator + "conf"+ File.separator +"fop.xconf"); fopxconfFile = new File(myWEBINFFilePath+ File.separator + "conf"+ File.separator +"fop.xconf");
} }
try { List<String> mandantenNamen = new LinkedList<String>();
FileInputStream ins; if (GetOpts.isPresent(Options.opt_mandID)) {
ins = new FileInputStream(loggingProperties); String mid = GetOpts.getValue(Options.opt_mandID);
System.out.println("Opt -mandantenID present: " + mid);
mandantenID = mid;
} else if (mandantenID == null){
System.out.println("No opt -mandantenID present. Set to " + DEFAULT_MANDANTEN_ID);
mandantenID = DEFAULT_MANDANTEN_ID;
} else {
System.out.println("No opt -mandantenID present. mandantenID was already set to " + mandantenID);
}
mandantenNamen.add(mandantenID);
try ( FileInputStream ins = new FileInputStream(loggingProperties) ) {
LogManager MyLogManager = java.util.logging.LogManager.getLogManager(); LogManager MyLogManager = java.util.logging.LogManager.getLogManager();
MyLogManager.readConfiguration(ins); MyLogManager.readConfiguration(ins);
log = Logger.getLogger(ExecuteMask.class.getName()); log = Logger.getLogger(ExecuteMask.class.getName());
@ -149,42 +196,48 @@ public class ExecuteMask {
System.out.println("Using Loggging-Level " + log.getLevel()); System.out.println("Using Loggging-Level " + log.getLevel());
} catch (FileNotFoundException e2) { } catch (FileNotFoundException e2) {
System.err.println("Datei " + loggingProperties + " nicht gefunden:" + e2.toString()); System.err.println("Datei " + loggingProperties + " nicht gefunden:" + e2.toString());
System.exit(1); return;
} catch (IOException e) { } catch (IOException e) {
System.err.println("Datei " + loggingProperties + " kann nicht gelesen werden:" + e.toString()); System.err.println("Datei " + loggingProperties + " kann nicht gelesen werden:" + e.toString());
System.exit(1); return;
} }
tutil.start(); tutil.start();
try { try {
SuperXManager.initKettleEnv(); // SxPools.closeAll();
SxPools.init(); // SxPools.init(mandantenNamen);
SxPools.get(mandantenID).init(); // SxPools.get(mandantenID).init();
SxPools.get(mandantenID).initLogging(true); // SxPools.get(mandantenID).initLogging(true);
SxPools.resetAllPools(); SuperXManager.initKettleEnv(APPLICATION_CONTEXT);
userid = getUserID(userName, mandantenID); userid = getUserID(userName, mandantenID);
adminUser = getUserAdmin(userName, mandantenID); adminUser = getUserAdmin(userName, mandantenID);
user = UserInitializer.initUser(mandantenID, userName, userid, adminUser); UserInitializer ui=new UserInitializer(mandantenID, userName, userid, adminUser);
Connection con=SxPools.get(mandantenID).getConnection();
ui.initUser(con,null);
user=ui.getUser();
user.setMandantenID(mandantenID);
con.close();
} catch (Exception e) { } catch (Exception e) {
log.severe("Fehler beim Aufbau der Connection: " + e.toString()); log.severe("Fehler beim Aufbau der Connection: " + e.toString());
System.exit(1); e.printStackTrace();
return;
} }
String tidString = GetOpts.getValue("-tid"); String tidString = GetOpts.getValue(Options.opt_tid);
String outfile = GetOpts.getValue("-out"); String outfile = GetOpts.getValue(Options.opt_out);
if (GetOpts.isPresent("-locale")) if (GetOpts.isPresent(Options.opt_locale))
myLocale = GetOpts.getValue("-locale"); myLocale = GetOpts.getValue(Options.opt_locale);
else else
myLocale = de.superx.util.SqlStringUtils.getEncoding(); myLocale = de.superx.util.SqlStringUtils.getEncoding();
if (GetOpts.isPresent("-params")) // TODO Do we really want to leave static field myParams
myParams = GetOpts.getValue("-params"); // undefined if opt_params is not set?!
if (GetOpts.isPresent(Options.opt_params))
myParams = GetOpts.getValue(Options.opt_params);
Locale desiredLocale = new Locale(myLocale); Locale desiredLocale = new Locale(myLocale);
SuperXManager.maxRows = 1000000; SuperXManager.maxRows = 1000000;
Maske maske = null; Maske maske = null;
InputCheckRegistry.registerDefaultChecks(); InputCheckRegistry.registerDefaultChecks();
try { try {
maske = new Maske(mandantenID, user, new Integer(tidString), desiredLocale); maske = new Maske(mandantenID, user, Integer.valueOf(tidString), desiredLocale);
/*NamedIdObjectList fields = maske.readFelderFromDb(user); NamedIdObjectList fields = maske.readFelderFromDb(user);
myFieldContainer = maske.getIndividualFields();
myFieldContainer.addAll(fields);*/
setParams(mock, myParams); setParams(mock, myParams);
maske.setFieldDefaults(user, mock, true); maske.setFieldDefaults(user, mock, true);
exportTable(mock, mockResponse, maske, user, outfile, desiredLocale); exportTable(mock, mockResponse, maske, user, outfile, desiredLocale);
@ -193,9 +246,8 @@ public class ExecuteMask {
e.printStackTrace(); e.printStackTrace();
log.severe("Fehler beim Ausführen der Maske " + tidString + ": " + e.toString()); log.severe("Fehler beim Ausführen der Maske " + tidString + ": " + e.toString());
System.exit(1); throw e;
} }
System.exit(0);
} }
public static HttpServletResponse getHttpResponse() { public static HttpServletResponse getHttpResponse() {
@ -226,7 +278,7 @@ public class ExecuteMask {
} }
if (userID == null) { if (userID == null) {
System.err.println("User " + userName + "unbekannt"); System.err.println("User " + userName + "unbekannt");
System.exit(1); return Integer.valueOf(-1);
} }
return userID; return userID;
} }
@ -276,7 +328,6 @@ public class ExecuteMask {
String paramName = paramString.substring(0, paramString.indexOf("=")); String paramName = paramString.substring(0, paramString.indexOf("="));
String paramVal = paramString.substring(paramString.indexOf("=") + 1); String paramVal = paramString.substring(paramString.indexOf("=") + 1);
mock.addParameter(paramName, paramVal); mock.addParameter(paramName, paramVal);
//System.out.println(paramName+"-"+paramVal);
} }
} }
@ -291,29 +342,29 @@ public class ExecuteMask {
* @param desiredLocale Locale für Ausgabedatei * @param desiredLocale Locale für Ausgabedatei
* *
*/ */
private static void exportTable(MockHttpServletRequest mock_par, MockHttpServletResponse mockResponse_par, private static void exportTable(HttpServletRequest mock_par, HttpServletResponse mockResponse_par,
Maske maske, SxUser user_par, String outfile, Locale desiredLocale) { Maske maske, SxUser user_par, String outfile, Locale desiredLocale) {
String currentXml_local = null; String currentXml_local = null;
String method = "html"; String method = "html";
String stylesheet = ServletHelper.getParameter(mock_par, "stylesheet"); String stylesheet = ServletHelper.getParameter(mock_par, RequestParameter.stylesheet);
// Default ist html Druckversion: // Default ist html Druckversion:
if (stylesheet == null || stylesheet.equals("")) if (stylesheet == null || stylesheet.equals(""))
stylesheet = "tabelle_html_p.xsl"; stylesheet = "tabelle_html_p.xsl";
log.info("Stylesheet " + stylesheet + " wird genutzt"); log.info("Stylesheet " + stylesheet + " wird genutzt");
String contenttype = ServletHelper.getParameter(mock_par, "contenttype"); String contenttype = ServletHelper.getParameter(mock_par, RequestParameter.contenttype);
// Default ist html: // Default ist html:
if (contenttype == null || contenttype.equals("")) if (contenttype == null || contenttype.equals("")) {
contenttype = "text/html"; contenttype = "text/html";
if (contenttype.indexOf("pdf") > -1) }
if (contenttype.indexOf("pdf") > -1) {
method = "pdf"; method = "pdf";
if (contenttype.indexOf("xml") > -1) }
if (contenttype.indexOf("xml") > -1) {
method = "xml"; method = "xml";
if (contenttype.indexOf("spreadsheetml") > -1) }
if (contenttype.indexOf("spreadsheetml") > -1) {
method = "xls"; method = "xls";
// if }
// (contenttype.indexOf("vnd.openxmlformats-officedocument.spreadsheetml.sheet")
// > -1) method = "xlsx";
log.info("Contenttype " + contenttype + " wird erzeugt"); log.info("Contenttype " + contenttype + " wird erzeugt");
maske.setMaxOffset(10000000); maske.setMaxOffset(10000000);
maske.setReuseResult(false); maske.setReuseResult(false);
@ -322,18 +373,31 @@ public class ExecuteMask {
maske.setDesiredContenttype(contenttype); maske.setDesiredContenttype(contenttype);
log.info("Start Maskengenerierung"); log.info("Start Maskengenerierung");
try { try {
String statistikExport = getParamChecked(mock_par, maske, RequestParameter.Statistikexport.toString());
if (!statistikExport.isEmpty()) {
String ausgabeFormat = ServletHelper.getParameter(mock_par, RequestParameter.Exportformat);
if (ausgabeFormat == null) {
ausgabeFormat = "text/html";
}
log.info("Amtliche Statistik. Ausgabeformat = " + ausgabeFormat);
StatisticExporter statisticExporter = new StatisticExporter(mock_par, mockResponse_par, maske);
if (statisticExporter.xmlStatisticExport(ausgabeFormat)) {
return;
}
}
currentXml_local = maske.runQuery(user_par, mock_par, null).toString(); currentXml_local = maske.runQuery(user_par, mock_par, null).toString();
System.out.println("Ausgabe Maskenprotokoll\n" + SuperXManager.activityLog.toString()); System.out.println("Ausgabe Maskenprotokoll\n" + SuperXManager.activityLog.toString());
log.info("Maskenergebnis wird lokalisiert"); log.info("Maskenergebnis wird lokalisiert");
currentXml_local = SxPools.get(mandantenID).localize(currentXml_local, desiredLocale); currentXml_local = SxPools.get(mandantenID).localize(currentXml_local, desiredLocale);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
log.severe("Fehler beim Erstellen des XML für Maske " + e.toString()); log.severe("Fehler beim Erstellen des XML für Maske " + e.toString());
} }
String ausgabedatei = ""; String ausgabedatei = "";
if (stylesheet.equals("tabelle_xml.xsl")) if (stylesheet.equals("tabelle_xml.xsl")) {
ausgabedatei = writeTextFile(currentXml_local, outfile); ausgabedatei = writeTextFile(currentXml_local, outfile);
}
else if (contenttype.equals("text/csv")) else if (contenttype.equals("text/csv"))
try { try {
ausgabedatei = writeTextFile(maske.getCSV(mandantenID).toString(), outfile); ausgabedatei = writeTextFile(maske.getCSV(mandantenID).toString(), outfile);
@ -342,7 +406,7 @@ public class ExecuteMask {
e.printStackTrace(); e.printStackTrace();
} }
else { else {
ausgabedatei = writeTextFile(currentXml_local, null); ausgabedatei = writeTextFile(currentXml_local, outfile + ".xml");
if (stylesheet.endsWith(".jrxml")) if (stylesheet.endsWith(".jrxml"))
exportJR(mock_par, mockResponse_par, maske, user_par, outfile, stylesheet, contenttype, mandantenID, exportJR(mock_par, mockResponse_par, maske, user_par, outfile, stylesheet, contenttype, mandantenID,
myWEBINFFilePath + "/reports/", currentXml_local); myWEBINFFilePath + "/reports/", currentXml_local);
@ -354,7 +418,7 @@ public class ExecuteMask {
} }
private static void exportJR(MockHttpServletRequest mock_par, MockHttpServletResponse mockResponse_par, Maske maske, private static void exportJR(HttpServletRequest mock_par, HttpServletResponse mockResponse_par, Maske maske,
SxUser user_par, String outfile, String stylesheet, String contentType, String mandantenID_par, SxUser user_par, String outfile, String stylesheet, String contentType, String mandantenID_par,
String reports_dir, String currentXml_par) { String reports_dir, String currentXml_par) {
@ -393,7 +457,7 @@ public class ExecuteMask {
try { try {
File temp = File.createTempFile("tabelle", ".xml"); File temp = File.createTempFile("tabelle", ".xml");
FileWriter f1 = new FileWriter(temp); FileWriter f1 = new FileWriter(temp);
f1.write(content); f1.write(content == null ? "" : content);
f1.flush(); f1.flush();
f1.close(); f1.close();
targetfilename = temp.getAbsolutePath(); targetfilename = temp.getAbsolutePath();
@ -401,7 +465,7 @@ public class ExecuteMask {
if (filename != null) { if (filename != null) {
Path destPath = Paths.get(filename); Path destPath = Paths.get(filename);
Path resultPath = Files.move(tmpPath, destPath, StandardCopyOption.REPLACE_EXISTING); Path resultPath = Files.move(tmpPath, destPath, StandardCopyOption.REPLACE_EXISTING);
targetfilename = resultPath.toString(); // dest.getAbsolutePath(); targetfilename = resultPath.toString();
} }
} catch (IOException e) { } catch (IOException e) {
log.severe("Fehler beim Erstellen der Datei " + filename + " " + e.toString()); log.severe("Fehler beim Erstellen der Datei " + filename + " " + e.toString());
@ -422,10 +486,10 @@ public class ExecuteMask {
* *
*/ */
private static void transformFile(Maske maske, String xmlfile, String stylesheet, String contenttype, private static void transformFile(Maske maske, String xmlfile, String stylesheet, String contenttype,
String filename, MockHttpServletResponse mockResponse_par, String method) { String filename, HttpServletResponse mockResponse_par, String method) {
TransletUtils.initFactory("net.sf.saxon.TransformerFactoryImpl", null); TransletUtils.initFactory("net.sf.saxon.TransformerFactoryImpl", null);
String stylesheetPath = myWEBINFFilePath + File.separator + ".." + File.separator + "xml" + File.separator String stylesheetPath = myWEBINFFilePath + File.separator + ".." + File.separator + "xml" + File.separator
+ stylesheet; + stylesheet;
if (method.equals("xls")) { if (method.equals("xls")) {
try { try {
XmlTransformer xt = new XmlTransformer(mockServletConfig, mock, mockResponse_par, null, null); XmlTransformer xt = new XmlTransformer(mockServletConfig, mock, mockResponse_par, null, null);
@ -451,6 +515,7 @@ public class ExecuteMask {
myTransformer.quellstring = xmlfile; myTransformer.quellstring = xmlfile;
myTransformer.stylesheet = stylesheetPath; myTransformer.stylesheet = stylesheetPath;
myTransformer.outfile = filename; myTransformer.outfile = filename;
myTransformer.mandantenID=mandantenID;
if (fopxconfFile != null) if (fopxconfFile != null)
myTransformer.setFopxconfFile(fopxconfFile); myTransformer.setFopxconfFile(fopxconfFile);
myTransformer.transformFile(method); myTransformer.transformFile(method);
@ -476,5 +541,19 @@ public class ExecuteMask {
public static void setMandantenID(String mandantenID) { public static void setMandantenID(String mandantenID) {
ExecuteMask.mandantenID = mandantenID; ExecuteMask.mandantenID = mandantenID;
} }
public static GenericApplicationContext createContext() {
/*
* https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/AnnotationConfigApplicationContext.html
* quote:
* "In case of multiple @Configuration classes, @Bean methods defined in later classes will override those defined in earlier classes.
* This can be leveraged to deliberately override certain bean definitions via an extra @Configuration class."
* - so it's alright to override some beans via "CLIConfig"
*/
if (APPLICATION_CONTEXT == null) {
APPLICATION_CONTEXT = new AnnotationConfigApplicationContext(BatchConfig.class, DataJdbcConfiguration.class, CLIConfig.class);
}
return APPLICATION_CONTEXT;
}
} }

476
src/de/superx/bin/FMParser.java

@ -1,253 +1,223 @@
package de.superx.bin; package de.superx.bin;
import static de.superx.servlet.SxSQL_Server.DEFAULT_MANDANTEN_ID;
import java.io.File; import static de.superx.servlet.SxSQL_Server.DEFAULT_MANDANTEN_ID;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.File;
import java.sql.Connection; import java.io.FileNotFoundException;
import java.sql.ResultSet; import java.io.IOException;
import java.sql.SQLException; import java.sql.Connection;
import java.sql.Statement; import java.sql.ResultSet;
import java.sql.DatabaseMetaData; import java.sql.SQLException;
import java.util.HashMap; import java.sql.Statement;
import java.util.Hashtable; import java.util.HashMap;
import java.util.Iterator; import java.util.Hashtable;
import java.util.Properties; import java.util.Iterator;
import java.util.StringTokenizer; import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger; import org.apache.commons.io.FileUtils;
import org.apache.log4j.Level;
import de.memtext.db.ConnectionCreator;
import de.memtext.util.DateUtils; import de.memtext.db.ConnectionCreator;
import de.memtext.util.GetOpts; import de.memtext.util.DateUtils;
import de.memtext.util.StringUtils; import de.memtext.util.GetOpts;
import de.superx.common.DBServletException; import de.memtext.util.GetOpts.Options;
import de.superx.common.FieldContainer; import de.memtext.util.StringUtils;
import de.superx.common.Sichten; import de.superx.common.FieldContainer;
import de.superx.common.StandaloneSicht; import de.superx.common.Sichten;
import de.superx.common.SuperX_el; import de.superx.common.StandaloneSicht;
import de.superx.common.SxResultRow; import de.superx.common.SuperX_el;
import de.superx.common.SxResultSet; import de.superx.common.SxResultRow;
import de.superx.common.SxSqlHelper; import de.superx.common.SxResultSet;
import de.superx.common.SxUser; import de.superx.common.SxSqlHelper;
import de.superx.common.TableFieldExists; import de.superx.common.SxUser;
import de.superx.common.TemplateProcessor; import de.superx.common.TableFieldExists;
import de.superx.servlet.SuperXManager; import de.superx.common.TemplateProcessor;
import de.superx.servlet.SxPools; import de.superx.servlet.SxPools;
import de.superx.servlet.SxSQL_Server; import de.superx.util.PropsReader;
import de.superx.util.PropsReader; import de.superx.util.SqlStringUtils;
import de.superx.util.SqlStringUtils;
public class FMParser extends TemplateProcessor {
public class FMParser extends TemplateProcessor { private String dbprop, infile, outfile;
private String dbprop, infile, outfile;
private Properties props; private Properties props;
private Statement stm; private Statement stm;
private String isSimpleParser;
private static String sqlDialect; private String isSimpleParser;
FMParser() { private static String sqlDialect;
super(DEFAULT_MANDANTEN_ID);
public FMParser(String mandantenId, Connection con) throws SQLException {
super(mandantenId, con);
} if (con.getMetaData().getDatabaseProductName().toLowerCase().contains("postgres")) {
sqlDialect = "Postgres";
private void run() throws FileNotFoundException, IOException, Exception { }
dbprop = GetOpts.getValue("-dbproperties:"); }
props = PropsReader.prepareProps(new File(dbprop));
infile = GetOpts.getValue("-in:"); public FMParser(String mandantenId) {
outfile = GetOpts.getValue("-out:"); super(mandantenId);
if (GetOpts.isPresent("-simpleParser")) }
isSimpleParser = GetOpts.getValue("-simpleParser:");
String input = StringUtils.readFile(new File(infile)); private void run() throws FileNotFoundException, IOException, Exception {
String output = ""; dbprop = GetOpts.getValue(Options.opt_dbprops);
if (isSimpleParser != null && isSimpleParser.equalsIgnoreCase("true")) { props = PropsReader.prepareProps(new File(dbprop));
output = simpleParser(dbprop, input); infile = GetOpts.getValue(Options.opt_in);
} else { outfile = GetOpts.getValue(Options.opt_out);
initConAndParser(); if (GetOpts.isPresent(Options.opt_simpPars))
isSimpleParser = GetOpts.getValue(Options.opt_simpPars);
sqlDialect = de.superx.util.SqlStringUtils.getSqlDialect(props String input = StringUtils.readFile(new File(infile));
.getProperty("driverName")); String output = "";
if (isSimpleParser != null && isSimpleParser.equalsIgnoreCase("true")) {
HashMap map = new HashMap(); output = simpleParser(dbprop, input);
map.put("TableFieldExists", new TableFieldExists(con)); } else {
SxPools.initTesting(props);
output = "--automatically created by SuperX/Freemarker for " initConAndParser();
+ sqlDialect + " (" + DateUtils.getTodayString() + " " sqlDialect = de.superx.util.SqlStringUtils.getSqlDialect(props.getProperty("driverName"));
+ DateUtils.getNowString() + ")\n" HashMap map = new HashMap();
+ process("FM-Parsing " + infile, input, map, sqlDialect); map.put("TableFieldExists", new TableFieldExists(con));
stm.close(); output = "--automatically created by SuperX/Freemarker for " + sqlDialect + " ("
con.close(); + DateUtils.getTodayString() + " " + DateUtils.getNowString() + ")\n"
} + process("FM-Parsing " + infile, input, map, sqlDialect);
StringUtils.write(new File(outfile), output); stm.close();
} con.close();
}
private void initConAndParser() throws IOException, SQLException, FileUtils.writeStringToFile(new File(outfile), output);
ClassNotFoundException { }
super.con = ConnectionCreator.getConnectionCryptPassword(dbprop,
"driverName", "connectionURL", "connectionName", private void initConAndParser() throws IOException, SQLException, ClassNotFoundException {
"connectionPassword"); super.con = ConnectionCreator.getConnectionCryptPassword(dbprop, "driverName", "connectionURL",
"connectionName", "connectionPassword");
stm = con.createStatement(); stm = con.createStatement();
if(SqlStringUtils.tableExists(con,"fm_templates",DEFAULT_MANDANTEN_ID)) if (SqlStringUtils.tableExists(con, "fm_templates", mandantenID)) {
{ setTemplates(readFromDb("select trim(both from id),content from fm_templates"));
setTemplates(readFromDb("select trim(both from id),content from fm_templates")); repositoryToMap(readFromDb(REPOSITORY_SELECT), repositoryMap);
repositoryToMap(readFromDb(REPOSITORY_SELECT), repositoryMap); }
} if (SqlStringUtils.tableExists(con, "konstanten", mandantenID)) {
if(SqlStringUtils.tableExists(con,"konstanten",DEFAULT_MANDANTEN_ID)) SxResultSet rs = readFromDb("select trim(both from beschreibung),apnr from konstanten");
{ for (Iterator it = rs.iterator(); it.hasNext();) {
SxResultSet rs = readFromDb("select trim(both from beschreibung),apnr from konstanten"); SxResultRow row = (SxResultRow) it.next();
for (Iterator it = rs.iterator(); it.hasNext();) { String beschreibung = (String) row.get(0);
SxResultRow row = (SxResultRow) it.next(); repositoryMap.put("K_" + beschreibung.trim(), row.get(1));
String beschreibung = (String) row.get(0); }
}
repositoryMap.put("K_" + beschreibung.trim(), row.get(1)); }
}
} @Override
} protected SxResultSet readFromDb(String sql) throws SQLException {
SuperX_el el = new SuperX_el();
SxSqlHelper sh = new SxSqlHelper();
sh.execute(sql, this.con, el);
protected SxResultSet readFromDb(String sql) throws SQLException { if (el.getError_String() != null && !el.getError_String().trim().equals("")) {
SuperX_el el = new SuperX_el(); throw new SQLException("\nProblem bei:" + "\n\n Meldung:" + el.getError_String() + "\n sql:" + sql);
}
SxSqlHelper sh=new SxSqlHelper(); return el.getResultSet();
sh.execute(sql, this.con, el); }
/**
if (el.getError_String() != null * @deprecated
&& !el.getError_String().trim().equals("")) * @param sql
throw new SQLException("\nProblem bei:" + "\n\n Meldung:" * @return
+ el.getError_String() + "\n sql:" + sql); * @throws SQLException
*/
return el.getResultSet(); @Deprecated
protected SxResultSet readFromDbAlt(String sql) throws SQLException {
SxResultSet result = new SxResultSet();
} ResultSet rs = stm.executeQuery(sql);
result.setColumnNames(rs.getMetaData());
int naturalOrder = 0;
while (rs.next()) {
SxResultRow row = new SxResultRow(rs.getMetaData().getColumnCount(), naturalOrder++);
/** for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
* @deprecated if (rs.getMetaData().getColumnType(i) == java.sql.Types.LONGVARCHAR)
* @param sql row.add(rs.getString(i));
* @return else
* @throws SQLException row.add(rs.getObject(i));
*/ }
protected SxResultSet readFromDbAlt(String sql) throws SQLException { result.add(row);
SxResultSet result = new SxResultSet(); }
ResultSet rs = stm.executeQuery(sql); rs.close();
return result;
result.setColumnNames(rs.getMetaData()); }
int naturalOrder = 0;
while (rs.next()) { public static void main(String[] args) {
SxResultRow row = new SxResultRow( GetOpts.setOpts(args);
rs.getMetaData().getColumnCount(), naturalOrder++); String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[]{Options.opt_dbprops, Options.opt_in, Options.opt_out});
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) { if (isdrin != null) {
if (rs.getMetaData().getColumnType(i) == java.sql.Types.LONGVARCHAR) System.err.println("-dbproperties: -in: -out:");
row.add(rs.getString(i)); System.exit(1);
else }
row.add(rs.getObject(i)); try {
} new FMParser(DEFAULT_MANDANTEN_ID).run();
result.add(row); } catch (Exception e) {
} System.err.println("Fehler beim FM-Parsen ");
rs.close(); e.printStackTrace();
return result; System.exit(1);
} }
}
public static void main(String[] args) {
GetOpts.setOpts(args); /*
String isdrin = GetOpts * Einfacher Parser für Fremddatenbanken, nur sqlDialect wird übergeben wird von
.isAllRequiredOptionsPresent("-dbproperties,-in,-out"); * DOSQL direkt aufgerufen
if (isdrin != null) { */
System.err.println("-dbproperties: -in: -out:"); public static String simpleParser(String dbprop, String input)
System.exit(1); throws FileNotFoundException, IOException, Exception {
} Properties props = PropsReader.prepareProps(new File(dbprop));
try { String output = "";
new FMParser().run(); sqlDialect = de.superx.util.SqlStringUtils.getSqlDialect(props.getProperty("driverName"));
HashMap map = new HashMap();
} catch (Exception e) { try {
System.err.println("Fehler beim FM-Parsen "); output = "--automatically created by SuperX/Freemarker for " + sqlDialect + " ("
e.printStackTrace(); + DateUtils.getTodayString() + " " + DateUtils.getNowString() + ")\n"
System.exit(1); + new FMParser(DEFAULT_MANDANTEN_ID).process("FM-Parsing ", input, map, sqlDialect);
} } catch (Exception e) {
System.err.println("Fehler beim FM-Parsen ");
} e.printStackTrace();
System.exit(1);
/* }
* Einfacher Parser für Fremddatenbanken, nur sqlDialect wird übergeben wird return output;
* von DOSQL direkt aufgerufen }
*/
public static String simpleParser(String dbprop, String input) /**
throws FileNotFoundException, IOException, Exception { * Methode war ursprünglich für direktes Einspielen einer einzelnen konkret mit
Properties props = PropsReader.prepareProps(new File(dbprop)); * name_intern benannten Sicht. Jetzt erweitert, dass aufgebaute Sicht auch
String output = ""; * zurückgeliefert wird, damit eine sichtsequence aufgebaut werden kann
sqlDialect = de.superx.util.SqlStringUtils.getSqlDialect(props */
.getProperty("driverName")); @Override
protected StandaloneSicht addSqlVarSicht(HashMap hmap, String varname, String name_intern, String gewuenschterStand)
HashMap map = new HashMap(); throws SQLException {
try { String sql = "select tid,name,label,'',beschreibung,quelle,standbutton,art \n"
output = "--automatically created by SuperX/Freemarker for " + " ,type,alt_hier_id,treecfgtable,treecfgid,gueltig_seit,gueltig_bis,xmlmaxentries,name_intern,attribut1,attribut2,attribut3,cacheapplet,cachexml \n"
+ sqlDialect + "from sichten where name_intern='"
+ " (" + name_intern
+ DateUtils.getTodayString() + "' and aktiv=1 order by type";
+ " " SxResultSet roh = new SxResultSet();
+ DateUtils.getNowString() StandaloneSicht sicht = null;
+ ")\n" roh = readFromDb(sql);
+ new FMParser().process("FM-Parsing ", input, map, Sichten sichten = new Sichten();
sqlDialect); SxUser user = new SxUser();
user.setAdmin(true); // Adminuser ok weil nur von DOSQL gebraucht
} catch (Exception e) { sichten.setUser(user);
System.err.println("Fehler beim FM-Parsen "); for (Iterator iter = roh.iterator(); iter.hasNext();) {
e.printStackTrace(); SxResultRow row = (SxResultRow) iter.next();
System.exit(1); Integer id = Integer.valueOf(1);
} try {
return output; sichten.initNonInternalSicht(DEFAULT_MANDANTEN_ID, StandaloneSicht.class, row, id);
sicht = (StandaloneSicht) sichten.getById(id);
} sicht.setConnection(con);
/** sicht.setSqlDialect(sqlDialect);
Methode war ursprünglich für direktes Einspielen einer einzelnen konkret mit name_intern benannten Sicht. if (gewuenschterStand.trim().startsWith("today")) {
Jetzt erweitert, dass aufgebaute Sicht auch zurückgeliefert wird, damit eine sichtsequence aufgebaut werden kann gewuenschterStand = DateUtils.getTodayString();
*/ }
protected StandaloneSicht addSqlVarSicht(HashMap hmap, String varname, String name_intern,String gewuenschterStand) sicht.setStand(new Hashtable(), hmap, new FieldContainer(), gewuenschterStand);
throws SQLException { hmap.put(varname, sicht);
String mandantenID="default"; // package de.superx.bin wird nur von Scripten gebraucht, MandantenID unerheblich } catch (Exception e) {
String sql = "select tid,name,label,'',beschreibung,quelle,standbutton,art \n" e.printStackTrace();
+ " ,type,alt_hier_id,treecfgtable,treecfgid,gueltig_seit,gueltig_bis,xmlmaxentries,name_intern,attribut1,attribut2,attribut3,cacheapplet,cachexml \n" throw new SQLException("Fehler beim Aufbau von Sicht " + name_intern + " " + e);
+ "from sichten where name_intern='" }
+ name_intern }
+ "' and aktiv=1 order by type"; return sicht;
SxResultSet roh = new SxResultSet(); }
StandaloneSicht sicht=null; }
roh = readFromDb(sql);
Sichten sichten = new Sichten(); // Created on 08.12.2006 at 18:03:46
SxUser user = new SxUser(mandantenID);
user.setAdmin(true); // Adminuser ok weil nur von DOSQL gebraucht
sichten.setUser(user);
for (Iterator iter = roh.iterator(); iter.hasNext();) {
SxResultRow row = (SxResultRow) iter.next();
Integer id = new Integer(1); // (Integer) row.get(0);
try {
sichten.initNonInternalSicht(mandantenID, StandaloneSicht.class,
row, id);
sicht = (StandaloneSicht) sichten.getById(id);
sicht.setConnection(con);
sicht.setSqlDialect(sqlDialect);
if (gewuenschterStand.trim().startsWith("today"))
gewuenschterStand = DateUtils.getTodayString();
sicht.setStand(new Hashtable(),hmap,new FieldContainer(),gewuenschterStand);
hmap.put(varname, sicht);
} catch (Exception e) {
e.printStackTrace();
throw new SQLException("Fehler beim Aufbau von Sicht "
+ name_intern + " " + e);
}
}
return sicht;
}
}
// Created on 08.12.2006 at 18:03:46

745
src/de/superx/bin/GxstageCSVImport.java

@ -0,0 +1,745 @@
package de.superx.bin;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.text.ParseException;
import java.util.Hashtable;
import java.util.StringTokenizer;
import org.postgresql.PGConnection;
import org.postgresql.copy.CopyManager;
import de.memtext.util.DateUtils;
import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
import de.superx.bin.SxConnection.DriverClass;
/*
*
* Basierend auf de.superx.common.FileToTableUpload mit Unterstützung für Header
*
*/
public class GxstageCSVImport {
private String logfile;
private String dbpropfile;
private String mode="stop";
private String inFormat;
private String targetTable;
private String srcFile;
private static final boolean header=true;
private String delim="^";
private String encoding;
private String inserts="";
private boolean continueAfterError;
private boolean removeTrailingDelim=true;
private boolean isPostgres;
private boolean useBatch=true;
private static int maxCols=1000;
private String[] insert_cols = new String[maxCols];
private int[] insert_types = new int[maxCols];
private int numberOfColumns;
public long numberOfRows;
private Connection uploadConnection;
private DatabaseMetaData dbmd;
private PreparedStatement pst;
private static String usage =
"-------------------------------------\n"
+ "Gebrauch: java de.superx.bin.GxstageCSVImport \n-dbproperties:<Pfad zu db.properties> \n"
+ "-table:<Tabellenname> \n-unl:<Dateipfad Quelldatei>(optional, default ist Tabellenname.unl) \n-delim:<delimiter>(optional, default ist ^) \n-header:<true|false>(optional, mit Feldüberschriften, default ist false)\n"
+ "-mode:<stop|exclude-row>(optional, default is stop) #Bei Fehlerhaften Daten kann das Hochladen gestoppt werden, oder der Datensatz wird übersprungen"
+ "\n-inserts:<false|simple|batch>(optional, default is false) #Bei -inserts:simple und batch werden Die Rohdaten in Insert-sql-Statements übersetzt (nur für Debugging-Zwecke, sehr langsam. Der Modus exclude-field ist darüberhinaus nicht anwendbar)"
+ "\n-encoding:<utf8,ISO-8859-1, default ist System.file.encoding>"
+ "\n---------------------------------------------------";
public Connection getUploadConnection() {
return uploadConnection;
}
public void setUploadConnection(Connection uploadConnection) {
this.uploadConnection = uploadConnection;
}
public boolean isRemoveTrailingDelim() {
return removeTrailingDelim;
}
public void setRemoveTrailingDelim(boolean removeTrailingDelim) {
this.removeTrailingDelim = removeTrailingDelim;
}
public String getDbpropfile() {
return dbpropfile;
}
public void setDbpropfile(String dbpropfile) {
this.dbpropfile = dbpropfile;
}
public String getMode() {
return mode;
}
public void setMode(String mode) {
if (!mode.equals("stop") && !mode.equals("exclude-field")&& !mode.equals("transaction"))
mode = "exclude-row";
this.mode = mode;
}
public String getInFormat() {
return inFormat;
}
public void setInFormat(String inFormat) {
this.inFormat = inFormat;
}
public String getTargetTable() {
return targetTable;
}
public void setTargetTable(String targetTable) {
this.targetTable = targetTable;
}
public String getSrcFile() {
return srcFile;
}
public void setSrcFile(String srcFile) {
this.srcFile = srcFile;
}
public String getDelim() {
return delim;
}
public void setDelim(String delim) {
if (delim.equals("tab"))
delim = "\t"; //Tab
if (delim.equals(""))
delim = "^"; //default Delimiter
this.delim = delim;
}
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
if(encoding==null || encoding.equals(""))
encoding="UTF-8";
this.encoding = encoding;
}
public String getInserts() {
return inserts;
}
public void setInserts(String inserts) {
if(inserts.equalsIgnoreCase("batch"))
useBatch=true;
if(inserts.equalsIgnoreCase("simple"))
useBatch=false;
this.inserts = inserts;
}
public boolean isContinueAfterError() {
return continueAfterError;
}
public void setContinueAfterError(boolean continueAfterError) {
this.continueAfterError = continueAfterError;
}
public String uploadFile() throws Exception
{
String protokoll="";
if(inFormat!=null&&inFormat.equalsIgnoreCase("xml"))
{
throw new IllegalArgumentException("xml nicht unterstützt");
}
else
{
protokoll=uploadCSV();
}
if(protokoll.indexOf("Exception")>-1)
throw new Exception(protokoll);
return protokoll;
}
private String uploadCSV() throws Exception
{
String line;
String line2;
File outFile=null;
String protokoll="";
if(isPostgres && !inserts.equalsIgnoreCase("simple") && !inserts.equalsIgnoreCase("batch"))
{
if(removeTrailingDelim)
srcFile=removeTrailingDelim(srcFile);
protokoll=uploadCSVinPostgres(srcFile,removeTrailingDelim);
}
else
protokoll=uploadCSVwithAnsiSQL(srcFile);
return protokoll;
}
private String removeTrailingDelim(String srcFile) throws UnsupportedEncodingException, FileNotFoundException, IOException {
String line;
File outFile;
String returnSrcFile=srcFile+".tmp";
BufferedReader in2 = new BufferedReader(new InputStreamReader(new FileInputStream(srcFile), encoding));
outFile=new File(srcFile+".tmp");
FileOutputStream out = new FileOutputStream(outFile, false);
PrintStream out2 = new PrintStream(out, true, encoding);
while ((line = in2.readLine()) != null) {
if (line.endsWith(delim))
line=line.substring(0,line.length()-delim.length());
out2.println(line);
out2.flush();
}
return returnSrcFile;
}
private String uploadCSVinPostgres(String srcFile, boolean deleteSrcFile) {
//neues Format für Postgres42-Treiber mit Format csv, geht aber auch mit Postgres9.2 Treiber
/*copy target_table (b, a, c)
from file.csv
with (delimiter ',', format csv, header)*/
// String test=" (hs_nr,gjahr,inst_ext,bund_fachgebiet,asp_akl,rest,rest_vj,zugang,abgang,abschr,histor_ahk,umbuch,zuschr,abschr_ges,datum,extkotr) ";
String cols="";
String msg="";
boolean dataFound=true;
try
{
if (header)
{
String headersInFile = getHeaderString(srcFile);
if (headersInFile!=null)
{
cols=headersInFile.replace(delim,",");
cols=" ("+cols+") ";
}
else
{
//headers ist null, Datei leer
dataFound=false;
numberOfRows=0;
}
}
//default quote ist ", kann aber vorkommen, daher quote Zeichen auf nicht erwartetes Backspace Oktal 10 setzen
String copySql = "COPY " + targetTable + cols+ " FROM STDIN (FORMAT csv, QUOTE '\b', DELIMITER '"+delim+"',NULL '',ENCODING '"+ encoding+"'"+(header?", HEADER true":"")+")";
if (dataFound)
{
final CopyManager cpm = ((PGConnection) uploadConnection).getCopyAPI();
msg = "";
FileReader in3 = new FileReader(srcFile);
Reader in4 = new BufferedReader(in3);
numberOfRows = cpm.copyIn(copySql, in4);
}
if(deleteSrcFile)
{
File outFile=new File(srcFile);
if(outFile!=null)
outFile.delete();
}
} catch (Exception e) {
msg=e.toString();
}
return msg;
}
protected String getHeaderString(String srcFile) throws FileNotFoundException, UnsupportedEncodingException, IOException {
FileInputStream fileInputStream = new FileInputStream(srcFile);
InputStreamReader ir=new InputStreamReader(fileInputStream, encoding);
BufferedReader br = new BufferedReader(ir);
String headersInFile=br.readLine();
br.close();
ir.close();
fileInputStream.close();
return headersInFile;
}
private String uploadCSVwithAnsiSQL(String srcFile) throws SQLException, FileNotFoundException, IOException {
numberOfRows=0;
String text;
String text2;
String msg="";
int zeilennr=1;
int fehlerSaetze=0;
String headersInFile=null;
if (header)
{ headersInFile = getHeaderString(srcFile);
}
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(srcFile), encoding));
initializeColumnSchema(headersInFile);
String insertHead=createPreparedStatementHead(headersInFile);
pst = uploadConnection.prepareStatement(insertHead);
if(useBatch)
pst.clearBatch();
boolean isFirstRow=true;
while ((text = in.readLine()) != null) {
if (isFirstRow&&header) { isFirstRow=false; continue;}
if (text.endsWith("\\")) {
text=text.substring(0, text.length()-1);
text2 = in.readLine();
if (text2 != null) {
text += "\n"+ text2;
while (text2.endsWith("\\")) {
text=text.substring(0, text.length()-1);
text2 = in.readLine();
if (text2 != null)
text += "\n"+text2;
}
}
}
String prepare =
createPreparedInsertStatement(zeilennr,
insertHead,
text);
if(!prepare.equals("") && mode.equals("stop"))
{
msg=prepare;
break;
}
if(useBatch)
pst.addBatch();
else
pst.executeUpdate();
numberOfRows++;
}
if(useBatch)
pst.executeBatch();
return msg;
}
private String createPreparedInsertStatement(
int line,
String insertHead,
String text)
throws SQLException {
int p;
int i=0;
int k=0;
String errmsg = "";
String feld_wert;
//pst.clearParameters();
do {
//ggf. Trennzeichen am Ende hinzufügen:
if(!text.endsWith(delim))
text+= delim;
p = text.indexOf(delim, i);
//logger.config("Type "+types[k]);
//maskierte Trennzeichen abfangen:
if(p>0 && text.substring(p-1, p).equals("\\"))
p = text.indexOf(delim, p+1);
if (p > -1 ) {
if(p==-1)
feld_wert = text.substring(i);
else
feld_wert = text.substring(i, p);
//wenn der Feldwert zufällig das Zeichen "\\n" enthält, wird es zu "\n"
if(feld_wert != null && (feld_wert.indexOf("\\\\n") >0 ))
{
feld_wert=de.memtext.util.StringUtils.replace(feld_wert, "\\\\n", "\\n");
}
//wenn der Feldwert das Zeichen "\Trennzeichen" enthält, wird der \ entfernt
if(feld_wert != null && (feld_wert.indexOf("\\"+delim) >0 ))
{
feld_wert=de.memtext.util.StringUtils.replace(feld_wert, "\\", "");
}
//wenn der Feldwert das Zeichen "\\" enthält, wird ein \ entfernt
if(feld_wert != null && (feld_wert.indexOf("\\\\") >0 ))
{
feld_wert=de.memtext.util.StringUtils.replace(feld_wert, "\\\\", "\\");
}
errmsg = feld_wert_to_pst(line,k, errmsg, feld_wert);
k++;
i = p + 1;
}
} while (p > -1);
return errmsg;
}
private String feld_wert_to_pst(int line, int col, String errmsg, String feld_wert) throws SQLException {
if( col >= numberOfColumns)
errmsg+= "Anzahl Spalten in Datei ist "+col+", aber es sollten nur "+(numberOfColumns-1)+" Spalten sein. Bitte prüfen Sie das Trennzeichen";
else
{
if (feld_wert.equals(""))
try {
pst.setNull(col + 1, insert_types[col]);
} catch (SQLException e1) {
errmsg += e1.toString();
} else {
switch (insert_types[col]) {
case Types.BIGINT :
case Types.TINYINT :
case Types.SMALLINT :
case Types.INTEGER :
try {
int myInt = (int) Integer.parseInt(feld_wert.trim());
pst.setInt(col + 1, myInt);
} catch (NumberFormatException e1) {
errmsg += e1.toString();
setFieldToNull(col, insert_types, pst);
} catch (SQLException e1) {
errmsg += conversionException(line, col, feld_wert,e1.toString());
setFieldToNull(col, insert_types, pst);
}
break;
case Types.FLOAT :
try {
float myFloat =
(float) Float.parseFloat(feld_wert.trim());
pst.setFloat(col + 1, myFloat);
} catch (NumberFormatException e1) {
errmsg += conversionException(line, col, feld_wert,e1.toString());
setFieldToNull(col, insert_types, pst);
} catch (SQLException e1) {
errmsg += conversionException(line, col, feld_wert,e1.toString());
setFieldToNull(col, insert_types, pst);
}
break;
case Types.REAL :
case Types.DOUBLE :
case Types.NUMERIC :
case Types.DECIMAL :
try {
double myDouble =
(double) Double.parseDouble(feld_wert.trim());
pst.setDouble(col + 1, myDouble);
} catch (NumberFormatException e1) {
errmsg += conversionException(line, col, feld_wert,e1.toString());
setFieldToNull(col, insert_types, pst);
} catch (SQLException e1) {
errmsg += conversionException(line, col, feld_wert, e1.toString());
setFieldToNull(col, insert_types, pst);
}
break;
case Types.CHAR :
case Types.VARCHAR :
default :
if(feld_wert.equals(" "))
feld_wert=""; //Leerzeichen im UNL-File wird zu Leerstring
try {
pst.setString(col + 1, feld_wert);
} catch (SQLException e1) {
errmsg += conversionException(line, col, feld_wert,e1.toString());
setFieldToNull(col, insert_types, pst);
}
break;
case Types.LONGVARCHAR :
ByteArrayInputStream by =
new ByteArrayInputStream(feld_wert.getBytes());
pst.setAsciiStream(
col + 1,
by,
feld_wert.length());
break;
case Types.DATE :
try {
java.util.Date datum =
DateUtils.parse(feld_wert.trim());
feld_wert = DateUtils.formatUS(datum);
//Leider ist dieser Schritt wg java.sql.Date nötig
pst.setDate(
col + 1,
java.sql.Date.valueOf(feld_wert));
} catch (SQLException e1) {
errmsg += conversionException(line, col, feld_wert, e1.toString());
setFieldToNull(col, insert_types, pst);
} catch (ParseException e1) {
errmsg += conversionException(line, col, feld_wert, e1.toString());
setFieldToNull(col, insert_types, pst);
}
catch (IllegalArgumentException e1) {
errmsg += conversionException(line, col, feld_wert, e1.toString());
setFieldToNull(col, insert_types, pst);
}
break;
case Types.TIME :
try {
//Time zeit = (java.sql.Time)
//DateUtils.timeParse(feld_wert);
pst.setTime(col + 1, java.sql.Time.valueOf(
feld_wert.trim()));
} catch (SQLException e1) {
errmsg += conversionException(line, col, feld_wert, e1.toString());
setFieldToNull(col, insert_types, pst);
}
catch (IllegalArgumentException e1) {
errmsg += conversionException(line, col, feld_wert, e1.toString());
setFieldToNull(col, insert_types, pst);
}
break;
case Types.TIMESTAMP :
try {
java.util.Date datum =
DateUtils.dateTimeParse(feld_wert.trim());
feld_wert = DateUtils.dateTimeFormatUS(datum);
//Leider ist dieser Schritt wg java.sql.Date nötig
pst.setTimestamp(
col + 1,
java.sql.Timestamp.valueOf(
feld_wert + ".0"));
} catch (SQLException e1) {
errmsg += conversionException(line, col,feld_wert, e1.toString());
setFieldToNull(col, insert_types, pst);
} catch (ParseException e1) {
errmsg += conversionException(line, col, feld_wert, e1.toString());
setFieldToNull(col, insert_types, pst);
}
catch (IllegalArgumentException e1) {
errmsg += conversionException(line, col, feld_wert, e1.toString());
setFieldToNull(col, insert_types, pst);
}
break;
case Types.BIT :
// Types.BOOLEAN gibt es im jdk 1.3 nicht
try {
boolean wf =
(boolean) Boolean.getBoolean(feld_wert.trim());
pst.setBoolean(col + 1, wf);
} catch (SQLException e1) {
errmsg += conversionException(line, col, feld_wert, e1.toString());
setFieldToNull(col, insert_types, pst);
}
//Boolean wird vom Informix-Treiber als OTHER (1111) erkannt
//Da aber default '' ist, klappt es trotzdem
break;
}
}
}
return errmsg;
}
private void setFieldToNull(
int k,
int[] insert_types,
PreparedStatement pst) {
if (mode.equals("exclude-field"))
try {
pst.setNull(k + 1, insert_types[k]);
} catch (SQLException e3) {
System.err.println("Invalid Field " + (k + 1) + " could not be set to null");
}
}
private String conversionException(int line,int col, String field_value, String error) {
String err_msg = "";
err_msg = "Error in line "+line+" in Column " + (col + 1) + " "+insert_cols[col]+" value "+ field_value+ ": " + error.toString() + "; ";
return err_msg;
}
private void initializeColumnSchema(String headersInFile) throws SQLException
{
ResultSet rs = null;
ResultSetMetaData rsmd = null;
String tabelle=targetTable;
if (!dbmd.storesLowerCaseIdentifiers())
tabelle = tabelle.toUpperCase();
rs =dbmd.getColumns(uploadConnection.getCatalog(), null, tabelle, null);
rsmd = rs.getMetaData();
Hashtable<String,Integer> fieldtypes=new Hashtable<String,Integer>();
while (rs.next()) {
fieldtypes.put(rs.getObject("COLUMN_NAME").toString(),Integer.valueOf(rs.getInt("DATA_TYPE")));
}
int i=0;
StringTokenizer st=new StringTokenizer(headersInFile,delim);
while (st.hasMoreTokens())
{
String colname=st.nextToken();
insert_cols[i]= colname ;
insert_types[i] = fieldtypes.get(colname).intValue();
i++;
}
numberOfColumns=i;
if(!dbmd.supportsBatchUpdates())
useBatch=false;
}
private String createPreparedStatementHeadOld() throws SQLException
{
String sql=null;
String insert_head = "insert into " + targetTable+"(";
String insert_val="";
for (int i = 0; i < numberOfColumns; i++)
{
insert_head += insert_cols[i] + ", ";
insert_val+="?, ";
}
insert_head = insert_head.substring(0, insert_head.length() - 2);
insert_val = insert_val.substring(0, insert_val.length() - 2);
insert_head +=") values( ";
sql=insert_head + insert_val+");";
return sql;
}
private String createPreparedStatementHead(String headersInFile) throws SQLException
{
String sql=null;
String insert_head = "insert into " + targetTable+"(";
String insert_val="";
if (headersInFile!=null)
{
StringTokenizer st=new StringTokenizer(headersInFile,delim);
while (st.hasMoreTokens())
{
String colname=st.nextToken();
insert_head += colname + ", ";
insert_val+="?, ";
}
}
else
{
for (int i = 0; i < numberOfColumns; i++)
{
insert_head += insert_cols[i] + ", ";
insert_val+="?, ";
}
}
insert_head = insert_head.substring(0, insert_head.length() - 2);
insert_val = insert_val.substring(0, insert_val.length() - 2);
insert_head +=") values( ";
sql=insert_head + insert_val+");";
return sql;
}
public Connection getConnection(Connection myConnection,String propfile) throws Exception {
if(myConnection==null)
{
SxConnection mySxConnection = null;
mySxConnection = new SxConnection();
mySxConnection.setPropfile(propfile);
myConnection = mySxConnection.getConnection();
String db_driver = mySxConnection.m_DriverClass.stringValue();
if(db_driver.equals(DriverClass.dc_postgre.stringValue()))
isPostgres=true;
}
dbmd = myConnection.getMetaData();
return myConnection;
}
public static void main(String args[]) {
try {
GetOpts.setOpts(args);
String isdrin =
GetOpts.isAllRequiredOptionsPresent(new Options[] {Options.opt_dbprops,Options.opt_table,Options.opt_unl});
if (isdrin != null) {
System.err.println("Folgende Optionen fehlen: " + isdrin);
System.err.println(usage);
System.exit(1);
}
GxstageCSVImport myUploader=new GxstageCSVImport();
//GetOpts myOpts=new GetOpts();
if (GetOpts.isPresent(Options.opt_dbprops))
myUploader.setDbpropfile(GetOpts.getValue(Options.opt_dbprops));
if (GetOpts.isPresent(Options.opt_inFormat))
myUploader.setInFormat(GetOpts.getValue(Options.opt_inFormat));
if (GetOpts.isPresent(Options.opt_table))
myUploader.setTargetTable( GetOpts.getValue(Options.opt_table));
if (GetOpts.isPresent(Options.opt_unl))
myUploader.setSrcFile(GetOpts.getValue(Options.opt_unl));
else
myUploader.setSrcFile(myUploader.getTargetTable() + ".unl");
if (GetOpts.isPresent(Options.opt_header)&&!GetOpts.getValue(Options.opt_header).equalsIgnoreCase("true"))
{
throw new IllegalArgumentException("nur header=true unterstützt");
}
if (GetOpts.isPresent(Options.opt_delim))
myUploader.setDelim(GetOpts.getValue(Options.opt_delim));
if (GetOpts.isPresent(Options.opt_encoding))
{
String encodingParam=GetOpts.getValue(Options.opt_encoding);
if(encodingParam != null && !encodingParam.equals("") )
myUploader.setEncoding(encodingParam);
}
else
myUploader.setEncoding(System.getProperty("file.encoding"));
if (GetOpts.isPresent(Options.opt_mode)) {
myUploader.setMode(GetOpts.getValue(Options.opt_mode).toLowerCase());
}
if (GetOpts.isPresent(Options.opt_inserts))
myUploader.setInserts(GetOpts.getValue(Options.opt_inserts));
long jetzt = new java.util.Date().getTime() ;
myUploader.setUploadConnection(myUploader.getConnection(null,myUploader.getDbpropfile()));
if (new File(myUploader.getSrcFile()).length()==0)
{
System.out.println("Nichts zu tun, Datei "+myUploader.getSrcFile()+" ist leer");
}
else
{
String protokoll=myUploader.uploadFile();
long erstrecht = new java.util.Date().getTime() ;
System.out.println(myUploader.numberOfRows+" lines loaded");
System.out.println("File "+myUploader.getSrcFile() +" uploaded");
if(protokoll.equals(""))
protokoll= " in "+(erstrecht-jetzt)/1000 +" Sec.";
System.out.println(protokoll);
}
} catch (Exception ex) {
System.err.println("Upload fehlgeschlagen: " + ex);
System.exit(1);
}
}
}

2
src/de/superx/bin/Iso.java

@ -1,6 +1,6 @@
package de.superx.bin; package de.superx.bin;
import javax.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServlet;
public class Iso extends HttpServlet { public class Iso extends HttpServlet {

39
src/de/superx/bin/KettleExecutor.java

@ -5,14 +5,11 @@ import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.exception.KettleException;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
import de.memtext.util.StringUtils; import de.memtext.util.StringUtils;
import de.superx.bin.fm.EtlStarter; import de.superx.bin.fm.EtlStarter;
import de.superx.common.DBServletException; import de.superx.common.DBServletException;
@ -22,6 +19,7 @@ import de.superx.common.SxResultSet;
import de.superx.servlet.ServletUtils; import de.superx.servlet.ServletUtils;
import de.superx.servlet.SuperXManager; import de.superx.servlet.SuperXManager;
import de.superx.servlet.SxPools; import de.superx.servlet.SxPools;
import static de.superx.servlet.SxSQL_Server.DEFAULT_MANDANTEN_ID;
public class KettleExecutor { public class KettleExecutor {
private String mandantenID; private String mandantenID;
@ -43,14 +41,14 @@ public class KettleExecutor {
this.jobParams = jobParams; this.jobParams = jobParams;
} }
public StringBuffer perform() throws IOException, SQLException, DBServletException { public StringBuffer perform() throws IOException {
try { try {
initSxJob(); initSxJob();
EtlStarter es = new EtlStarter(this.mandantenID); EtlStarter es = new EtlStarter(this.mandantenID);
if (!isModusVorschau()) { if (!isModusVorschau()) {
check_sql("vor"); check_sql("vor");
} }
resultMessages.append(es.kettleCallEmbedded(mandantenID, sxJob.getFilepath(), jobParams, isPostgres)); resultMessages.append(es.kettleCallEmbedded(sxJob.getFilepath(), jobParams, isPostgres));
if (isModusVorschau()) { if (isModusVorschau()) {
//Vor Ergebnis Vorschau einfügen //Vor Ergebnis Vorschau einfügen
resultMessages.insert(0, getPreviewInfo()); resultMessages.insert(0, getPreviewInfo());
@ -65,7 +63,7 @@ public class KettleExecutor {
return resultMessages; return resultMessages;
} }
private boolean isModusVorschau() { private boolean isModusVorschau() {
return jobParams.containsKey("Modus") && jobParams.get("Modus") != null && jobParams.get("Modus").equals("3"); return jobParams.containsKey("Modus") && jobParams.get("Modus") != null && jobParams.get("Modus").equals("3");
} }
@ -110,8 +108,7 @@ public class KettleExecutor {
} }
} }
private void initSxJob() throws SQLException, DBServletException { private void initSxJob() throws SQLException, DBServletException {
SxResultSet rs = ServletUtils.execute("Einlesen von SxJob)", "select caption,filepath,params,check_sql from sx_jobs where tid=" + jobParams.get("Job"), mandantenID); SxResultSet rs = ServletUtils.execute("Einlesen von SxJob)", "select caption,filepath,params,check_sql from sx_jobs where tid=" + jobParams.get("Job"), mandantenID);
sxJob = new SxJob(); sxJob = new SxJob();
@ -125,39 +122,35 @@ public class KettleExecutor {
} }
public static void main(String args[]) { public static void main(String args[]) {
String usage = "usage: -mandantenID:default -MODULE_PFAD:/home/superx/db/module -WEB_INF_PFAD:/home/superx/webserver/tomcat/webapps/superx/WEB-INF -job_uniquename:abc -path_to_uploadfile:/home/superx (optional)"; String usage = "usage: -mandantenID:" + DEFAULT_MANDANTEN_ID + " -MODULE_PFAD:/home/superx/db/module -WEB_INF_PFAD:/home/superx/webserver/tomcat/webapps/superx/WEB-INF -job_uniquename:abc -path_to_uploadfile:/home/superx (optional)";
GetOpts.setOpts(args); GetOpts.setOpts(args);
String isdrin = GetOpts.isAllRequiredOptionsPresent("-mandantenID,-WEB_INF_PFAD,-MODULE_PFAD,-job_uniquename"); //String isdrin = GetOpts.isAllRequiredOptionsPresent("-mandantenID,-WEB_INF_PFAD,-MODULE_PFAD,-job_uniquename");
String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[] {Options.opt_mandID,Options.opt_webinf,Options.opt_module,Options.opt_jobUniqueName});
if (isdrin != null) { if (isdrin != null) {
System.err.println(usage); System.err.println(usage);
System.exit(1); System.exit(1);
} }
String mandantenID = GetOpts.getValue("-mandantenID"); String mandantenID = GetOpts.getValue(Options.opt_mandID);
String job_uniquename = GetOpts.getValue("-job_uniquename"); String job_uniquename = GetOpts.getValue(Options.opt_jobUniqueName);
String webinfpfad=GetOpts.getValue("-WEB_INF_PFAD"); SuperXManager.setWEB_INFPfad(GetOpts.getValue(Options.opt_webinf));
if(webinfpfad != null && !webinfpfad.equals("")) SuperXManager.setModuleDir(GetOpts.getValue(Options.opt_module));
SuperXManager.setWEB_INFPfad(GetOpts.getValue("-WEB_INF_PFAD"));
SuperXManager.setModuleDir(GetOpts.getValue("-MODULE_PFAD"));
String path_to_uploadfile = ""; String path_to_uploadfile = "";
if (GetOpts.isPresent("-path_to_uploadfile")) { if (GetOpts.isPresent(Options.opt_uploadpath)) {
path_to_uploadfile = GetOpts.getValue("-path_to_uploadfile"); path_to_uploadfile = GetOpts.getValue(Options.opt_uploadpath);
if (!new File(path_to_uploadfile).exists()) { if (!new File(path_to_uploadfile).exists()) {
System.out.println("Fehler: Datei " + path_to_uploadfile + " nicht gefunden"); System.out.println("Fehler: Datei " + path_to_uploadfile + " nicht gefunden");
System.exit(-1); System.exit(-1);
} }
} }
try { try {
//muss vor SxPools init ausgeführt werden, sonst kann kein kettleDatabaseMeta-Objekt erzeugt werden java.lang.RuntimeException: Database type not found!
KettleEnvironment.init();
SxPools.init(); SxPools.init();
SxPools.get(mandantenID).init(); SxPools.get(mandantenID).init();
//SxPools.get(mandantenID).initLogging(true); //SxPools.get(mandantenID).initLogging(true);
SxPools.resetAllPools(); SxPools.resetAllPools();
} catch (Exception e) { } catch (Exception e) {
System.out.println("Fehler beim Datenbankverbindungsaufbau " + e); System.out.println("Fehler beim Datenbankverbindungsaufbau" + e);
e.printStackTrace(); e.printStackTrace();
; ;

8
src/de/superx/bin/LdapLockout.java

@ -9,6 +9,7 @@ import java.sql.ResultSet;
import java.sql.Statement; import java.sql.Statement;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
import de.superx.servlet.LdapPasswordChecker; import de.superx.servlet.LdapPasswordChecker;
/** /**
* Klasse zum Sperren von Benutzern, die in LDAP gesperrt sind * Klasse zum Sperren von Benutzern, die in LDAP gesperrt sind
@ -20,7 +21,8 @@ public class LdapLockout {
private static String usage = "Gebrauch: java de.superx.bin.LdapLockout -dbproperties=<<Pfad zu db.properties>> -ldapconfig=<<Pfad zu superx_standalone_ldap.properties>>"; private static String usage = "Gebrauch: java de.superx.bin.LdapLockout -dbproperties=<<Pfad zu db.properties>> -ldapconfig=<<Pfad zu superx_standalone_ldap.properties>>";
public static void main(String[] args) { public static void main(String[] args) {
GetOpts.setOpts(args); GetOpts.setOpts(args);
String isdrin = GetOpts.isAllRequiredOptionsPresent("-dbproperties,-ldapconfig"); String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[]{Options.opt_dbprops,
Options.opt_ldapconfig});
if (isdrin != null) { if (isdrin != null) {
System.err.println("Folgende Optionen fehlen: " + isdrin); System.err.println("Folgende Optionen fehlen: " + isdrin);
System.err.println(usage); System.err.println(usage);
@ -33,8 +35,8 @@ public class LdapLockout {
{ {
f.delete(); f.delete();
} }
LdapPasswordChecker.setup(new File(GetOpts.getValue("-ldapconfig"))); LdapPasswordChecker.setup(new File(GetOpts.getValue(Options.opt_ldapconfig)));
checkUsers(GetOpts.getValue("-dbproperties")); checkUsers(GetOpts.getValue(Options.opt_dbprops));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();

102
src/de/superx/bin/MaskenSqlUpdater.java

@ -1,54 +1,48 @@
package de.superx.bin; package de.superx.bin;
import java.io.File; import java.io.File;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.Statement; import java.sql.Statement;
import de.memtext.db.ConnectionCreator; import de.memtext.db.ConnectionCreator;
import de.memtext.util.DateUtils; import de.memtext.util.DateUtils;
import de.memtext.util.StringUtils; import de.memtext.util.StringUtils;
public class MaskenSqlUpdater { public class MaskenSqlUpdater {
public static void main(String[] args) { public static void main(String[] args) {
if (args.length != 3) { if (args.length != 3) {
System.out System.out.println("usage: MaskenSqlUpdater DB_PROPERTIES maskennummer sourcefile");
.println("usage: MaskenSqlUpdater DB_PROPERTIES maskennummer sourcefile"); System.exit(1);
System.exit(1); }
} Connection con = null;
Connection con = null; int tid = Integer.parseInt(args[1]);
int tid = Integer.parseInt(args[1]); try {
try { con = ConnectionCreator.getConnectionCryptPassword(args[0], "driverName", "connectionURL", "connectionName", "connectionPassword");
con = ConnectionCreator.getConnectionCryptPassword(args[0], } catch (Exception e) {
"driverName", "connectionURL", "connectionName", System.out.println("ERROR: Verbindung konnte nicht aufgebaut werden.\n" + e);
"connectionPassword"); System.exit(1);
} catch (Exception e) { }
System.out try {
.println("ERROR: Verbindung konnte nicht aufgebaut werden.\n" String sql = StringUtils.readFile(new File(args[2]));
+ e);
System.exit(1); Statement stm = con.createStatement();
} PreparedStatement pst = con.prepareStatement("update maskeninfo set select_stmt=? where tid=?");
try { pst.setString(1, sql);
String sql = StringUtils.readFile(new File(args[2])); pst.setInt(2, tid);
int rows = pst.executeUpdate();
Statement stm = con.createStatement();
PreparedStatement pst = con
.prepareStatement("update maskeninfo set select_stmt=? where tid=?"); if (rows == 0) throw new IllegalArgumentException("Wahrscheinlich gibt es keine Maske mit der tid " + tid);
pst.setString(1, sql); System.out.println("update erfolgreich auf " + con.getMetaData().getURL() + " um " + DateUtils.getNowString());
pst.setInt(2, tid); stm.close();
int rows=pst.executeUpdate(); con.close();
} catch (Exception e) {
System.out.println("ERROR:" + e);
if (rows==0) throw new IllegalArgumentException("Wahrscheinlich gibt es keine Maske mit der tid "+tid);
System.out.println("update erfolgreich auf "+con.getMetaData().getURL() +" um "+DateUtils.getNowString()); }
stm.close(); }
con.close(); }
} catch (Exception e) {
System.out.println("ERROR:"+e); //Created on 12.04.2005 at 11:14:26
}
}
}
//Created on 12.04.2005 at 11:14:26

1
src/de/superx/bin/PasswdUpdater.java

@ -13,6 +13,7 @@ import de.memtext.util.CryptUtils;
* @author superx * @author superx
* *
*/ */
@Deprecated
public class PasswdUpdater { public class PasswdUpdater {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
if (args.length != 1) { if (args.length != 1) {

37
src/de/superx/bin/Pgcheck.java

@ -10,25 +10,24 @@ public class Pgcheck {
* @param args * @param args
*/ */
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("INFO: argumente connectionURL username [passwd]"); System.out.println("INFO: argumente connectionURL username [passwd]");
if (args.length>=2) if (args.length >= 2) {
{ try {
try { System.out.println("Teste Verbindung ...");
System.out.println("Teste Verbindung ..."); Class.forName("org.postgresql.Driver");
Class.forName("org.postgresql.Driver"); String passwd = "dummy";
String passwd="dummy"; if (args.length > 2) passwd = args[2];
if (args.length>2) passwd=args[2]; Connection conn = DriverManager.getConnection(args[0], args[1], passwd);
Connection conn = DriverManager.getConnection(args[0],args[1], passwd); Statement st = conn.createStatement();
Statement st=conn.createStatement(); System.out.println("Verbindung erfolgreich");
System.out.println("Verbindung erfolgreich"); st.close();
st.close(); conn.close();
conn.close(); } catch (Exception e) {
} System.out.println(e);
catch (Exception e) }
{ }
System.out.println(e);
}}
}} }
}
//Created on 19.02.2009 at 11:34:00 //Created on 19.02.2009 at 11:34:00

1125
src/de/superx/bin/PropAdmin.java

File diff suppressed because it is too large Load Diff

550
src/de/superx/bin/PropAdminOld.java

@ -0,0 +1,550 @@
package de.superx.bin;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.LinkedList;
import java.util.Properties;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import de.memtext.util.CryptUtils;
import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
import de.memtext.widgets.LabeledComboBox;
import de.memtext.widgets.LabeledTextField;
import de.memtext.widgets.RadioButtonGroup;
import de.memtext.widgets.VerticalBox;
import de.memtext.widgets.WarningMessage;
import de.superx.util.ConnectionDialogCommon;
import de.superx.util.SqlStringUtils;
public class PropAdminOld extends JFrame implements ActionListener, ItemListener {
static Container cp;
static LinkedList logLevels = new LinkedList();
static JTextField tAdminPasswd, tdriver, turl, tadminUser, tRestrictedUser, tRestrictedPassword;
static LabeledTextField ltfMaskCache;
static LabeledTextField ltfUserCache;
static JComboBox tname;
static LabeledComboBox sqlLogLevel, xmlLogLevel;
static LabeledTextField maxActive;
static LabeledTextField minIdle;
static LabeledTextField maxIdle;
static RadioButtonGroup rbEntwicklungsmodus = new RadioButtonGroup();
static private String defaultDBDriver = "com.informix.jdbc.IfxDriver";
static private String defaultConnection = "jdbc:informix-sqli://<<hostname>>:<<Portnr>>:informixserver=<<informixserver>>;database=superx";
static private String defaultUser = "superx";
private static String dbpropfile = "db.properties";
static private String connTypes[][];
private static boolean isGuiWanted = true;
static Properties props = new Properties();
static byte key[] = { (byte) 255, (byte) 221, (byte) 127, (byte) 109, (byte) 129 };
static int keyLength = key.length;
private static String usage = "-------------------------------------\nGebrauch: java de.superx.bin.PropAdmin -dbproperties:<<Pfad zu den db-Properties>>(optional) \n---------------------------------------------------";
// private static String newAdminPassword;
public PropAdminOld() {
super("DB-Properties Admin @version@");
ltfMaskCache = new LabeledTextField("Masken, die im Cache sein sollen", "select tid from maskeninfo where 1=0", 50);
ltfUserCache = new LabeledTextField("User, die im Cache sein sollen", "select tid from userinfo where 1=0", 50);
maxActive = new LabeledTextField("maxActive", 3);
minIdle = new LabeledTextField("minIdle", 3);
maxIdle = new LabeledTextField("maxIdle", 3);
sqlLogLevel = new LabeledComboBox("Log Level SQL", logLevels);
xmlLogLevel = new LabeledComboBox("Log Level XML", logLevels);
sqlLogLevel.setSelectedIndex(1);
xmlLogLevel.setSelectedIndex(1);
rbEntwicklungsmodus.add(new JLabel("Entwicklungsmodus "));
rbEntwicklungsmodus.add("an");
rbEntwicklungsmodus.add("aus");
rbEntwicklungsmodus.setSelection("an");
JButton btnTestAdmin = new JButton("Verbindung testen");
btnTestAdmin.addActionListener(this);
cp = this.getContentPane();
cp.setLayout(new BorderLayout());
JPanel titel = new JPanel();
JLabel ltitel = new JLabel("DB-Properties Admin für " + dbpropfile);
ltitel.setFont(new Font("Courier", Font.BOLD, 14));
titel.add(ltitel);
cp.add(titel, "North");
VerticalBox center = new VerticalBox();
JPanel p0 = new JPanel(new FlowLayout(FlowLayout.LEFT));
tname = new JComboBox();
connTypes = ConnectionDialogCommon.getTypes();
for (int i = 0; i < connTypes.length; i++) {
tname.addItem(connTypes[i][0]);
}
// controls.add(types);
JLabel lname = new JLabel(" Driver :");
lname.setFont(new Font("Courier", Font.BOLD, 12));
// tname=new JTextField(30);
JLabel c_name = new JLabel("(mögliche Datenbanksysteme für SuperX)");
p0.add(lname);
p0.add(tname);
p0.add(c_name);
center.add(p0);
// JPanel center=new JPanel(new GridLayout(0,1));
JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
JLabel ldriver = new JLabel(" Driver Class:");
ldriver.setFont(new Font("Courier", Font.BOLD, 12));
tdriver = new JTextField(30);
JLabel c_driver = new JLabel("(muss im CLASSPATH stehen!)");
p1.add(ldriver);
p1.add(tdriver);
p1.add(c_driver);
center.add(p1);
JPanel p1b = new JPanel(new FlowLayout(FlowLayout.LEFT));
JLabel lurl = new JLabel(" Connection URL:");
lurl.setFont(new Font("Courier", Font.BOLD, 12));
turl = new JTextField(50);
p1b.add(lurl);
p1b.add(turl);
center.add(p1b);
JPanel p3 = new JPanel(new FlowLayout(FlowLayout.LEFT));
JLabel luser = new JLabel(" Username:");
luser.setFont(new Font("Courier", Font.BOLD, 12));
tadminUser = new JTextField(10);
JLabel lpasswd = new JLabel(" Password:");
lpasswd.setFont(new Font("Courier", Font.BOLD, 12));
tAdminPasswd = new JPasswordField(10);
p3.add(luser);
p3.add(tadminUser);
p3.add(lpasswd);
p3.add(tAdminPasswd);
p3.add(btnTestAdmin);
center.add(p3);
JPanel p3b = new JPanel(new FlowLayout(FlowLayout.LEFT));
JLabel lbl33 = new JLabel(" Eingeschränkter User:");
lbl33.setFont(new Font("Courier", Font.BOLD, 12));
p3b.add(lbl33);
tRestrictedUser = new JTextField(10);
p3b.add(tRestrictedUser);
tRestrictedPassword = new JPasswordField(10);
p3b.add(new JLabel("Passwort"));
p3b.add(tRestrictedPassword);
JButton btnTest2 = new JButton("Verb.testen");
btnTest2.addActionListener(this);
JButton btnSelectRights = new JButton("select-Rechte auf alle Tabellen");
btnSelectRights.addActionListener(this);
p3b.add(btnTest2);
p3b.add(btnSelectRights);
center.add(p3b);
center.add(sqlLogLevel);
center.add(xmlLogLevel);
center.addWithLeftAlignment(rbEntwicklungsmodus);
center.addWithLeftAlignment(new JLabel("<html>(Im Entwicklungsmodus werden alle SQL-Befehle von Abfragen einzeln an die Datenbank geschickt.<br>Das dauert etwas l&auml;nger, erm&ouml;glicht aber bessere Fehlermeldungen.)<br>"));
center.add(ltfMaskCache);
center.add(ltfUserCache);
JPanel p4 = new JPanel();
p4.add(new JLabel("<html>Der Apache ConnectionPool verwaltet die Anzahl benötigter Verbindungen dynamisch.<br>min/max idle gibt an wieviele Connections ständig bereit gehalten werden sollen.<br>maxActive gibt an wieviele Connections maximal gleichzeitig aktiv sein sollen."));
center.add(p4);
JPanel p5 = new JPanel();
p5.add(minIdle);
p5.add(maxIdle);
p5.add(maxActive);
center.add(p5);
cp.add(center, "Center");
JButton OK = new JButton("Speichern");
OK.addActionListener(this);
JPanel unten = new JPanel();
unten.add(OK);
cp.add(unten, "South");
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
tname.addItemListener(this);
this.pack();
}
private static void properties_einlesen() throws IOException {
if (!isGuiWanted) System.out.println("Lese ein: " + dbpropfile);
props = new Properties();
FileInputStream is = new FileInputStream(dbpropfile);
if (is != null) {
props.load(is);
is.close();
} else {
if (isGuiWanted) JOptionPane.showMessageDialog(null, "Kann Properties nicht einlesen.", "DB-Prop Admin", JOptionPane.INFORMATION_MESSAGE);
System.out.println("kann properties nicht einlesen");
}
// System.out.println(CryptUtils.decryptSimple(props.getProperty(
// "connectionPassword")));
}
private static void initFormFromProps() {
String tdriverclass = props.getProperty("driverName");
tdriver.setText(tdriverclass);
// if(props.getProperty( "connectionURL" ).equals(""))
// {
// Default-Url:
for (int i = 0; i < connTypes.length; i++) {
if (tdriverclass.equals(connTypes[i][1])) {
tname.setSelectedIndex(i);
}
}
if (props.getProperty("connectionURL") != null) turl.setText(props.getProperty("connectionURL"));
// }
tadminUser.setText(props.getProperty("connectionName"));
tRestrictedUser.setText(props.getProperty("restrictedConnectionName"));
if (props.getProperty("logLevelSQL") != null) sqlLogLevel.setSelectedItem(props.getProperty("logLevelSQL"));
if (props.getProperty("logLevelXML") != null) xmlLogLevel.setSelectedItem(props.getProperty("logLevelXML"));
if (props.getProperty("maskCache") != null) ltfMaskCache.setValue(props.getProperty("maskCache"));
if (props.getProperty("userCache") != null) ltfUserCache.setValue(props.getProperty("userCache"));
if (props.getProperty("minIdle") != null)
minIdle.setValue(props.getProperty("minIdle"));
else
minIdle.setValue("5");
if (props.getProperty("maxIdle") != null) maxIdle.setValue(props.getProperty("maxIdle"));
if (props.getProperty("maxActive") != null) maxActive.setValue(props.getProperty("maxActive"));
if (props.getProperty("developmentMode") == null || props.getProperty("developmentMode").equals("true"))
rbEntwicklungsmodus.setSelection("an");
else
rbEntwicklungsmodus.setSelection("aus");
}
@Override
public void actionPerformed(ActionEvent event) {
String cmd = event.getActionCommand();
if (cmd.equals("Speichern"))
{
try {
formValuesToProps();
saveProps();
System.exit(0);
} catch (Exception e) {
System.out.println("Es ist ein Fehler aufgetreten.");
e.printStackTrace();
WarningMessage.show(null, "Fehler: " + e, "SuperX");
}
}
if (cmd.equals("Verbindung testen")) {
try {
formValuesToProps();
boolean isOk = testConnection(props.getProperty("connectionName"), tAdminPasswd.getText());
} catch (Exception e) {
WarningMessage.show(null, "Fehler:" + e, "PropAdmin");
}
}
if (cmd.equals("Verb.testen")) {
try {
formValuesToProps();
testConnection(props.getProperty("restrictedConnectionName"), tRestrictedPassword.getText());
} catch (Exception e) {
WarningMessage.show(null, "Fehler:" + e, "PropAdmin");
}
}
if (cmd.equals("select-Rechte auf alle Tabellen")) {
try {
if (tRestrictedUser.getText() == null || tRestrictedUser.getText().trim().equals(""))
throw new IllegalArgumentException("Eingeschränkter user muss angegeben sein");
if (tadminUser.getText() == null || tadminUser.getText().trim().equals("")) throw new IllegalArgumentException("User muss angegeben sein");
if (tAdminPasswd.getText() == null || tAdminPasswd.getText().trim().equals("")) throw new IllegalArgumentException("Userpassword muss angegeben sein");
// int result=JOptionPane.showConfirmDialog(this,
// "Wollen Sie dem eingeschränktem User select-Rechte auf alle Tabellen geben?"
// ,"PropAdmin",JOptionPane.YES_NO_OPTION);
// if (result==JOptionPane.YES_OPTION)
grantSelectToRestrictedUser();
} catch (Exception e) {
WarningMessage.show(null, "Fehler:" + e, "PropAdmin");
}
}
}
private void grantSelectToRestrictedUser() throws Exception {
Class.forName(props.getProperty("driverName"));
Connection conn = DriverManager.getConnection(props.getProperty("connectionURL"), tadminUser.getText(), tAdminPasswd.getText());
Statement stm = conn.createStatement();
ResultSet rs = null;
if (props.getProperty("driverName").indexOf("postgres") > -1)
rs = conn.getMetaData().getTables(null, null, null, null);
else
rs = conn.getMetaData().getTables("superx", "superx", null, null);
while (rs.next()) {
System.out.println(rs.getObject(3).toString());
if (rs.getString(4) != null && (rs.getString(4).equals("TABLE") || rs.getString(4).equals("VIEW")))
stm.execute("grant select on " + rs.getObject(3).toString() + " to " + tRestrictedUser.getText() + ";");
}
rs.close();
stm.close();
conn.close();
}
private static boolean testConnection(String username, String password) {
boolean result = false;
try {
Class.forName(props.getProperty("driverName"));
if (props.getProperty("driverName").indexOf("postgres") > -1) {
props.put("charSet", SqlStringUtils.getEncoding().equals("xUTF-8") ? "UTF-8" : "Latin-1");
props.put("DateStyle", "German, DMY");
} else // Informix
{
props.put("GL_DATETIME", "%d.%m.%Y %T");
props.put("CLIENT_LOCALE", SqlStringUtils.getEncoding().equals("xUTF-8") ? "UTF-8" : "de_de.8859-1");
}
Connection conn = DriverManager.getConnection(props.getProperty("connectionURL"), username, password);
DatabaseMetaData dbmd = conn.getMetaData();
/*
* am 19.1.2006 auskommentiert, weil propadmin auch für DBen ausser
* superx genutzt wird. dq Statement stm=conn.createStatement(); if
* (props.getProperty("driverName").indexOf("postgres")>-1)
*
* stm.executeQuery("select date('1.1.2005');"); else
* stm.executeQuery("select 'xx' from xdummy");
*/
String msg = "Verbindung mit Datenbank " + conn.getCatalog() + " (" + dbmd.getDatabaseProductName() + " " + dbmd.getDatabaseProductVersion() + ") als " + username
+ " erfolgreich aufgebaut";
if (isGuiWanted)
JOptionPane.showMessageDialog(null, msg, "DB-Prop Admin", JOptionPane.INFORMATION_MESSAGE);
else
System.out.println(msg);
// stm.close();
conn.close();
result = true;
} catch (Exception e) {
String msg = "Ein Fehler ist aufgetreten.\n" + e.toString();
if (props.getProperty("driverName").indexOf("postgres") > -1 && e.toString().indexOf("Date Style") > -1) {
msg += "\nPrüfen Sie,ob Date Style auf dem Server auf German, DMY steht.";
}
if (isGuiWanted)
JOptionPane.showMessageDialog(null, msg, "DB-Prop Admin", JOptionPane.WARNING_MESSAGE);
else
System.out.println("Fehler: " + e.toString());
}
return result;
}
private static void formValuesToProps() throws Exception {
String driver = tdriver.getText();
String name = tadminUser.getText();
String passwd = tAdminPasswd.getText();
String url = turl.getText();
if (driver == null || name == null || passwd == null || url == null || driver.equals("") || name.equals("") || url.equals("")) {
if (isGuiWanted) JOptionPane.showMessageDialog(null, "Bitte alle Felder ausfüllen!", "DB-Prop Admin", JOptionPane.INFORMATION_MESSAGE);
return;
}
props.setProperty("connectionPassword", "sx_des" + CryptUtils.encryptStringDES(tAdminPasswd.getText()));
props.setProperty("connectionName", name);
props.setProperty("restrictedConnectionName", tRestrictedUser.getText());
if (tRestrictedPassword.getText() != null && tRestrictedPassword.getText().length() > 1)
props.setProperty("restrictedConnectionPassword", "sx_des" + CryptUtils.encryptStringDES(tRestrictedPassword.getText()));
props.setProperty("connectionURL", url);
props.setProperty("driverName", driver);
props.setProperty("minIdle", (String) minIdle.getValue());
props.setProperty("maxIdle", (String) maxIdle.getValue());
props.setProperty("maxActive", (String) maxActive.getValue());
props.setProperty("maskCache", (String) ltfMaskCache.getValue());
props.setProperty("userCache", (String) ltfUserCache.getValue());
props.setProperty("logLevelSQL", sqlLogLevel.getSelectedItem().toString());
props.setProperty("logLevelXML", xmlLogLevel.getSelectedItem().toString());
props.setProperty("developmentMode", rbEntwicklungsmodus.getSelectedName().equals("an") ? "true" : "false");
}
private static void saveProps() {
try {
props.remove("charSet");
props.remove("DateStyle");
props.remove("GL_DATETIME");
props.remove("CLIENT_LOCALE");
OutputStream os = new FileOutputStream(dbpropfile);
props.store(os, "SuperX DB.properties");
os.close();
System.out.println("Änderung gespeichert in " + dbpropfile);
} catch (IOException e) {
String fehler = "Konnte db.properties-Datei nicht speichern:" + e.toString();
if (isGuiWanted) JOptionPane.showMessageDialog(null, fehler, "DB-Prop Admin", JOptionPane.WARNING_MESSAGE);
System.out.println(e.toString());
System.exit(1);
}
}
public static void main(String args[]) {
logLevels.add("SEVERE");
logLevels.add("WARNING");
logLevels.add("INFO");
logLevels.add("FINE");
logLevels.add("FINER");
logLevels.add("FINEST");
System.out.println("Umgebungsvariable LANG: " + System.getProperty("file.encoding"));
GetOpts.setOpts(args);
PropAdminOld propAdmin = null;
if (GetOpts.isPresent(Options.opt_dbprops)) dbpropfile = GetOpts.getValue(Options.opt_dbprops);
if (GetOpts.isPresent(Options.opt_noguiVar0) || GetOpts.isPresent(Options.opt_noguiVar1) || GetOpts.isPresent(Options.opt_noguiVar2)) {
isGuiWanted = false;
} else {
try {
// wenn keine graphische Umgebung verfügbar ist
// tritt ein Fehler auf.
JFrame f = new JFrame();
} catch (Throwable e) {
System.out.println("Keine graphische Umgebung verfuegbar - starte Shell-Modus");
isGuiWanted = false;
}
if (isGuiWanted) propAdmin = new PropAdminOld();
}
try {
properties_einlesen();
if (isGuiWanted) {
initFormFromProps();
}
} catch (IOException e) {
String fehler = "Konnte db.properties-Datei nicht finden.\nEs wird eine neue in \n" + dbpropfile + " \nangelegt.";
if (isGuiWanted) {
JOptionPane.showMessageDialog(null, fehler, "DB-Prop Admin", JOptionPane.INFORMATION_MESSAGE);
System.out.println(fehler);
tdriver.setText(defaultDBDriver);
tadminUser.setText(defaultUser);
turl.setText(defaultConnection);
} else {
System.out.println("Sie koennen nur bestehende db.properties Dateien bearbeiten.");
System.out.println("Geben Sie den Parameter -dbproperties:/home/superx/../db.properties an");
System.out.println(e);
System.exit(1);
}
}
if (isGuiWanted) {
propAdmin.show();
} else {
noGuiEdit();
}
}
private static void noGuiEdit() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Die meisten Paramter koennen Sie mit dem vi bearbeiten.");
System.out.print("Passwort für uneingeschränkten User (erscheint auf Bildschirm!): ");
String newAdminPassword = br.readLine();
System.out.println();
// System.out.println("you entered: " + pass);
if (testConnection(props.getProperty("connectionName"), newAdminPassword)) {
System.out.print("Einen Moment - Verschlüsselung läuft ...");
props.setProperty("connectionPassword", "sx_des" + CryptUtils.encryptStringDES(newAdminPassword));
System.out.println(" OK");
saveProps();
}
if (props.getProperty("restrictedConnectionName") != null) {
System.out.print("Passwort für eingeschraenkten User (erscheint auf Bildschirm!): ");
String newPassword = br.readLine();
System.out.println();
if (testConnection(props.getProperty("restrictedConnectionName"), newPassword)) {
System.out.print("Einen Moment - Verschlüsselung läuft ...");
props.setProperty("restrictedConnectionPassword", "sx_des" + CryptUtils.encryptStringDES(newPassword));
System.out.println(" OK");
saveProps();
}
}
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void itemStateChanged(ItemEvent e) {
String s = (String) e.getItem();
for (int i = 0; i < connTypes.length; i++) {
if (s.equals(connTypes[i][0])) {
tdriver.setText(connTypes[i][1]);
// if(turl.getText().indexOf( ">>") < 0)
turl.setText(connTypes[i][2]);
}
}
}
}

445
src/de/superx/bin/Psql.java

@ -1,4 +1,5 @@
package de.superx.bin; package de.superx.bin;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -16,240 +17,212 @@ import java.sql.Statement;
* *
*/ */
public class Psql public class Psql {
{ Connection db; // The connection to the database
Connection db; // The connection to the database
Statement st; // Our statement to run queries with Statement st; // Our statement to run queries with
DatabaseMetaData dbmd; // This defines the structure of the database
boolean done = false; // Added by CWJ to permit \q command DatabaseMetaData dbmd; // This defines the structure of the database
String delim = "\t";
String header="false"; boolean done = false; // Added by CWJ to permit \q command
public Psql(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException String delim = "\t";
{
String header = "false";
if (args.length > 0)
{ public Psql(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException {
delim=args[0].trim();
if (args.length > 0) {
} delim = args[0].trim();
if (args.length > 0)
{ }
header=args[1].trim(); if (args.length > 0) {
header = args[1].trim();
}
SxConnection myConnection = new SxConnection(); }
try SxConnection myConnection = new SxConnection();
{ try {
Connection myDb=myConnection.getConnection(); Connection myDb = myConnection.getConnection();
st=myDb.createStatement(); st = myDb.createStatement();
dbmd = myDb.getMetaData(); dbmd = myDb.getMetaData();
st = myDb.createStatement(); st = myDb.createStatement();
} } catch (Exception e) {
catch (Exception e) System.err.println("Keine DB-Verbindung: " + e.toString());
{ }
System.err.println("Keine DB-Verbindung: "+e.toString());
} // This prints the backend's version
System.out.println("Connected to " + dbmd.getDatabaseProductName() + " " + dbmd.getDatabaseProductVersion());
// This prints the backend's version
System.out.println("Connected to " + dbmd.getDatabaseProductName() + " " + dbmd.getDatabaseProductVersion()); System.out.println();
System.out.println(); // This provides us the means of reading from stdin
StreamTokenizer input = new StreamTokenizer(new InputStreamReader(System.in));
// This provides us the means of reading from stdin input.resetSyntax();
StreamTokenizer input = new StreamTokenizer(new InputStreamReader(System.in)); input.slashSlashComments(true); // allow // as a comment delimiter
input.resetSyntax(); input.eolIsSignificant(false); // treat eol's as spaces
input.slashSlashComments(true); // allow // as a comment delimiter input.wordChars(32, 126);
input.eolIsSignificant(false); // treat eol's as spaces input.whitespaceChars(59, 59);
input.wordChars(32, 126); // input.quoteChar(39); *** CWJ: messes up literals in query string ***
input.whitespaceChars(59, 59);
// input.quoteChar(39); *** CWJ: messes up literals in query string *** // Now the main loop.
int tt = 0, lineno = 1;
// Now the main loop. while (tt != StreamTokenizer.TT_EOF && !done) {
int tt = 0, lineno = 1; System.out.print("[" + lineno + "] ");
while (tt != StreamTokenizer.TT_EOF && ! done) System.out.flush();
{
System.out.print("[" + lineno + "] "); // Here, we trap SQLException so they don't terminate the application
System.out.flush(); try {
if ((tt = input.nextToken()) == StreamTokenizer.TT_WORD) {
// Here, we trap SQLException so they don't terminate the application processLine(input.sval);
try lineno++;
{ }
if ((tt = input.nextToken()) == StreamTokenizer.TT_WORD) } catch (SQLException ex) {
{ System.out.println(ex.getMessage());
processLine(input.sval); }
lineno++; }
}
} System.out.println("Now closing the connection");
catch (SQLException ex) st.close();
{ db.close();
System.out.println(ex.getMessage()); }
}
} /*
* This processes a statement
System.out.println("Now closing the connection"); */
st.close(); public void processLine(String line) throws SQLException {
db.close(); if (line.startsWith("\\")) {
} processSlashCommand(line);
return;
/* }
* This processes a statement
*/ boolean type = st.execute(line);
public void processLine(String line) throws SQLException boolean loop = true;
{ while (loop) {
if (line.startsWith("\\")) if (type) {
{ // A ResultSet was returned
processSlashCommand(line); ResultSet rs = st.getResultSet();
return ; displayResult(rs);
} } else {
int count = st.getUpdateCount();
boolean type = st.execute(line);
boolean loop = true; if (count == -1) {
while (loop) // This indicates nothing left
{ loop = false;
if (type) } else {
{ // An update count was returned
// A ResultSet was returned System.out.println("Updated " + st.getUpdateCount() + " rows");
ResultSet rs = st.getResultSet(); }
displayResult(rs); }
}
else if (loop) type = st.getMoreResults();
{ }
int count = st.getUpdateCount(); }
if (count == -1) /*
{ * This displays a result set.
// This indicates nothing left * Note: it closes the result once complete.
loop = false; */
} public void displayResult(ResultSet rs) throws SQLException {
else ResultSetMetaData rsmd = rs.getMetaData();
{ int cols = rsmd.getColumnCount();
// An update count was returned // Print the result column names
System.out.println("Updated " + st.getUpdateCount() + " rows"); if (header.equals("true")) {
} for (int i = 1; i <= cols; i++)
} System.out.print(rsmd.getColumnLabel(i) + (i < cols ? delim : "\n"));
}
if (loop)
type = st.getMoreResults(); // now the results
} while (rs.next()) {
} for (int i = 1; i <= cols; i++) {
Object o = rs.getObject(i);
/* if (rs.wasNull())
* This displays a result set. System.out.print("{null}" + (i <= cols ? delim : "\n"));
* Note: it closes the result once complete. else
*/ System.out.print(o.toString() + (i <= cols ? delim : "\n"));
public void displayResult(ResultSet rs) throws SQLException }
{ }
ResultSetMetaData rsmd = rs.getMetaData();
int cols = rsmd.getColumnCount(); // finally close the result set
// Print the result column names rs.close();
if(header.equals("true")) }
{
for (int i = 1;i <= cols;i++) /*
System.out.print(rsmd.getColumnLabel(i) + (i < cols ? delim : "\n")); * This process / commands (for now just /d)
} */
public void processSlashCommand(String line) throws SQLException {
// now the results if (line.startsWith("\\d")) {
while (rs.next())
{ if (line.startsWith("\\d ")) {
for (int i = 1;i <= cols;i++) // Display details about a table
{ String table = line.substring(3);
Object o = rs.getObject(i); displayResult(dbmd.getColumns(null, null, table, "%"));
if (rs.wasNull()) } else {
System.out.print("{null}" + (i <= cols ? delim : "\n")); String types[] = null;
else if (line.equals("\\d"))
System.out.print(o.toString() + (i <= cols ? delim : "\n")); types = allUserTables;
} else if (line.equals("\\di"))
} types = usrIndices;
else if (line.equals("\\dt"))
// finally close the result set types = usrTables;
rs.close(); else if (line.equals("\\ds"))
} types = usrSequences;
else if (line.equals("\\dS"))
/* types = sysTables;
* This process / commands (for now just /d) else
*/ throw new SQLException("Unsupported \\d command: " + line);
public void processSlashCommand(String line) throws SQLException
{ // Display details about all system tables
if (line.startsWith("\\d")) //
{ // Note: the first two arguments are ignored. To keep to the spec,
// you must put null here
if (line.startsWith("\\d ")) //
{ displayResult(dbmd.getTables(null, null, "%", types));
// Display details about a table }
String table = line.substring(3); } else if (line.equals("\\q")) // Added by CWJ to permit \q command
displayResult(dbmd.getColumns(null, null, table, "%")); done = true;
} else
else throw new SQLException("Unsupported \\ command: " + line);
{ }
String types[] = null;
if (line.equals("\\d")) private static final String allUserTables[] = { "TABLE", "INDEX", "SEQUENCE" };
types = allUserTables;
else if (line.equals("\\di")) private static final String usrIndices[] = { "INDEX" };
types = usrIndices;
else if (line.equals("\\dt")) private static final String usrTables[] = { "TABLE" };
types = usrTables;
else if (line.equals("\\ds")) private static final String usrSequences[] = { "SEQUENCE" };
types = usrSequences;
else if (line.equals("\\dS")) private static final String sysTables[] = { "SYSTEM TABLE", "SYSTEM INDEX" };
types = sysTables;
else /*
throw new SQLException("Unsupported \\d command: " + line); * Display some instructions on how to run the example
*/
// Display details about all system tables public static void instructions() {
// System.out.println("\nThis example shows how some of the other JDBC features work within the\ndriver. It does this by implementing a very simple psql equivalent in java.\nNot everything that psql does is implemented.\n");
// Note: the first two arguments are ignored. To keep to the spec, System.out.println("Useage:\n java example.psql jdbc:postgresql:database user password [debug]\n\nThe debug field can be anything. It's presence will enable DriverManager's\ndebug trace. Unless you want to see screens of items, don't put anything in\nhere.");
// you must put null here System.exit(1);
// }
displayResult(dbmd.getTables(null, null, "%", types));
} /*
} * This little lot starts the test
else if (line.equals("\\q")) // Added by CWJ to permit \q command */
done = true; public static void main(String args[]) {
else System.out.println("PostgreSQL psql example v6.3 rev 1\n");
throw new SQLException("Unsupported \\ command: " + line);
} //if (args.length < 3)
// instructions();
private static final String allUserTables[] = {"TABLE", "INDEX", "SEQUENCE"};
private static final String usrIndices[] = {"INDEX"}; // This line outputs debug information to stderr. To enable this, simply
private static final String usrTables[] = {"TABLE"}; // add an extra parameter to the command line
private static final String usrSequences[] = {"SEQUENCE"}; //if (args.length > 3)
private static final String sysTables[] = {"SYSTEM TABLE", "SYSTEM INDEX"}; // DriverManager.setLogStream(System.err);
/* // Now run the tests
* Display some instructions on how to run the example try {
*/ Psql test = new Psql(args);
public static void instructions() } catch (Exception ex) {
{ System.err.println("Exception caught.\n" + ex);
System.out.println("\nThis example shows how some of the other JDBC features work within the\ndriver. It does this by implementing a very simple psql equivalent in java.\nNot everything that psql does is implemented.\n"); ex.printStackTrace();
System.out.println("Useage:\n java example.psql jdbc:postgresql:database user password [debug]\n\nThe debug field can be anything. It's presence will enable DriverManager's\ndebug trace. Unless you want to see screens of items, don't put anything in\nhere."); }
System.exit(1); }
}
/*
* This little lot starts the test
*/
public static void main(String args[])
{
System.out.println("PostgreSQL psql example v6.3 rev 1\n");
//if (args.length < 3)
// instructions();
// This line outputs debug information to stderr. To enable this, simply
// add an extra parameter to the command line
//if (args.length > 3)
// DriverManager.setLogStream(System.err);
// Now run the tests
try
{
Psql test = new Psql(args);
}
catch (Exception ex)
{
System.err.println("Exception caught.\n" + ex);
ex.printStackTrace();
}
}
} }

232
src/de/superx/bin/PublicPrivateKeyManager.java

@ -1,119 +1,113 @@
package de.superx.bin; package de.superx.bin;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.Statement; import java.sql.Statement;
import java.util.Hashtable; import java.util.Hashtable;
import de.memtext.util.DSAHandler; import de.memtext.util.DSAHandler;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
public class PublicPrivateKeyManager {
public class PublicPrivateKeyManager {
public static void main(String[] args) {
GetOpts.setOpts(args); public static void main(String[] args) {
String isdrin = GetOpts GetOpts.setOpts(args);
.isAllRequiredOptionsPresent("-dbproperties,-function"); String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[] {Options.opt_dbprops,Options.opt_function});
if (isdrin != null) { if (isdrin != null) {
System.err.println("Folgende Optionen fehlen: " + isdrin); System.err.println("Folgende Optionen fehlen: " + isdrin);
System.exit(1); System.exit(1);
} }
SxConnection sxcon = new SxConnection(); SxConnection sxcon = new SxConnection();
sxcon.setPropfile(GetOpts.getValue("-dbproperties")); sxcon.setPropfile(GetOpts.getValue(Options.opt_dbprops));
String function = GetOpts.getValue("-function"); String function = GetOpts.getValue(Options.opt_function);
try { try {
if (function.equals("install")) if (function.equals("install")) {
{ install(sxcon); install(sxcon);
check(sxcon); check(sxcon);
} }
if (function.equals("delete")) if (function.equals("delete")) {
{ delete(sxcon);
delete(sxcon); System.out.println("public/private key entfernt");
System.out.println("public/private key entfernt"); }
} if (function.equals("check")) {
if (function.equals("check")) System.out.println("Suche keys ...");
{ check(sxcon);
System.out.println("Suche keys ..."); }
check(sxcon); } catch (Exception e) {
} e.printStackTrace();
} catch (Exception e) { }
e.printStackTrace(); }
}
} private static void check(SxConnection sxcon) throws Exception {
Connection con = sxcon.getConnection();
private static void check(SxConnection sxcon) throws Exception Statement st = con.createStatement();
{ ResultSet rs = st.executeQuery("select count(*) from sx_repository where id='privatekey'");
Connection con = sxcon.getConnection(); int countprivate = 0;
Statement st=con.createStatement(); while (rs.next())
ResultSet rs=st.executeQuery("select count(*) from sx_repository where id='privatekey'"); countprivate = rs.getInt(1);
int countprivate=0; rs.close();
while (rs.next()) rs = st.executeQuery("select count(*) from sx_repository where id='publickey'");
countprivate=rs.getInt(1); int countpublic = 0;
rs.close(); while (rs.next())
rs=st.executeQuery("select count(*) from sx_repository where id='publickey'"); countpublic = rs.getInt(1);
int countpublic=0; rs.close();
while (rs.next()) st.close();
countpublic=rs.getInt(1); con.close();
rs.close(); if (countprivate == 0) System.out.println("private key nicht installiert");
st.close(); if (countprivate == 1) System.out.println("private key installiert");
con.close(); if (countprivate > 1) {
if (countprivate==0) System.out.println("private key nicht installiert"); System.out.println("mehr als ein private key gefunden - alle keys werden gelöscht");
if (countprivate==1) System.out.println("private key installiert"); delete(sxcon);
if (countprivate>1) }
{ if (countpublic == 0) System.out.println("public key nicht installiert");
System.out.println("mehr als ein private key gefunden - alle keys werden gelöscht"); if (countpublic == 1) System.out.println("public key installiert");
delete(sxcon); if (countpublic > 1) {
} System.out.println("mehr als ein public key gefunden - alle keys werden gelöscht");
if (countpublic==0) System.out.println("public key nicht installiert"); delete(sxcon);
if (countpublic==1) System.out.println("public key installiert"); }
if (countpublic>1)
{
System.out.println("mehr als ein public key gefunden - alle keys werden gelöscht"); }
delete(sxcon);
} private static void delete(SxConnection sxcon) throws Exception {
Connection con = sxcon.getConnection();
Statement st = con.createStatement();
} st.executeUpdate("delete from sx_repository where id in ('privatekey','publickey')");
private static void delete(SxConnection sxcon) throws Exception { st.close();
Connection con = sxcon.getConnection(); con.close();
Statement st = con.createStatement(); }
st
.executeUpdate("delete from sx_repository where id in ('privatekey','publickey')"); private static void install(SxConnection sxcon) throws Exception {
st.close(); delete(sxcon);
con.close(); Connection con = sxcon.getConnection();
} Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select max(tid) from sx_repository");
private static void install(SxConnection sxcon) throws Exception { int tid = 0;
delete(sxcon); while (rs.next())
Connection con = sxcon.getConnection(); tid = rs.getInt(1);
Statement st=con.createStatement(); rs.close();
ResultSet rs=st.executeQuery("select max(tid) from sx_repository"); Hashtable table = DSAHandler.generateKeyPair();
int tid=0; //PreparedStatement pst = con .prepareStatement("insert into testmb (tid,id,content,active) (?,?,2)");
while (rs.next()) //
tid=rs.getInt(1);
rs.close(); PreparedStatement pst = con.prepareStatement("insert into sx_repository (tid,id,content,aktiv) values (?,?,?,2)");
Hashtable table = DSAHandler.generateKeyPair(); pst.setInt(1, ++tid);
//PreparedStatement pst = con .prepareStatement("insert into testmb (tid,id,content,active) (?,?,2)"); pst.setString(2, "privatekey");
// pst.setString(3, table.get("privatekey").toString());
//System.out.println(pst.get);
PreparedStatement pst = con pst.execute();
.prepareStatement("insert into sx_repository (tid,id,content,aktiv) values (?,?,?,2)"); pst.setInt(1, ++tid);
pst.setInt(1, ++tid); pst.setString(2, "publickey");
pst.setString(2, "privatekey"); pst.setString(3, table.get("publickey").toString());
pst.setString(3, table.get("privatekey").toString()); pst.execute();
//System.out.println(pst.get); pst.close();
pst.execute(); con.close();
pst.setInt(1, ++tid);
pst.setString(2, "publickey"); }
pst.setString(3, table.get("publickey").toString()); }
pst.execute();
pst.close(); //Created on 21.10.2006 at 10:03:41
con.close();
}
}
//Created on 21.10.2006 at 10:03:41

248
src/de/superx/bin/RestrictedConnectionManager.java

@ -1,132 +1,116 @@
package de.superx.bin; package de.superx.bin;
import java.io.File; import java.io.File;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.Statement; import java.sql.Statement;
import java.util.Properties; import java.util.Properties;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.superx.util.PropsReader; import de.memtext.util.GetOpts.Options;
import de.superx.util.PropsReader;
public class RestrictedConnectionManager {
public class RestrictedConnectionManager {
public static void main(String[] args) {
GetOpts.setOpts(args); public static void main(String[] args) {
String isdrin = GetOpts GetOpts.setOpts(args);
.isAllRequiredOptionsPresent("-dbproperties,-kern_tabellen_freischalten"); String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[] {Options.opt_dbprops,Options.opt_kernTabellenFreischalten});
if (isdrin != null) { if (isdrin != null) {
System.err.println("Folgende Optionen fehlen: " + isdrin); System.err.println("Folgende Optionen fehlen: " + isdrin);
System.exit(1); System.exit(1);
} }
String kerninsert = GetOpts.getValue("-kern_tabellen_freischalten"); String kerninsert = GetOpts.getValue(Options.opt_kernTabellenFreischalten);
if (!kerninsert.equals("true") && !kerninsert.equals("false")) if (!kerninsert.equals("true") && !kerninsert.equals("false")) throw new IllegalArgumentException("-kern_tabellen_freischalten:true/false");
throw new IllegalArgumentException(
"-kern_tabellen_freischalten:true/false"); String dbpropfile = GetOpts.getValue(Options.opt_dbprops);
try {
String dbpropfile = GetOpts.getValue("-dbproperties"); Properties props = PropsReader.prepareProps(new File(dbpropfile));
try { String restrictedUser = props.getProperty("restrictedConnectionName");
Properties props = PropsReader.prepareProps(new File(dbpropfile)); if (restrictedUser == null || restrictedUser.trim().equals("")) {
String restrictedUser = props System.out.println("RestrictedRightsManager: Keine Aktion nötig, da kein eingeschränkter User gefunden in " + dbpropfile);
.getProperty("restrictedConnectionName"); } else {
if (restrictedUser == null || restrictedUser.trim().equals("")) { Class.forName(props.getProperty("driverName"));
System.out
.println("RestrictedRightsManager: Keine Aktion nötig, da kein eingeschränkter User gefunden in " Connection conn = DriverManager.getConnection(props.getProperty("connectionURL"), props.getProperty("connectionName"),
+ dbpropfile); PropsReader.check(props.getProperty("connectionPassword")));
} else { Statement stm = conn.createStatement();
Class.forName(props.getProperty("driverName")); StringBuffer grant = new StringBuffer("grant update on userinfo to " + restrictedUser + ";grant insert,update on protokoll to " + restrictedUser
+ ";grant insert,update,delete,select on user_pw to " + restrictedUser + ";");
Connection conn = DriverManager.getConnection(props if (props.getProperty("driverName").indexOf("postgres") > -1)
.getProperty("connectionURL"), props grant.append(";grant all on protokoll_protokoll_id_seq to " + restrictedUser + ";" + "grant all on sx_captions_tid_seq to " + restrictedUser + ";");
.getProperty("connectionName"), PropsReader.check(props
.getProperty("connectionPassword"))); if (kerninsert.equals("true")) {
Statement stm = conn.createStatement(); freischalten(grant, restrictedUser, "protokoll");
StringBuffer grant = new StringBuffer(
"grant update on userinfo to "+restrictedUser+";grant insert,update on protokoll to " + restrictedUser +
";grant insert,update,delete,select on user_pw to "+restrictedUser+";") ;
if (props.getProperty("driverName").indexOf("postgres")>-1)
grant.append(";grant all on protokoll_protokoll_id_seq to "+restrictedUser+";"+
"grant all on sx_captions_tid_seq to "+restrictedUser+";"); freischalten(grant, restrictedUser, "user_pw");
if (kerninsert.equals("true")) { freischalten(grant, restrictedUser, "group_field_pref");
freischalten(grant, restrictedUser, "protokoll"); freischalten(grant, restrictedUser, "sx_captions");
freischalten(grant, restrictedUser, "sx_stylesheets");
freischalten(grant, restrictedUser, "sx_mask_style");
freischalten(grant, restrictedUser, "userinfo");
freischalten(grant, restrictedUser, "groupinfo");
freischalten(grant, restrictedUser, "user_institution");
freischalten(grant, restrictedUser, "user_pw"); freischalten(grant, restrictedUser, "user_sachgeb_bez");
freischalten(grant, restrictedUser, "user_masken_bez");
freischalten(grant, restrictedUser, "group_field_pref"); freischalten(grant, restrictedUser, "group_sachgeb_bez");
freischalten(grant, restrictedUser, "sx_captions"); freischalten(grant, restrictedUser, "group_masken_bez");
freischalten(grant, restrictedUser, "sx_stylesheets"); freischalten(grant, restrictedUser, "user_group_bez");
freischalten(grant, restrictedUser, "sx_mask_style"); freischalten(grant, restrictedUser, "user_sichten");
freischalten(grant, restrictedUser, "userinfo"); freischalten(grant, restrictedUser, "user_sichtarten");
freischalten(grant, restrictedUser, "groupinfo"); freischalten(grant, restrictedUser, "group_sichten");
freischalten(grant, restrictedUser, "user_institution"); freischalten(grant, restrictedUser, "group_sichtarten");
freischalten(grant, restrictedUser, "user_sachgeb_bez"); freischalten(grant, restrictedUser, "felderinfo");
freischalten(grant, restrictedUser, "user_masken_bez"); freischalten(grant, restrictedUser, "maskeninfo");
freischalten(grant, restrictedUser, "group_sachgeb_bez"); freischalten(grant, restrictedUser, "konstanten");
freischalten(grant, restrictedUser, "group_masken_bez"); freischalten(grant, restrictedUser, "maske_system_bez");
freischalten(grant, restrictedUser, "user_group_bez"); freischalten(grant, restrictedUser, "masken_felder_bez");
freischalten(grant, restrictedUser, "user_sichten"); freischalten(grant, restrictedUser, "sachgeb_maske_bez");
freischalten(grant, restrictedUser, "user_sichtarten"); freischalten(grant, restrictedUser, "organigramm");
freischalten(grant, restrictedUser, "group_sichten"); freischalten(grant, restrictedUser, "themenbaum");
freischalten(grant, restrictedUser, "group_sichtarten"); freischalten(grant, restrictedUser, "sx_downloads");
freischalten(grant, restrictedUser, "felderinfo"); freischalten(grant, restrictedUser, "download_group_bez");
freischalten(grant, restrictedUser, "maskeninfo"); freischalten(grant, restrictedUser, "download_keyw_bez");
freischalten(grant, restrictedUser, "konstanten"); freischalten(grant, restrictedUser, "download_user_bez");
freischalten(grant, restrictedUser, "maske_system_bez"); freischalten(grant, restrictedUser, "group_hinweis");
freischalten(grant, restrictedUser, "masken_felder_bez"); freischalten(grant, restrictedUser, "user_hinweis");
freischalten(grant, restrictedUser, "sachgeb_maske_bez"); freischalten(grant, restrictedUser, "user_einstellungen");
freischalten(grant, restrictedUser, "organigramm"); freischalten(grant, restrictedUser, "user_dialog");
freischalten(grant, restrictedUser, "themenbaum"); }
freischalten(grant, restrictedUser, "sx_downloads"); stm.execute(grant.toString());
freischalten(grant, restrictedUser, "download_group_bez"); String upd = null;
freischalten(grant, restrictedUser, "download_keyw_bez");
freischalten(grant, restrictedUser, "download_user_bez"); ResultSet rs = null;
freischalten(grant, restrictedUser, "group_hinweis"); if (props.getProperty("driverName").indexOf("postgres") > -1)
freischalten(grant, restrictedUser, "user_hinweis"); rs = conn.getMetaData().getTables(null, null, null, null);
freischalten(grant, restrictedUser, "user_einstellungen"); else
freischalten(grant, restrictedUser, "user_dialog"); rs = conn.getMetaData().getTables("superx", "superx", null, null);
}
stm.execute(grant.toString()); while (rs.next()) {
String upd = null; upd = "grant select on " + rs.getObject(3).toString() + " to " + restrictedUser + ";";
//System.out.println(upd);
ResultSet rs = null; if (rs.getString(4) != null && (rs.getString(4).equals("TABLE") || rs.getString(4).equals("VIEW"))) stm.execute(upd);
if (props.getProperty("driverName").indexOf("postgres") > -1) }
rs = conn.getMetaData().getTables(null, null, null, null); rs.close();
else stm.close();
rs = conn.getMetaData().getTables("superx", "superx", null, conn.close();
null); System.out.println(" RestrictedRightsManager fertig");
}
while (rs.next()) { } catch (Exception e) {
upd = "grant select on " + rs.getObject(3).toString() System.out.println("Es ist ein Fehler aufgetreten:");
+ " to " + restrictedUser + ";"; e.printStackTrace();
//System.out.println(upd); }
if (rs.getString(4) != null }
&& (rs.getString(4).equals("TABLE") || rs
.getString(4).equals("VIEW"))) private static void freischalten(StringBuffer grant, String user, String table) {
stm.execute(upd); grant.append("grant select,insert, update, delete on " + table + " to " + user + ";");
} }
rs.close(); }
stm.close();
conn.close(); //Created on 03.11.2006 at 15:44:10
System.out.println(" RestrictedRightsManager fertig");
}
} catch (Exception e) {
System.out.println("Es ist ein Fehler aufgetreten:");
e.printStackTrace();
}
}
private static void freischalten(StringBuffer grant, String user,
String table) {
grant.append("grant select,insert, update, delete on " + table + " to " + user
+ ";");
}
}
//Created on 03.11.2006 at 15:44:10

418
src/de/superx/bin/SendMail.java

@ -7,17 +7,17 @@ import java.io.IOException;
import java.util.Date; import java.util.Date;
import java.util.Properties; import java.util.Properties;
import javax.activation.DataHandler; import jakarta.activation.DataHandler;
import javax.activation.FileDataSource; import jakarta.activation.FileDataSource;
import javax.mail.Message; import jakarta.mail.Message;
import javax.mail.Multipart; import jakarta.mail.Multipart;
import javax.mail.PasswordAuthentication; import jakarta.mail.PasswordAuthentication;
import javax.mail.Session; import jakarta.mail.Session;
import javax.mail.Transport; import jakarta.mail.Transport;
import javax.mail.internet.InternetAddress; import jakarta.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart; import jakarta.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage; import jakarta.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart; import jakarta.mail.internet.MimeMultipart;
import com.martiansoftware.jsap.FlaggedOption; import com.martiansoftware.jsap.FlaggedOption;
import com.martiansoftware.jsap.JSAP; import com.martiansoftware.jsap.JSAP;
@ -27,213 +27,193 @@ import com.martiansoftware.jsap.Switch;
//TODO flag ssl aktivieren //TODO flag ssl aktivieren
public class SendMail { public class SendMail {
private static final String port = "25"; private static final String port = "25";
private String to, from, smtphost, username, password, subject, msg,
msgfile, attach; private String to, from, smtphost, username, password, subject, msg, msgfile, attach;
private boolean sslWanted = false;
private boolean sslWanted = false;
public void send(String[] args) {
public void send(String[] args) {
readArgs(args);
Session session = getSession(); readArgs(args);
Session session = getSession();
try {
// create a message try {
MimeMessage message = new MimeMessage(session); // create a message
message.setFrom(new InternetAddress(from)); MimeMessage message = new MimeMessage(session);
InternetAddress[] address = { new InternetAddress(to) }; message.setFrom(new InternetAddress(from));
message.setRecipients(Message.RecipientType.TO, address); InternetAddress[] address = { new InternetAddress(to) };
message.setSubject(subject); message.setRecipients(Message.RecipientType.TO, address);
String content = getContent(); message.setSubject(subject);
String content = getContent();
// attach the file to the message
if (attach != null) { // attach the file to the message
// create and fill the first message part if (attach != null) {
MimeBodyPart mbp1 = new MimeBodyPart(); // create and fill the first message part
mbp1.setText(content); MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setText(content);
// create the second message part
MimeBodyPart mbp2 = new MimeBodyPart(); // create the second message part
MimeBodyPart mbp2 = new MimeBodyPart();
FileDataSource fds = new FileDataSource(attach);
mbp2.setDataHandler(new DataHandler(fds)); FileDataSource fds = new FileDataSource(attach);
mbp2.setFileName(fds.getName()); mbp2.setDataHandler(new DataHandler(fds));
// create the Multipart and add its parts to it mbp2.setFileName(fds.getName());
Multipart mp = new MimeMultipart(); // create the Multipart and add its parts to it
mp.addBodyPart(mbp1); Multipart mp = new MimeMultipart();
mp.addBodyPart(mbp2); mp.addBodyPart(mbp1);
mp.addBodyPart(mbp2);
// add the Multipart to the message
message.setContent(mp); // add the Multipart to the message
message.setContent(mp);
} else {
message.setContent(content, "text/html"); } else {
} message.setContent(content, "text/html");
}
// set the Date: header
message.setSentDate(new Date()); // set the Date: header
message.setSentDate(new Date());
// Transport transport = session.getTransport("smtp");
// transport.connect(smtphost, port, username, password); // Transport transport = session.getTransport("smtp");
// transport.connect(smtphost, port, username, password);
Transport.send(message);
System.out.println("Email verschickt"); Transport.send(message);
System.out.println("Email verschickt");
} catch (Exception mex) {
mex.printStackTrace(); } catch (Exception mex) {
System.out.println("Es ist ein Fehler aufgetreten: " + mex); mex.printStackTrace();
System.exit(-1); System.out.println("Es ist ein Fehler aufgetreten: " + mex);
} System.exit(-1);
}
}
}
private String getContent() throws IOException {
String content = msg; private String getContent() throws IOException {
if (msgfile != null) String content = msg;
content = readFile(new File(msgfile)); if (msgfile != null) content = readFile(new File(msgfile));
return content; return content;
} }
private void readArgs(String[] args) { private void readArgs(String[] args) {
JSAP jsap = new JSAP(); JSAP jsap = new JSAP();
FlaggedOption fto = new FlaggedOption("to") FlaggedOption fto = new FlaggedOption("to").setStringParser(JSAP.STRING_PARSER).setRequired(true).setLongFlag("to");
.setStringParser(JSAP.STRING_PARSER).setRequired(true) FlaggedOption ffrom = new FlaggedOption("from").setStringParser(JSAP.STRING_PARSER).setRequired(true).setLongFlag("from");
.setLongFlag("to"); FlaggedOption fhost = new FlaggedOption("host").setStringParser(JSAP.STRING_PARSER).setRequired(true).setLongFlag("host");
FlaggedOption ffrom = new FlaggedOption("from")
.setStringParser(JSAP.STRING_PARSER).setRequired(true) FlaggedOption fusername = new FlaggedOption("username").setStringParser(JSAP.STRING_PARSER).setRequired(true).setLongFlag("username");
.setLongFlag("from");
FlaggedOption fhost = new FlaggedOption("host") FlaggedOption fpassword = new FlaggedOption("password").setStringParser(JSAP.STRING_PARSER).setRequired(true).setLongFlag("password");
.setStringParser(JSAP.STRING_PARSER).setRequired(true) FlaggedOption fsubject = new FlaggedOption("subject").setStringParser(JSAP.STRING_PARSER).setRequired(true).setLongFlag("subject");
.setLongFlag("host"); FlaggedOption fmsg = new FlaggedOption("msg").setStringParser(JSAP.STRING_PARSER).setRequired(false).setLongFlag("msg");
FlaggedOption fmsgfile = new FlaggedOption("msgfile").setStringParser(JSAP.STRING_PARSER).setRequired(false).setLongFlag("msgfile");
FlaggedOption fusername = new FlaggedOption("username") FlaggedOption fattach = new FlaggedOption("attach").setStringParser(JSAP.STRING_PARSER).setRequired(false).setLongFlag("attach");
.setStringParser(JSAP.STRING_PARSER).setRequired(true) Switch sw1 = new Switch("ssl").setLongFlag("ssl");
.setLongFlag("username");
sw1.setHelp("ssl aktivieren");
FlaggedOption fpassword = new FlaggedOption("password")
.setStringParser(JSAP.STRING_PARSER).setRequired(true) JSAPResult config = null;
.setLongFlag("password"); try {
FlaggedOption fsubject = new FlaggedOption("subject") jsap.registerParameter(fto);
.setStringParser(JSAP.STRING_PARSER).setRequired(true) jsap.registerParameter(ffrom);
.setLongFlag("subject"); jsap.registerParameter(fhost);
FlaggedOption fmsg = new FlaggedOption("msg") jsap.registerParameter(sw1);
.setStringParser(JSAP.STRING_PARSER).setRequired(false) jsap.registerParameter(fusername);
.setLongFlag("msg"); jsap.registerParameter(fpassword);
FlaggedOption fmsgfile = new FlaggedOption("msgfile") jsap.registerParameter(fsubject);
.setStringParser(JSAP.STRING_PARSER).setRequired(false) jsap.registerParameter(fmsg);
.setLongFlag("msgfile"); jsap.registerParameter(fmsgfile);
FlaggedOption fattach = new FlaggedOption("attach") jsap.registerParameter(fattach);
.setStringParser(JSAP.STRING_PARSER).setRequired(false) config = jsap.parse(args);
.setLongFlag("attach"); if (!config.success()) {
Switch sw1 = new Switch("ssl").setLongFlag("ssl"); for (java.util.Iterator errs = config.getErrorMessageIterator(); errs.hasNext();) {
System.out.println("Error: " + errs.next());
sw1.setHelp("ssl aktivieren");
}
JSAPResult config = null; printUsage();
try { }
jsap.registerParameter(fto);
jsap.registerParameter(ffrom); to = config.getString("to");
jsap.registerParameter(fhost); from = config.getString("from");
jsap.registerParameter(sw1); smtphost = config.getString("host");
jsap.registerParameter(fusername); sslWanted = config.getBoolean("ssl");
jsap.registerParameter(fpassword); subject = config.getString("subject");
jsap.registerParameter(fsubject); username = config.getString("username");
jsap.registerParameter(fmsg); password = config.getString("password");
jsap.registerParameter(fmsgfile); msg = config.getString("msg");
jsap.registerParameter(fattach); msgfile = config.getString("msgfile");
config = jsap.parse(args); attach = config.getString("attach");
if (!config.success()) { // System.out.println(smtphost + " " + username + " " + password);
for (java.util.Iterator errs = config.getErrorMessageIterator(); errs } catch (JSAPException e) {
.hasNext();) {
System.out.println("Error: " + errs.next()); System.out.println("Fehler: " + e);
printUsage();
}
printUsage(); }
} }
to = config.getString("to"); private Session getSession() {
from = config.getString("from"); Authenticator authenticator = new Authenticator();
smtphost = config.getString("host");
sslWanted = config.getBoolean("ssl"); Properties properties = new Properties();
subject = config.getString("subject"); properties.setProperty("mail.smtp.submitter", authenticator.getPasswordAuthentication().getUserName());
username = config.getString("username"); properties.setProperty("mail.smtp.auth", "true");
password = config.getString("password"); if (sslWanted) {
msg = config.getString("msg"); properties.put("mail.smtp.starttls.enable", "true");
msgfile = config.getString("msgfile"); System.out.println("SSL aktiviert");
attach = config.getString("attach"); }
// System.out.println(smtphost + " " + username + " " + password); properties.setProperty("mail.smtp.host", this.smtphost);
} catch (JSAPException e) { properties.setProperty("mail.smtp.port", port);
System.out.println("Fehler: " + e); return Session.getInstance(properties, authenticator);
printUsage(); }
} private static void printUsage() {
} System.out.println("usage: java de.superx.bin.SendMail --to test@test.de --from system@super-ics.de --host smtp.strato.de --ssl (optional) --username system --password geheim --subject \"Ihre Dokumente\" "
+ " --msg \"Hier erhalten Sie Ihre Protokolle\" (optional) --msgfile c:\\nachricht.txt (optional) --attach c:\\protokoll.xls (optinal)");
private Session getSession() { System.exit(1);
Authenticator authenticator = new Authenticator(); }
Properties properties = new Properties(); /**
properties.setProperty("mail.smtp.submitter", authenticator * Copy of de.memtext.util.StringUtils.readFile Reads the contents of a file
.getPasswordAuthentication().getUserName()); * and returns them as a string
properties.setProperty("mail.smtp.auth", "true"); *
if (sslWanted) { * @param filename
properties.put("mail.smtp.starttls.enable", "true"); * @return String with content of files
System.out.println("SSL aktiviert"); * @throws IOException
} */
properties.setProperty("mail.smtp.host", this.smtphost); public static String readFile(File f) throws IOException {
properties.setProperty("mail.smtp.port", port); FileReader fr = new FileReader(f);
BufferedReader bfr = new BufferedReader(fr);
return Session.getInstance(properties, authenticator); String line;
} StringBuffer result = new StringBuffer();
while ((line = bfr.readLine()) != null) {
private static void printUsage() { result.append(line + "\n");
System.out
.println("usage: java de.superx.bin.SendMail --to test@test.de --from system@super-ics.de --host smtp.strato.de --ssl (optional) --username system --password geheim --subject \"Ihre Dokumente\" " }
+ " --msg \"Hier erhalten Sie Ihre Protokolle\" (optional) --msgfile c:\\nachricht.txt (optional) --attach c:\\protokoll.xls (optinal)"); bfr.close();
System.exit(1); fr.close();
} return result.toString();
}
/**
* Copy of de.memtext.util.StringUtils.readFile Reads the contents of a file public static void main(String[] args) {
* and returns them as a string SendMail sm = new SendMail();
* sm.send(args);
* @param filename }
* @return String with content of files
* @throws IOException private class Authenticator extends jakarta.mail.Authenticator {
*/ private PasswordAuthentication authentication;
public static String readFile(File f) throws IOException {
FileReader fr = new FileReader(f); public Authenticator() {
BufferedReader bfr = new BufferedReader(fr); // String username = "auth-user";
String line; // String password = "auth-password";
StringBuffer result = new StringBuffer(); authentication = new PasswordAuthentication(username, password);
while ((line = bfr.readLine()) != null) { }
result.append(line + "\n");
@Override
} protected PasswordAuthentication getPasswordAuthentication() {
bfr.close(); return authentication;
fr.close(); }
return result.toString(); }
}
public static void main(String[] args) {
SendMail sm = new SendMail();
sm.send(args);
}
private class Authenticator extends javax.mail.Authenticator {
private PasswordAuthentication authentication;
public Authenticator() {
// String username = "auth-user";
// String password = "auth-password";
authentication = new PasswordAuthentication(username, password);
}
protected PasswordAuthentication getPasswordAuthentication() {
return authentication;
}
}
} }

25
src/de/superx/bin/ShowEnv.java

@ -5,6 +5,7 @@
* Window>Preferences>Java>Code Generation>Code and Comments * Window>Preferences>Java>Code Generation>Code and Comments
*/ */
package de.superx.bin; package de.superx.bin;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Properties; import java.util.Properties;
@ -20,17 +21,15 @@ import java.util.Properties;
*/ */
public class ShowEnv { public class ShowEnv {
public static void main(String[] args) { public static void main(String[] args) {
Properties sysprops = System.getProperties(); Properties sysprops = System.getProperties();
Enumeration propnames = sysprops.propertyNames(); Enumeration propnames = sysprops.propertyNames();
System.out.println("SuperX @version@\n"); System.out.println("SuperX @version@\n");
while (propnames.hasMoreElements()) { while (propnames.hasMoreElements()) {
String propname = (String)propnames.nextElement(); String propname = (String) propnames.nextElement();
System.out.println( System.out.println(propname + "=" + System.getProperty(propname));
propname + "=" + System.getProperty(propname) }
); }
}
}
} }

148
src/de/superx/bin/SimpleSoapClient.java

@ -1,4 +1,5 @@
package de.superx.bin; package de.superx.bin;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@ -23,85 +24,72 @@ import javax.xml.transform.stream.StreamResult;
public class SimpleSoapClient { public class SimpleSoapClient {
public static void main(String args[]) { public static void main(String args[]) {
if (args.length != 3) { if (args.length != 3) {
System.out System.out.println("Usage path/to/envelope.xml URL /path/to/ouputfile.xml");
.println("Usage path/to/envelope.xml URL /path/to/ouputfile.xml"); System.exit(-1);
System.exit(-1); }
} try {
try { // Create SOAP Connection
// Create SOAP Connection SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory SOAPConnection soapConnection = soapConnectionFactory.createConnection();
.newInstance();
SOAPConnection soapConnection = soapConnectionFactory // Send SOAP Message to SOAP Server
.createConnection(); String url = args[1];
// Send SOAP Message to SOAP Server SOAPMessage sr = getSoapMessageFromString(readFile(new File(args[0])));
String url = args[1]; sr.getMimeHeaders().addHeader("SOAPAction", "http://sap.com/xi/WebService/soap1.1");
SOAPMessage sr = getSoapMessageFromString(readFile(new File(args[0]))); SOAPMessage soapResponse = soapConnection.call(sr, url);
sr.getMimeHeaders().addHeader("SOAPAction",
"http://sap.com/xi/WebService/soap1.1"); soapResponse.writeTo(System.out);
final StringWriter sw = new StringWriter();
SOAPMessage soapResponse = soapConnection.call(sr, url);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
soapResponse.writeTo(System.out); // optional indenting
final StringWriter sw = new StringWriter(); transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
Transformer transformer = TransformerFactory.newInstance()
.newTransformer(); transformer.transform(new DOMSource(soapResponse.getSOAPPart()), new StreamResult(sw));
// optional indenting
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); writeFile(args, sw);
transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "2"); soapConnection.close();
} catch (Exception e) {
transformer.transform(new DOMSource(soapResponse.getSOAPPart()), e.printStackTrace();
new StreamResult(sw)); }
}
writeFile(args, sw);
private static void writeFile(String[] args, final StringWriter sw) throws IOException {
soapConnection.close(); FileWriter fw = new FileWriter(args[2]);
} catch (Exception e) { BufferedWriter bfw = new BufferedWriter(fw);
e.printStackTrace(); bfw.write(sw.toString());
} bfw.close();
} fw.close();
}
private static void writeFile(String[] args, final StringWriter sw)
throws IOException { //
FileWriter fw = new FileWriter(args[2]); // I did this in two steps. First created a DOM Document, and then create
BufferedWriter bfw = new BufferedWriter(fw); // the SOAPMessage from the Document.
bfw.write(sw.toString()); private static SOAPMessage getSoapMessageFromString(String xml) throws SOAPException, IOException {
bfw.close(); MessageFactory factory = MessageFactory.newInstance();
fw.close(); SOAPMessage message = factory.createMessage(new MimeHeaders(), new ByteArrayInputStream(xml.getBytes(Charset.forName("UTF-8"))));
} return message;
}
//
// I did this in two steps. First created a DOM Document, and then create private static String readFile(File f) throws IOException {
// the SOAPMessage from the Document. FileReader fr = new FileReader(f);
private static SOAPMessage getSoapMessageFromString(String xml) BufferedReader bfr = new BufferedReader(fr);
throws SOAPException, IOException { String line;
MessageFactory factory = MessageFactory.newInstance(); StringBuffer result = new StringBuffer();
SOAPMessage message = factory while ((line = bfr.readLine()) != null) {
.createMessage( result.append(line + "\n");
new MimeHeaders(),
new ByteArrayInputStream(xml.getBytes(Charset }
.forName("UTF-8")))); bfr.close();
return message; fr.close();
} return result.toString();
}
private static String readFile(File f) throws IOException {
FileReader fr = new FileReader(f);
BufferedReader bfr = new BufferedReader(fr);
String line;
StringBuffer result = new StringBuffer();
while ((line = bfr.readLine()) != null) {
result.append(line + "\n");
}
bfr.close();
fr.close();
return result.toString();
}
} }

234
src/de/superx/bin/SimpleTransform.java

@ -1,123 +1,111 @@
package de.superx.bin; package de.superx.bin;
/* /*
* *
* Simple Transformation of an XML Source via xsl File * Simple Transformation of an XML Source via xsl File
*/ */
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.util.logging.LogManager; import java.util.logging.LogManager;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.TimeUtils; import de.memtext.util.GetOpts.Options;
import de.memtext.util.TimeUtils;
/**
* Use the TraX interface to perform a transformation in the simplest manner possible /**
* (3 statements). * Use the TraX interface to perform a transformation in the simplest manner possible
*/ * (3 statements).
public class SimpleTransform { */
private static String usage = public class SimpleTransform {
"-------------------------------------\nGebrauch: java de.superx.SimpleTransform -logger=<<Pfad zu logging.properties>> -IN=<<xml-Datei>> -XSL=<<xsl-Datei>> -method=<<xml |html|text>>(optional) -param=<<Parameter>>(optional) -OUT=<<Ausgabedatei>>(optional) \n---------------------------------------------------"; private static String usage = "-------------------------------------\nGebrauch: java de.superx.SimpleTransform -logger=<<Pfad zu logging.properties>> -IN=<<xml-Datei>> -XSL=<<xsl-Datei>> -method=<<xml |html|text>>(optional) -param=<<Parameter>>(optional) -OUT=<<Ausgabedatei>>(optional) \n---------------------------------------------------";
static Logger logger =
(Logger) Logger.getLogger(SimpleTransform.class.toString()); static Logger logger = (Logger) Logger.getLogger(SimpleTransform.class.toString());
private static String _out = ""; private static String _out = "";
public static void transform(String args[])
throws public static void transform(String args[])
TransformerException, throws TransformerException, TransformerConfigurationException, FileNotFoundException, IOException, ClassNotFoundException, FileNotFoundException, IOException {
TransformerConfigurationException,
FileNotFoundException, String _xml = "";
IOException, String _xsl = "";
ClassNotFoundException,
FileNotFoundException, String method = "text";
IOException { String _params = "";
String logfile = "";
String _xml = ""; GetOpts.setOpts(args);
String _xsl = ""; String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[] {Options.opt_logger,Options.opt_in,Options.opt_xsl});
if (isdrin != null) {
String method = "text"; System.err.println("Folgende Optionen fehlen: " + isdrin);
String _params = ""; System.err.println(usage);
String logfile = ""; System.exit(1);
GetOpts.setOpts(args); }
String isdrin = GetOpts.isAllRequiredOptionsPresent("-logger,-IN,-XSL");
if (isdrin != null) { //GetOpts myOpts=new GetOpts();
System.err.println("Folgende Optionen fehlen: " + isdrin); if (GetOpts.isPresent(Options.opt_logger)) logfile = GetOpts.getValue(Options.opt_logger);
System.err.println(usage); if (GetOpts.isPresent(Options.opt_in)) _xml = GetOpts.getValue(Options.opt_in);
System.exit(1); if (GetOpts.isPresent(Options.opt_xsl)) _xsl = GetOpts.getValue(Options.opt_xsl);
} if (GetOpts.isPresent(Options.opt_out)) _out = GetOpts.getValue(Options.opt_out);
if (GetOpts.isPresent(Options.opt_method)) method = GetOpts.getValue(Options.opt_method);
//GetOpts myOpts=new GetOpts(); if (GetOpts.isPresent(Options.opt_params)) _params = GetOpts.getValue(Options.opt_params);
if (GetOpts.isPresent("-logger"))
logfile = GetOpts.getValue("-logger"); //logger.initRaw(dosql.class)
if (GetOpts.isPresent("-IN")) //PropertyConfigurator.configure(logfile);
_xml = GetOpts.getValue("-IN"); File f = new File(logfile);
if (GetOpts.isPresent("-XSL")) if (!f.exists()) {
_xsl = GetOpts.getValue("-XSL"); throw new IOException("Datei nicht gefunden: " + logfile);
if (GetOpts.isPresent("-OUT")) }
_out = GetOpts.getValue("-OUT"); FileInputStream ins = new FileInputStream(logfile);
if (GetOpts.isPresent("-method")) LogManager MyLogManager = java.util.logging.LogManager.getLogManager();
method = GetOpts.getValue("-method"); MyLogManager.readConfiguration(ins);
if (GetOpts.isPresent("-params")) //logfile = MyLogManager.getProperty(".level");
_params = GetOpts.getValue("-params"); logger.info("Using Loggging-Level " + MyLogManager.getProperty(".level"));
//logger.initRaw(dosql.class) SxTransformer myTransformer = null;
//PropertyConfigurator.configure(logfile); if (_out.equals(""))
File f = new File(logfile); myTransformer = new SxTransformer(logger, System.out);
if (!f.exists()) { else
throw new IOException("Datei nicht gefunden: " + logfile); myTransformer = new SxTransformer(logger, _out);
} myTransformer.quellstring = _xml;
FileInputStream ins = new FileInputStream(logfile); myTransformer.stylesheet = _xsl;
LogManager MyLogManager = java.util.logging.LogManager.getLogManager(); myTransformer.setParams(_params);
MyLogManager.readConfiguration(ins); try {
//logfile = MyLogManager.getProperty(".level"); myTransformer.transformFile(method);
logger.info("Using Loggging-Level " + MyLogManager.getProperty(".level")); } catch (Exception e) {
// TODO Auto-generated catch block
SxTransformer myTransformer = null; e.printStackTrace();
if (_out.equals("")) }
myTransformer = new SxTransformer(logger, System.out); }
else
myTransformer = new SxTransformer(logger, _out); public static void main(String args[]) {
myTransformer.quellstring = _xml; try {
myTransformer.stylesheet = _xsl; if (args.length < 2) {
myTransformer.setParams(_params); System.err.println("Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zur xml-Datei,Pfad zur xsl-Datei) erfoderlich");
try { System.err.println(usage);
myTransformer.transformFile(method); System.exit(1);
} catch (Exception e) { }
// TODO Auto-generated catch block TimeUtils t = new TimeUtils();
e.printStackTrace(); t.start();
} transform(args);
} t.print(" done");
public static void main(String args[]) { String msg = "XML-Transformation erfolgreich ";
try { if (_out != null && !_out.equals("")) msg += _out + " erzeugt";
if (args.length < 2) { System.out.println(msg);
System.err.println( } catch (Exception ex) {
"Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zur xml-Datei,Pfad zur xsl-Datei) erfoderlich"); System.err.println("Es ist ein Fehler aufgetreten, " + _out + " konnte nicht erstellt werden\n" + ex.toString());
System.err.println(usage); File f = new File(_out);
System.exit(1); if (f.exists()) {
} f.delete();
TimeUtils t=new TimeUtils(); t.start(); }
transform(args); System.exit(1);
t.print(" done"); }
String msg = "XML-Transformation erfolgreich "; }
if (_out != null && !_out.equals("")) }
msg += _out + " erzeugt";
System.out.println(msg);
} catch (Exception ex) {
System.err.println("Es ist ein Fehler aufgetreten, "+_out+" konnte nicht erstellt werden\n"+ex.toString());
File f = new File(_out);
if (f.exists()) {
f.delete();
}
System.exit(1);
}
}
}

128
src/de/superx/bin/SpecialUpdater.java

@ -1,66 +1,64 @@
package de.superx.bin; package de.superx.bin;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import de.memtext.db.ConnectionCreator; import de.memtext.db.ConnectionCreator;
public class SpecialUpdater { public class SpecialUpdater {
public static String url="jdbc:informix-sqli://jupiter:50000:informixserver=superx_host;database=superx"; public static String url = "jdbc:informix-sqli://jupiter:50000:informixserver=superx_host;database=superx";
public static String passwd="anfang12";
SpecialUpdater() public static String passwd = "anfang12";
{
SpecialUpdater() {
}
public void run() throws SQLException }
{
ConnectionCreator.loadClass("com.informix.jdbc.IfxDriver"); public void run() throws SQLException {
Connection con=ConnectionCreator.getConnection(url,"superx",passwd); ConnectionCreator.loadClass("com.informix.jdbc.IfxDriver");
Statement stm=con.createStatement(); Connection con = ConnectionCreator.getConnection(url, "superx", passwd);
ResultSet rs=stm.executeQuery("select tid,relation from felderinfo where art=12"); Statement stm = con.createStatement();
int tid; ResultSet rs = stm.executeQuery("select tid,relation from felderinfo where art=12");
String relation,relationCorr; int tid;
PreparedStatement pst=con.prepareStatement("update felderinfo set relation=? where tid=?"); String relation, relationCorr;
while (rs.next()) { PreparedStatement pst = con.prepareStatement("update felderinfo set relation=? where tid=?");
tid=rs.getInt("tid"); while (rs.next()) {
relation=rs.getString("relation"); tid = rs.getInt("tid");
if (relation.indexOf("tid")>-1&&relation.indexOf("sichten")>-1) relation = rs.getString("relation");
{ if (relation.indexOf("tid") > -1 && relation.indexOf("sichten") > -1) {
System.out.println("replace for "+tid+" "); System.out.println("replace for " + tid + " ");
System.out.println(" "+relation); System.out.println(" " + relation);
relationCorr=relation.replaceAll(" tid "," id "); relationCorr = relation.replaceAll(" tid ", " id ");
System.out.println(" "+relationCorr); System.out.println(" " + relationCorr);
pst.setString(1,relationCorr); pst.setString(1, relationCorr);
pst.setInt(2,tid); pst.setInt(2, tid);
pst.execute(); pst.execute();
} }
} }
rs.close(); rs.close();
stm.close(); stm.close();
con.close(); con.close();
} }
public static void main(String[] args) {
if (args.length==0) public static void main(String[] args) {
{ if (args.length == 0) {
System.out.println(" informix driver must be in classpath"); System.out.println(" informix driver must be in classpath");
System.out.println(" url [passwd]"); System.out.println(" url [passwd]");
} }
if (args.length>0) if (args.length > 0) url = args[0];
url=args[0]; if (args.length > 1) passwd = args[1];
if (args.length>1) try {
passwd=args[1]; new SpecialUpdater().run();
try { } catch (SQLException e) {
new SpecialUpdater().run(); e.printStackTrace();
} catch (SQLException e) { }
e.printStackTrace(); }
} }
}
}
//Created on 17.02.2005 at 15:55:28 //Created on 17.02.2005 at 15:55:28

84
src/de/superx/bin/SxConnection.java

@ -19,16 +19,44 @@ import de.superx.util.SqlStringUtils;
* @version 1.1 * @version 1.1
*/ */
public class SxConnection { public class SxConnection {
public enum DriverClass{
dc_postgre("org.postgresql.Driver", "PG"),
dc_informix("com.informix.jdbc.IfxDriver", "IDS");
private String value, abbr;
private DriverClass(String value, String abbr) {
this.value = value;
this.abbr = abbr;
}
public String stringValue() {
return value;
}
public String getAbbr() {
return abbr;
}
}
byte key[] = { (byte) 255, (byte) 221, (byte) 127, (byte) 109, (byte) 129 }; byte key[] = { (byte) 255, (byte) 221, (byte) 127, (byte) 109, (byte) 129 };
int keyLength = key.length; int keyLength = key.length;
boolean isPwLogWanted = false; boolean isPwLogWanted = false;
public Connection con; public Connection con;
private String m_DBUrl; private String m_DBUrl;
private String m_User; private String m_User;
private String m_Password; private String m_Password;
private Properties props = new Properties(); private Properties props = new Properties();
public String m_DriverClass;
public DriverClass m_DriverClass;
public String propfile = ""; public String propfile = "";
/** /**
@ -42,22 +70,22 @@ public class SxConnection {
props.put("user", m_User); props.put("user", m_User);
props.put("password", m_Password); props.put("password", m_Password);
if (m_DriverClass.equals("org.postgresql.Driver")) { if (m_DriverClass == DriverClass.dc_postgre) {
props.put("charSet", SqlStringUtils.getEncoding().equals("UTF-8")?"UTF-8":"Latin-1"); props.put("charSet", SqlStringUtils.getEncoding().equals("UTF-8") ? "UTF-8" : "Latin-1");
props.put("DateStyle", "German, DMY"); props.put("DateStyle", "German, DMY");
} }
if (m_DriverClass.equals("com.informix.jdbc.IfxDriver")) { if (m_DriverClass == DriverClass.dc_informix) {
props.put("GL_DATETIME", "%d.%m.%Y %T"); props.put("GL_DATETIME", "%d.%m.%Y %T");
props.put("CLIENT_LOCALE", SqlStringUtils.getEncoding().equals("UTF-8")?"UTF-8":"de_de.8859-1"); props.put("CLIENT_LOCALE", SqlStringUtils.getEncoding().equals("UTF-8") ? "UTF-8" : "de_de.8859-1");
} }
Class.forName(m_DriverClass); Class.forName(m_DriverClass.stringValue());
//System.out.println(m_DriverClass); //System.out.println(m_DriverClass);
//Zur Zeit wird die db_locale auf Deutsch festgelegt. //Zur Zeit wird die db_locale auf Deutsch festgelegt.
// In Zukunft muss sie mit db.properties übergeben werden. // In Zukunft muss sie mit db.properties übergeben werden.
con = DriverManager.getConnection(m_DBUrl, props); con = DriverManager.getConnection(m_DBUrl, props);
if (m_DriverClass.equals("org.postgresql.Driver")) { if (m_DriverClass == DriverClass.dc_postgre) {
//Seit postgres 8 (win) geht der props.Datestyle Parameter nicht //Seit postgres 8 (win) geht der props.Datestyle Parameter nicht
// mehr // mehr
DatabaseMetaData dbmd = con.getMetaData(); DatabaseMetaData dbmd = con.getMetaData();
@ -85,8 +113,7 @@ public class SxConnection {
private void loadProperties() throws Exception { private void loadProperties() throws Exception {
String pfad = ""; String pfad = "";
if (propfile.equals("") || propfile.equals(null)) if (propfile.equals("") || propfile.equals(null))
pfad = ".." + System.getProperty("file.separator") + "conf" pfad = ".." + System.getProperty("file.separator") + "conf" + System.getProperty("file.separator") + "db.properties";
+ System.getProperty("file.separator") + "db.properties";
else else
pfad = propfile; pfad = propfile;
//String pfad=".." + System.getProperty("file.separator") + ".." + //String pfad=".." + System.getProperty("file.separator") + ".." +
@ -104,7 +131,13 @@ public class SxConnection {
m_DBUrl = props.getProperty("connectionURL"); m_DBUrl = props.getProperty("connectionURL");
m_User = props.getProperty("connectionName"); m_User = props.getProperty("connectionName");
m_Password = PropsReader.check(props.getProperty("connectionPassword")); m_Password = PropsReader.check(props.getProperty("connectionPassword"));
m_DriverClass = props.getProperty("driverName"); for (DriverClass dc : DriverClass.values()) {
if (dc.stringValue().equals(props.getProperty("driverName"))) {
m_DriverClass = dc;
}
}
//m_DriverClass = props.getProperty("driverName");
} }
@ -131,20 +164,19 @@ public class SxConnection {
/** /**
* @return * @return
*/ */
public String getM_DriverClass() { public DriverClass getM_DriverClass() {
return m_DriverClass; return m_DriverClass;
} }
public String getDatabaseAbbr() public String getDatabaseAbbr() {
{ //String result = "unknown";
String result="unknown"; //if (getM_DriverClass() == DriverClass.dc_postgre) result = "PG";
if (getM_DriverClass().toLowerCase().indexOf( //if (getM_DriverClass() == DriverClass.dc_informix) result = "IDS";
"postgres") > -1) result="PG"; //return result;
if (getM_DriverClass().toLowerCase().indexOf( return getM_DriverClass().getAbbr();
"informix") > -1) result="IDS";
return result;
} }
public String getPropfile() { public String getPropfile() {
return propfile; return propfile;
} }
@ -153,7 +185,11 @@ public class SxConnection {
* @param string * @param string
*/ */
public void setM_DriverClass(String string) { public void setM_DriverClass(String string) {
m_DriverClass = string; for (DriverClass dc : DriverClass.values()) {
if(dc.stringValue().equals(string)) {
m_DriverClass = dc;
}
}
} }
/** /**
@ -164,7 +200,9 @@ public class SxConnection {
} }
public void close() throws SQLException { public void close() throws SQLException {
con.close(); if(con != null) {
con.close();
}
} }

497
src/de/superx/bin/SxDBUtils.java

@ -1,4 +1,5 @@
package de.superx.bin; package de.superx.bin;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
@ -26,277 +27,259 @@ import de.superx.util.SqlStringUtils;
* *
*/ */
public class SxDBUtils { public class SxDBUtils {
private static SimpleDateFormat AmericanDateFormat = private static SimpleDateFormat AmericanDateFormat = new SimpleDateFormat("yyyy-MM-dd");
new SimpleDateFormat("yyyy-MM-dd");
public static int fieldCount(String tabname) throws Exception { public static int fieldCount(String tabname) throws Exception {
int fieldcount; int fieldcount;
SxConnection myConnection = new SxConnection(); SxConnection myConnection = new SxConnection();
//myConnection.setPropfile( PropFile); //myConnection.setPropfile( PropFile);
String query = String query = "select count(*) from pg_attribute A, pg_class C, pg_type T where A.attrelid=C.relfilenode and A.atttypid=T.oid and A.attnum>0 and A.attisdropped = FALSE and C.relname='" + tabname
"select count(*) from pg_attribute A, pg_class C, pg_type T where A.attrelid=C.relfilenode and A.atttypid=T.oid and A.attnum>0 and C.relname='" + "';";
+ tabname Connection myDb = myConnection.getConnection();
+ "';"; Statement st = myDb.createStatement();
Connection myDb = myConnection.getConnection(); ResultSet rs = null;
Statement st = myDb.createStatement(); try {
ResultSet rs = null; rs = st.executeQuery(query);
try { } catch (SQLException se) {
rs = st.executeQuery(query); System.err.println("SQL-Fehler: " + se.toString());
} catch (SQLException se) { } catch (Exception e) {
System.err.println("SQL-Fehler: " + se.toString()); System.err.println("DB-Zugriff-Fehler: " + e.toString());
} catch (Exception e) { }
System.err.println("DB-Zugriff-Fehler: " + e.toString());
}
if (rs.next()) { if (rs.next()) {
fieldcount = rs.getInt(1); fieldcount = rs.getInt(1);
} else { } else {
fieldcount = 0; fieldcount = 0;
} }
return fieldcount; return fieldcount;
}
public static void main(String args[]) {
TimeUtils tu=new TimeUtils();
String f_wert=null;
tu.start();
for (int i=0;i<1000;i++)
{
f_wert="\nx\r\nx\n\rx\\\n\\\rx\\\r\\\nx\\n\\rx\\r\\nx\\rx\r";
f_wert= replaceString(f_wert, "\n", "\\\n");
f_wert = replaceString(f_wert, "\r\n", "\\\n");
f_wert = replaceString(f_wert, "\n\r", "\\\n");
f_wert = replaceString(f_wert,"\\\n\\\r","");
f_wert = replaceString(f_wert,"\\\r\\\n","");
f_wert = replaceString(f_wert,"\\r\\n","");
f_wert = replaceString(f_wert,"\\n\\r","");
f_wert = replaceString(f_wert,"\\r","\\\n");
f_wert = replaceString(f_wert,"\r","\\\n");
}
tu.print("replace String 1000x");
String old=f_wert;
StringBuffer t=null;
for (int i=0;i<1000;i++)
{
f_wert="\nx\r\nx\n\rx\\\n\\\rx\\\r\\\nx\\n\\rx\\r\\nx\\rx\r";
t=new StringBuffer(f_wert);
StringUtils.replace(t,"\n","\\\n");
StringUtils.replace(t,"\r\n","\\\n");
StringUtils.replace(t,"\n\r","\\\n");
StringUtils.replace(t,"\\\n\\\r","");
StringUtils.replace(t,"\\\r\\\n","");
StringUtils.replace(t,"\\n\\r","");
StringUtils.replace(t,"\\r\\n","");
StringUtils.replace(t,"\\r","\\\n");
StringUtils.replace(t,"\r","\\\n");
}
tu.print("replace StringBuffer 1000x");
System.out.println(old.equals(t.toString()));
} }
public static String replaceString(
String str,
String search_str,
String replace_str) {
String zs = "";
if (!search_str.equals("") && search_str != null) { public static void main(String args[]) {
int offset = 0; TimeUtils tu = new TimeUtils();
int pos = str.indexOf(search_str, offset); String f_wert = null;
while (pos > -1) { tu.start();
zs += str.substring(offset, pos); for (int i = 0; i < 1000; i++) {
zs += replace_str; f_wert = "\nx\r\nx\n\rx\\\n\\\rx\\\r\\\nx\\n\\rx\\r\\nx\\rx\r";
offset = pos + search_str.length(); f_wert = replaceString(f_wert, "\n", "\\\n");
pos = str.indexOf(search_str, offset); f_wert = replaceString(f_wert, "\r\n", "\\\n");
} f_wert = replaceString(f_wert, "\n\r", "\\\n");
zs += str.substring(offset, str.length()); f_wert = replaceString(f_wert, "\\\n\\\r", "");
} else f_wert = replaceString(f_wert, "\\\r\\\n", "");
//Der Suchstring war leer f_wert = replaceString(f_wert, "\\r\\n", "");
zs = str; f_wert = replaceString(f_wert, "\\n\\r", "");
return zs; f_wert = replaceString(f_wert, "\\r", "\\\n");
} f_wert = replaceString(f_wert, "\r", "\\\n");
public static List toResultList(ResultSet rs) throws SQLException { }
List help = new LinkedList(); tu.print("replace String 1000x");
ResultSetMetaData rsmd = rs.getMetaData(); String old = f_wert;
int numberOfColumns = rsmd.getColumnCount(); StringBuffer t = null;
for (int i = 0; i < 1000; i++) {
f_wert = "\nx\r\nx\n\rx\\\n\\\rx\\\r\\\nx\\n\\rx\\r\\nx\\rx\r";
t = new StringBuffer(f_wert);
StringUtils.replace(t, "\n", "\\\n");
StringUtils.replace(t, "\r\n", "\\\n");
StringUtils.replace(t, "\n\r", "\\\n");
StringUtils.replace(t, "\\\n\\\r", "");
StringUtils.replace(t, "\\\r\\\n", "");
StringUtils.replace(t, "\\n\\r", "");
StringUtils.replace(t, "\\r\\n", "");
StringUtils.replace(t, "\\r", "\\\n");
StringUtils.replace(t, "\r", "\\\n");
}
tu.print("replace StringBuffer 1000x");
System.out.println(old.equals(t.toString()));
}
List row = null; public static String replaceString(String str, String search_str, String replace_str) {
while (rs.next()) { String zs = "";
row = new LinkedList();
for (int i = 1; i <= numberOfColumns; i++) {
row.add(rs.getObject(i));
}
help.add(row);
}
rs.close();
return help;
}
public static String getSqlTypeName(int type) { if (!search_str.equals("") && search_str != null) {
switch (type) { int offset = 0;
case Types.ARRAY : int pos = str.indexOf(search_str, offset);
return "ARRAY"; while (pos > -1) {
case Types.BIGINT : zs += str.substring(offset, pos);
return "BIGINT"; zs += replace_str;
case Types.BIT : offset = pos + search_str.length();
return "BOOLEAN"; pos = str.indexOf(search_str, offset);
case Types.TINYINT : }
return "TINYINT"; zs += str.substring(offset, str.length());
case Types.SMALLINT : } else
return "SMALLINT"; //Der Suchstring war leer
case Types.INTEGER : zs = str;
return "INTEGER"; return zs;
case Types.FLOAT : }
return "FLOAT";
case Types.REAL :
return "REAL";
case Types.DOUBLE :
return "DOUBLE";
case Types.NUMERIC :
return "NUMERIC";
case Types.DECIMAL :
return "DECIMAL";
case Types.CHAR :
return "CHAR";
case Types.VARCHAR :
return "VARCHAR";
case Types.LONGVARCHAR :
return "LONGVARCHAR";
case Types.DATE :
return "DATE";
case Types.TIME :
return "TIME";
case Types.TIMESTAMP :
return "DATETIME";
//used to be TIMESTAMP, but HIS uses datetime
case Types.BINARY :
return "BINARY";
case Types.VARBINARY :
return "VARBINARY";
case Types.LONGVARBINARY :
return "LONGVARBINARY";
case Types.NULL :
return "NULL";
case Types.OTHER :
return "OTHER";
case Types.JAVA_OBJECT :
return "JAVA_OBJECT";
case Types.DISTINCT :
return "DISTINCT";
case Types.STRUCT :
return "STRUCT";
case Types.BLOB :
return "BLOB";
case Types.CLOB :
return "CLOB";
case Types.REF :
return "REF";
default :
return "" + type + " Unknown";
}
}
public static String field_value(Object o) {
String f_wert = "";
if (o != null) {
if (o instanceof java.sql.Date) {
if (System.getProperty("user.language") != null
&& (System.getProperty("user.language").equals("us_US")
|| System.getProperty("user.language").equals("en_US")))
f_wert = "" + getUSDateFormat((java.sql.Date) o);
else
f_wert = SqlStringUtils.getValueAsString(o);
// DateFormat.getDateInstance(DateFormat.MEDIUM).format(o);
} public static List toResultList(ResultSet rs) throws SQLException {
else{ List help = new LinkedList();
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
if (o instanceof java.sql.Timestamp)
f_wert = SqlStringUtils.getValueAsString(o);
else
//"" +DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM).format(o);
if (o instanceof java.sql.Time)
f_wert = SqlStringUtils.getValueAsString(o);
else
//""+ DateFormat.getTimeInstance(DateFormat.MEDIUM).format(o);
if (o instanceof java.lang.String) {
f_wert=o.toString().trim();
if(f_wert.length()==0 )
f_wert=" "; //Leerstring wird auf " " gesetzt
else
f_wert=f_wert.trim(); //Leerzeichen bei gefüllten Feldern entfernen.
}
else List row = null;
//default: while (rs.next()) {
f_wert = o.toString(); row = new LinkedList();
} for (int i = 1; i <= numberOfColumns; i++) {
row.add(rs.getObject(i));
}
help.add(row);
}
rs.close();
return help;
}
} else public static String getSqlTypeName(int type) {
f_wert = ""; switch (type) {
return f_wert; case Types.ARRAY:
} return "ARRAY";
case Types.BIGINT:
return "BIGINT";
case Types.BIT:
return "BOOLEAN";
case Types.TINYINT:
return "TINYINT";
case Types.SMALLINT:
return "SMALLINT";
case Types.INTEGER:
return "INTEGER";
case Types.FLOAT:
return "FLOAT";
case Types.REAL:
return "REAL";
case Types.DOUBLE:
return "DOUBLE";
case Types.NUMERIC:
return "NUMERIC";
case Types.DECIMAL:
return "DECIMAL";
case Types.CHAR:
return "CHAR";
case Types.VARCHAR:
return "VARCHAR";
case Types.LONGVARCHAR:
return "LONGVARCHAR";
case Types.DATE:
return "DATE";
case Types.TIME:
return "TIME";
case Types.TIMESTAMP:
return "DATETIME";
//used to be TIMESTAMP, but HIS uses datetime
case Types.BINARY:
return "BINARY";
case Types.VARBINARY:
return "VARBINARY";
case Types.LONGVARBINARY:
return "LONGVARBINARY";
case Types.NULL:
return "NULL";
case Types.OTHER:
return "OTHER";
case Types.JAVA_OBJECT:
return "JAVA_OBJECT";
case Types.DISTINCT:
return "DISTINCT";
case Types.STRUCT:
return "STRUCT";
case Types.BLOB:
return "BLOB";
case Types.CLOB:
return "CLOB";
case Types.REF:
return "REF";
default:
return "" + type + " Unknown";
}
}
/** public static String field_value(Object o) {
* Gets a date String in the format needed by Hsql String f_wert = "";
if (o != null) {
* @param Date - java.util.Date object to be transformed if (o instanceof java.sql.Date) {
* @return String - in the format for Hsql ("01-01-2004") if (System.getProperty("user.language") != null && (System.getProperty("user.language").equals("us_US") || System.getProperty("user.language").equals("en_US")))
*/ f_wert = "" + getUSDateFormat((java.sql.Date) o);
public static String getUSDateFormat(java.sql.Date date) { else
StringBuffer result = new StringBuffer(""); f_wert = SqlStringUtils.getValueAsString(o);
if (date != null) { // DateFormat.getDateInstance(DateFormat.MEDIUM).format(o);
AmericanDateFormat.format(date, result, new FieldPosition(0));
//result.append("");
}
return date == null ? null : result.toString();
}
public static String prepareInformixCsv(String feldwert)
{
//Informix-LOAD ist unser Standardformat; es setzt linebreaks als \n um, davor ein "\"
//Bei Textfelder müssen alle anderen Linebreaks raus, deshalb der folgende Passus
String f_wert; } else {
char newline = '\n';
f_wert=feldwert ;
if(f_wert.length()==0 ) f_wert=""; //der String enthält nur Sonderzeichen und wird auf leer gesetzt. if (o instanceof java.sql.Timestamp)
else f_wert = SqlStringUtils.getValueAsString(o);
{ else
//wenn der Feldwert zufällig das Zeichen "\" enthält, wird es mit "\" maskiert //"" +DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM).format(o);
if( f_wert != null && (f_wert.indexOf("\\") >-1 )) if (o instanceof java.sql.Time)
{ f_wert = SqlStringUtils.getValueAsString(o);
f_wert=de.memtext.util.StringUtils.replace(f_wert, "\\", "\\\\"); else
//""+ DateFormat.getTimeInstance(DateFormat.MEDIUM).format(o);
if (o instanceof java.lang.String) {
f_wert = o.toString().trim();
if (f_wert.length() == 0)
f_wert = " "; //Leerstring wird auf " " gesetzt
else
f_wert = f_wert.trim(); //Leerzeichen bei gefüllten Feldern entfernen.
}
else
//default:
f_wert = o.toString();
} }
//Linebreaks umsetzen:
if(f_wert.equals("\n")
|| f_wert.equals("\r\n")
|| f_wert.equals("\n\r")
|| f_wert.equals("\\n\r")
|| f_wert.equals("\\\n\\\r")
|| f_wert.equals("\\\n")
|| f_wert.equals("\\n")
|| f_wert.equals("\\\r")
|| f_wert.equals("\\r")
|| f_wert.equals("\r")
)
f_wert="";
//neue Version mit StringBuffer ist schneller
StringBuffer t=new StringBuffer(f_wert);
StringUtils.replace(t,"\r\n","\n");
StringUtils.replace(t,"\n","\\\n");
StringUtils.replace(t,"\n\r","\\\n");
StringUtils.replace(t,"\\\n\\\r","");
StringUtils.replace(t,"\\\r\\\n","");
StringUtils.replace(t,"\\n\\r","");
StringUtils.replace(t,"\\r\\n","");
StringUtils.replace(t,"\\r","\\\n");
StringUtils.replace(t,"\r","\\\n");
f_wert=t.toString();
} else
f_wert = "";
return f_wert;
}
/**
* Gets a date String in the format needed by Hsql
* @param Date - java.util.Date object to be transformed
* @return String - in the format for Hsql ("01-01-2004")
*/
public static String getUSDateFormat(java.sql.Date date) {
StringBuffer result = new StringBuffer("");
if (date != null) {
AmericanDateFormat.format(date, result, new FieldPosition(0));
//result.append("");
}
return date == null ? null : result.toString();
} }
return f_wert;
public static String prepareInformixCsv(String feldwert) {
//Informix-LOAD ist unser Standardformat; es setzt linebreaks als \n um, davor ein "\"
//Bei Textfelder müssen alle anderen Linebreaks raus, deshalb der folgende Passus
String f_wert;
char newline = '\n';
f_wert = feldwert;
if (f_wert.length() == 0)
f_wert = ""; //der String enthält nur Sonderzeichen und wird auf leer gesetzt.
else {
//wenn der Feldwert zufällig das Zeichen "\" enthält, wird es mit "\" maskiert
if (f_wert != null && (f_wert.indexOf("\\") > -1)) {
f_wert = de.memtext.util.StringUtils.replace(f_wert, "\\", "\\\\");
}
//Linebreaks umsetzen:
if (f_wert.equals("\n") || f_wert.equals("\r\n") || f_wert.equals("\n\r") || f_wert.equals("\\n\r") || f_wert.equals("\\\n\\\r") || f_wert.equals("\\\n")
|| f_wert.equals("\\n") || f_wert.equals("\\\r") || f_wert.equals("\\r") || f_wert.equals("\r")) f_wert = "";
//neue Version mit StringBuffer ist schneller
StringBuffer t = new StringBuffer(f_wert);
StringUtils.replace(t, "\r\n", "\n");
StringUtils.replace(t, "\n", "\\\n");
StringUtils.replace(t, "\n\r", "\\\n");
StringUtils.replace(t, "\\\n\\\r", "");
StringUtils.replace(t, "\\\r\\\n", "");
StringUtils.replace(t, "\\n\\r", "");
StringUtils.replace(t, "\\r\\n", "");
StringUtils.replace(t, "\\r", "\\\n");
StringUtils.replace(t, "\r", "\\\n");
f_wert = t.toString();
}
return f_wert;
} }
} }

692
src/de/superx/bin/SxExtractor.java

@ -5,17 +5,19 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Properties; import java.util.Properties;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.logging.LogManager; import java.util.logging.LogManager;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.Enumeration;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import de.memtext.util.ExceptionHandler;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
import de.memtext.util.XMLUtils; import de.memtext.util.XMLUtils;
/* /*
@ -25,348 +27,346 @@ import de.memtext.util.XMLUtils;
* 18.9.08 DQ Params werden anders gelesen * 18.9.08 DQ Params werden anders gelesen
*/ */
public class SxExtractor { public class SxExtractor {
String delim = "^"; String delim = "^";
String header = "false";
String logfile = "../conf/logging.properties"; String header = "false";
String tabelle = "";
String dbpropfile = "../conf/db.properties"; String logfile = "../conf/logging.properties";
String myElement = "table";
String myAttrib = "name"; String tabelle = "";
String outformat = "txt";
String outfile = ""; String dbpropfile = "../conf/db.properties";
String _dateiPfad = "";
private static final String extraction_table = "extraction-table"; String myElement = "table";
private static final String extraction_script = "extraction-script";
private static final String extraction_sql = "extraction-sql"; String myAttrib = "name";
private static final String database_name = "database";
private static final String version_name = "version"; String outformat = "txt";
private static final String transfer_unload_file = "transfer-unload-file";
String outfile = "";
private static Document document;
//LogUtils logger=null; String _dateiPfad = "";
public Logger logger = (Logger) Logger.getLogger(SxExtractor.class
.toString()); private static final String extraction_table = "extraction-table";
//static Logger logger = Logger.getLogger(dosql.class);
private ExceptionHandler exceptionHandler = new ExceptionHandler(false); private static final String extraction_script = "extraction-script";
private static String usage = "-------------------------------------\n"
+ "Dieses Script analysiert eine vorgegebene XML-Datei auf Attribute extraction-table, extraction-script und extraction-sql. Wess es ein Attribur findet, startet es die entsprechende DB-Verbindung und entlädt das Ergebnis nach dem Wert des Attributs transfer-unload-file\n" private static final String extraction_sql = "extraction-sql";
+ "Gebrauch: java de.superx.bin.SxExtractor -logger=<<Pfad zu logging.properties>> -dbproperties=<<Pfad zu db.properties>> "
+ "-xml:<xml-Datei> -params:<Parameter, die in sql- oder Script-Dateien ersetzt werden; Syntax:param1=wert1|param2=wert2 etc> -outFormat:<Ausgabeformat (txt | html | xml)>(optional) " private static final String database_name = "database";
+ " -delim:<delimiter> -header:<mit Spaltenüberschriften (true | false)>(optional) -outfile:<Ausgabedatei>(optional) \n---------------------------------------------------";
private static final String version_name = "version";
public SxExtractor(String args[]) throws IOException {
String name = ""; private static final String transfer_unload_file = "transfer-unload-file";
String unl_file = "";
String params = ""; private static Document document;
String database = "";
String version = ""; // LogUtils logger=null;
String p_database = ""; public Logger logger = (Logger) Logger.getLogger(SxExtractor.class.toString());
String p_version = "";
String unload_params="unload_params.txt"; // static Logger logger = Logger.getLogger(dosql.class);
String sourcesystem="";
GetOpts.setOpts(args); private static String usage = "-------------------------------------\n"
Node myNode; + "Dieses Script analysiert eine vorgegebene XML-Datei auf Attribute extraction-table, extraction-script und extraction-sql. Wess es ein Attribur findet, startet es die entsprechende DB-Verbindung und entlädt das Ergebnis nach dem Wert des Attributs transfer-unload-file\n"
String isdrin = GetOpts + "Gebrauch: java de.superx.bin.SxExtractor -logger=<<Pfad zu logging.properties>> -dbproperties=<<Pfad zu db.properties>> "
.isAllRequiredOptionsPresent("-logger,-dbproperties,-xml"); + "-xml:<xml-Datei> -params:<Parameter, die in sql- oder Script-Dateien ersetzt werden; Syntax:param1=wert1|param2=wert2 etc> -outFormat:<Ausgabeformat (txt | html | xml)>(optional) "
if (isdrin != null) { + " -delim:<delimiter> -header:<mit Spaltenüberschriften (true | false)>(optional) -outfile:<Ausgabedatei>(optional) \n---------------------------------------------------";
System.err.println("Folgende Optionen fehlen: " + isdrin);
System.err.println(usage); public SxExtractor(String args[]) throws IOException, SAXException {
System.exit(1); String name = "";
} String unl_file = "";
Properties props = new Properties(); String params = "";
//GetOpts myOpts=new GetOpts(); String database = "";
if (GetOpts.isPresent("-logger")) String version = "";
logfile = GetOpts.getValue("-logger"); String p_database = "";
if (GetOpts.isPresent("-dbproperties")) String p_version = "";
dbpropfile = GetOpts.getValue("-dbproperties"); String unload_params = "unload_params.txt";
if (GetOpts.isPresent("-xml")) String sourcesystem = "";
_dateiPfad = GetOpts.getValue("-xml"); GetOpts.setOpts(args);
if (GetOpts.isPresent("-params")) Node myNode;
params = GetOpts.getValue("-params"); String isdrin = GetOpts.isAllRequiredOptionsPresent(
if (GetOpts.isPresent("-outFormat")) new Options[] { Options.opt_logger, Options.opt_dbprops, Options.opt_xml });
outformat = GetOpts.getValue("-outFormat"); if (isdrin != null) {
if (GetOpts.isPresent("-delim")) System.err.println("Folgende Optionen fehlen: " + isdrin);
delim = GetOpts.getValue("-delim"); System.err.println(usage);
if (GetOpts.isPresent("-header")) System.exit(1);
header = GetOpts.getValue("-header"); }
if (GetOpts.isPresent("-database")) Properties props = new Properties();
p_database = GetOpts.getValue("-database"); // GetOpts myOpts=new GetOpts();
if (GetOpts.isPresent("-version")) if (GetOpts.isPresent(Options.opt_logger))
p_version = GetOpts.getValue("-version"); logfile = GetOpts.getValue(Options.opt_logger);
if (GetOpts.isPresent("-unload_params")) if (GetOpts.isPresent(Options.opt_dbprops))
unload_params = GetOpts.getValue("-unload_params"); dbpropfile = GetOpts.getValue(Options.opt_dbprops);
if (GetOpts.isPresent(Options.opt_xml))
_dateiPfad = GetOpts.getValue(Options.opt_xml);
//wenn eine Datei "unload_params.txt existiert und mindestens ein Parameter if (GetOpts.isPresent(Options.opt_xml))
//definiert ist, überschreibt er die Kommandozeile params = GetOpts.getValue(Options.opt_xml);
//Grund: Kommandozeile unter Unix löst Variablen sonst auf if (GetOpts.isPresent(Options.opt_outFormat))
if (new File(unload_params).exists()) outformat = GetOpts.getValue(Options.opt_outFormat);
{ if (GetOpts.isPresent(Options.opt_delim))
FileInputStream is = new FileInputStream(unload_params); delim = GetOpts.getValue(Options.opt_delim);
if (GetOpts.isPresent(Options.opt_header))
if (is != null) { header = GetOpts.getValue(Options.opt_header);
props.load(is); if (GetOpts.isPresent(Options.opt_db))
is.close(); p_database = GetOpts.getValue(Options.opt_db);
Enumeration propnames = props.propertyNames(); if (GetOpts.isPresent(Options.opt_version))
if(propnames!=null) p_version = GetOpts.getValue(Options.opt_version);
{ if (GetOpts.isPresent(Options.opt_unlParams))
params=""; unload_params = GetOpts.getValue(Options.opt_unlParams);
while (propnames.hasMoreElements()) {
String propname = (String)propnames.nextElement(); // wenn eine Datei "unload_params.txt existiert und mindestens ein Parameter
params+=propname + "=" + props.getProperty(propname)+"^"; // definiert ist, überschreibt er die Kommandozeile
if(propname.equals("$SOURCESYSTEM")) // Grund: Kommandozeile unter Unix löst Variablen sonst auf
sourcesystem=props.getProperty(propname); if (new File(unload_params).exists()) {
} FileInputStream is = new FileInputStream(unload_params);
//params=params.substring(0, params.length()-1);
} if (is != null) {
} props.load(is);
} is.close();
File f = new File(logfile); Enumeration propnames = props.propertyNames();
if (!f.exists()) { if (propnames != null) {
throw new IOException("Datei nicht gefunden: " + logfile); params = "";
} while (propnames.hasMoreElements()) {
FileInputStream ins = new FileInputStream(logfile); String propname = (String) propnames.nextElement();
LogManager MyLogManager = java.util.logging.LogManager.getLogManager(); params += propname + "=" + props.getProperty(propname) + "^";
MyLogManager.readConfiguration(ins); if (propname.equals("$SOURCESYSTEM"))
sourcesystem = props.getProperty(propname);
//XMLUtils myUtils=new XMLUtils(); }
XMLUtils.getExceptionHandler().setWithGui(false); // params=params.substring(0, params.length()-1);
XMLUtils.getExceptionHandler().setExitWanted(true); }
if (delim.equals("")) }
delim = "^"; //default Delimiter }
File f = new File(logfile);
document = XMLUtils.buildDocument(new File(_dateiPfad), false); if (!f.exists()) {
// NodeList myNodes = document.getElementsByTagName(myElement); throw new IOException("Datei nicht gefunden: " + logfile);
NodeList myNodes = document.getElementsByTagName("unload-job"); }
FileInputStream ins = new FileInputStream(logfile);
for (int i = 0; i < myNodes.getLength(); i++) { LogManager MyLogManager = java.util.logging.LogManager.getLogManager();
myNode = myNodes.item(i); MyLogManager.readConfiguration(ins);
if (myNode.getNodeType() == Node.TEXT_NODE)
continue; if (delim.equals(""))
if (XMLUtils.hasAttrib(myNode, transfer_unload_file)) delim = "^"; // default Delimiter
unl_file = XMLUtils
.getAttribValue(myNode, transfer_unload_file); document = XMLUtils.buildDocument(new File(_dateiPfad), false);
else // NodeList myNodes = document.getElementsByTagName(myElement);
unl_file = ""; NodeList myNodes = document.getElementsByTagName("unload-job");
//now we have an unload-job-node, and an unload-file is specified.
//now the question: is it an extract-table,script or sql? for (int i = 0; i < myNodes.getLength(); i++) {
if (XMLUtils.hasAttrib(myNode, extraction_table)) myNode = myNodes.item(i);
name = XMLUtils.getAttribValue(myNode, extraction_table); if (myNode.getNodeType() == Node.TEXT_NODE)
else continue;
name = ""; if (XMLUtils.hasAttrib(myNode, transfer_unload_file))
if (XMLUtils.hasAttrib(myNode, version_name)) unl_file = XMLUtils.getAttribValue(myNode, transfer_unload_file);
version = XMLUtils.getAttribValue(myNode, version_name); else
else unl_file = "";
version = ""; // now we have an unload-job-node, and an unload-file is specified.
if (XMLUtils.hasAttrib(myNode, database_name)) // now the question: is it an extract-table,script or sql?
database = XMLUtils.getAttribValue(myNode, database_name); if (XMLUtils.hasAttrib(myNode, extraction_table))
else name = XMLUtils.getAttribValue(myNode, extraction_table);
database = ""; else
if (!name.equals("")) { name = "";
//This is a simple table to be unloaded if (XMLUtils.hasAttrib(myNode, version_name))
extractTable(name, unl_file, database, version, p_database, version = XMLUtils.getAttribValue(myNode, version_name);
p_version); else
} version = "";
if (XMLUtils.hasAttrib(myNode, database_name))
if (XMLUtils.hasAttrib(myNode, extraction_script)) database = XMLUtils.getAttribValue(myNode, database_name);
name = XMLUtils.getAttribValue(myNode, extraction_script); else
else database = "";
name = ""; if (!name.equals("")) {
if (!name.equals("")) { // This is a simple table to be unloaded
//this is an extraction script extractTable(name, unl_file, database, version, p_database, p_version);
//wenn es ein Attribut "sourcesystem" gibt und }
//in den unload_params ein SOURCESYSTEM definiert ist,
//wird dies auf Gleichheit geprüft if (XMLUtils.hasAttrib(myNode, extraction_script))
if(!XMLUtils.hasAttrib(myNode, "sourcesystem") name = XMLUtils.getAttribValue(myNode, extraction_script);
|| XMLUtils.getAttribValue(myNode,"sourcesystem").equals("") else
|| (XMLUtils.hasAttrib(myNode, "sourcesystem") && XMLUtils.getAttribValue(myNode,"sourcesystem").equals(sourcesystem))) name = "";
{ if (!name.equals("")) {
extractionScript(name, unl_file, params, database, version, // this is an extraction script
p_database, p_version); // wenn es ein Attribut "sourcesystem" gibt und
} // in den unload_params ein SOURCESYSTEM definiert ist,
} // wird dies auf Gleichheit geprüft
if (!XMLUtils.hasAttrib(myNode, "sourcesystem")
//Now: are there the sql-Statements? || XMLUtils.getAttribValue(myNode, "sourcesystem").equals("")
NodeList mySqls = myNode.getChildNodes(); || (XMLUtils.hasAttrib(myNode, "sourcesystem")
//name("extraction-sql"); && XMLUtils.getAttribValue(myNode, "sourcesystem").equals(sourcesystem))) {
String sql = ""; extractionScript(name, unl_file, params, database, version, p_database, p_version);
}
for (int k = 0; k < mySqls.getLength(); k++) { }
Node mySqlNode = mySqls.item(k);
if (//mySqlNode.getNodeType() == Node.TEXT_NODE // Now: are there the sql-Statements?
//&& NodeList mySqls = myNode.getChildNodes();
mySqlNode.getNodeName().equals(extraction_sql)) { // name("extraction-sql");
//continue; String sql = "";
//wenn es ein Attribut "sourcesystem" gibt und
//in den unload_params ein SOURCESYSTEM definiert ist, for (int k = 0; k < mySqls.getLength(); k++) {
//wird dies auf Gleichheit geprüft Node mySqlNode = mySqls.item(k);
if(!XMLUtils.hasAttrib(mySqlNode, "sourcesystem") if (// mySqlNode.getNodeType() == Node.TEXT_NODE
|| XMLUtils.getAttribValue(mySqlNode,"sourcesystem").equals("") // &&
|| (XMLUtils.hasAttrib(mySqlNode, "sourcesystem") && XMLUtils.getAttribValue(mySqlNode,"sourcesystem").equals(sourcesystem))) mySqlNode.getNodeName().equals(extraction_sql)) {
params = extractionSql(unl_file, params, p_database, // continue;
p_version, mySqlNode); //when version and database // wenn es ein Attribut "sourcesystem" gibt und
// correct // in den unload_params ein SOURCESYSTEM definiert ist,
} // wird dies auf Gleichheit geprüft
} //mySqls loop if (!XMLUtils.hasAttrib(mySqlNode, "sourcesystem")
} // myNodes loop || XMLUtils.getAttribValue(mySqlNode, "sourcesystem").equals("")
} || (XMLUtils.hasAttrib(mySqlNode, "sourcesystem")
&& XMLUtils.getAttribValue(mySqlNode, "sourcesystem").equals(sourcesystem)))
private String extractionSql( params = extractionSql(unl_file, params, p_database, p_version, mySqlNode); // when version and
// database
String unl_file, String params, String p_database, String p_version, // correct
Node mySqlNode) { }
String database; } // mySqls loop
String version; } // myNodes loop
String sql; }
if (XMLUtils.hasAttrib(mySqlNode, database_name))
database = XMLUtils.getAttribValue(mySqlNode, database_name); private String extractionSql(
else
database = ""; String unl_file, String params, String p_database, String p_version, Node mySqlNode) {
if (XMLUtils.hasAttrib(mySqlNode, version_name)) String database;
version = XMLUtils.getAttribValue(mySqlNode, version_name); String version;
else String sql;
version = ""; if (XMLUtils.hasAttrib(mySqlNode, database_name))
if (isDatabaseAndVersionOk(p_database, p_version, database, version)) { database = XMLUtils.getAttribValue(mySqlNode, database_name);
else
sql = XMLUtils.getChildNodeValues(mySqlNode); database = "";
if (!sql.equals("")) { if (XMLUtils.hasAttrib(mySqlNode, version_name))
//This is a simple sql-String to be unloaded version = XMLUtils.getAttribValue(mySqlNode, version_name);
//First the params are replaced: else
if (!params.equals("")) { version = "";
if (!params.endsWith("^")) if (isDatabaseAndVersionOk(p_database, p_version, database, version)) {
params += "^";
StringTokenizer st = new StringTokenizer(params, "^"); sql = XMLUtils.getChildNodeValues(mySqlNode);
for (; st.hasMoreTokens();) { if (!sql.equals("")) {
String param = st.nextToken(); // This is a simple sql-String to be unloaded
if (!param.equals("")) { // First the params are replaced:
String paramname = param.substring(0, param if (!params.equals("")) {
.indexOf("=")); if (!params.endsWith("^"))
String paramvalue = param.substring(param params += "^";
.indexOf("=") + 1, param.length()); StringTokenizer st = new StringTokenizer(params, "^");
sql = de.superx.bin.SxDBUtils.replaceString(sql, for (; st.hasMoreTokens();) {
paramname, paramvalue); String param = st.nextToken();
} //param not "" if (!param.equals("")) {
} //loop String paramname = param.substring(0, param.indexOf("="));
} //params !="" String paramvalue = param.substring(param.indexOf("=") + 1, param.length());
String[] myArgs = new String[7]; sql = de.superx.bin.SxDBUtils.replaceString(sql, paramname, paramvalue);
myArgs[0] = logfile; //logfile } // param not ""
myArgs[1] = dbpropfile; //db.properties } // loop
myArgs[2] = sql; //_sql } // params !=""
myArgs[3] = outformat; //outformat String[] myArgs = new String[7];
myArgs[4] = delim; //_delim myArgs[0] = logfile; // logfile
myArgs[5] = header; //header myArgs[1] = dbpropfile; // db.properties
myArgs[6] = unl_file; myArgs[2] = sql; // _sql
myArgs[3] = outformat; // outformat
try { myArgs[4] = delim; // _delim
Doquery.go(myArgs); myArgs[5] = header; // header
} catch (Exception e) { myArgs[6] = unl_file;
e.printStackTrace(); try {
} Doquery.go(myArgs);
} catch (Exception e) {
logger.info("Executed sql:\n " + sql);
} //when sql !="" e.printStackTrace();
} }
return params;
} logger.info("Executed sql:\n " + sql);
} // when sql !=""
private boolean isDatabaseAndVersionOk(String p_database, String p_version, }
String database, String version) { return params;
boolean version_ok=false; }
StringTokenizer st = new StringTokenizer(version, ",");
for (; st.hasMoreTokens();) { private boolean isDatabaseAndVersionOk(String p_database, String p_version, String database, String version) {
String m_version = st.nextToken(); boolean version_ok = false;
if (m_version.trim().equals(p_version)) StringTokenizer st = new StringTokenizer(version, ",");
version_ok=true; for (; st.hasMoreTokens();) {
} //loop String m_version = st.nextToken();
if (m_version.trim().equals(p_version))
return (database.indexOf(p_database) > -1 || database.equals("")) version_ok = true;
&& (version_ok || version.equals("")); } // loop
}
return (database.indexOf(p_database) > -1 || database.equals("")) && (version_ok || version.equals(""));
private void extractionScript(String name, String unl_file, String params, }
String database, String version, String p_database, String p_version) {
if (isDatabaseAndVersionOk(p_database, p_version, database, version)) { private void extractionScript(String name, String unl_file, String params, String database, String version,
//This is an sql-File whose result is to be unloaded String p_database, String p_version) {
String[] myArgs = new String[8]; if (isDatabaseAndVersionOk(p_database, p_version, database, version)) {
myArgs[0] = "-logger:" + logfile; //logfile // This is an sql-File whose result is to be unloaded
myArgs[1] = "-dbproperties:" + dbpropfile; //db.properties String[] myArgs = new String[8];
myArgs[0] = "-logger:" + logfile; // logfile
myArgs[2] = "-sqlfile:" + name; //_sql myArgs[1] = "-dbproperties:" + dbpropfile; // db.properties
myArgs[3] = "-outFormat:" + outformat; //outformat
myArgs[4] = "-delim:" + delim; //_delim myArgs[2] = "-sqlfile:" + name; // _sql
myArgs[5] = "-header:" + header; //header myArgs[3] = "-outFormat:" + outformat; // outformat
myArgs[6] = "-params:" + params; myArgs[4] = "-delim:" + delim; // _delim
if (unl_file.equals("")) { myArgs[5] = "-header:" + header; // header
if (outformat.equals("txt")) myArgs[6] = "-params:" + params;
myArgs[7] = "-outfile:" + name + ".unl"; //outfile if (unl_file.equals("")) {
else if (outformat.equals("txt"))
myArgs[7] = "-outfile:" + name + "." + outformat; myArgs[7] = "-outfile:" + name + ".unl"; // outfile
//outfile else
} else myArgs[7] = "-outfile:" + name + "." + outformat;
myArgs[7] = "-outfile:" + unl_file; // outfile
} else
try { myArgs[7] = "-outfile:" + unl_file;
de.superx.bin.Dosql.execute(myArgs);
} catch (Exception e) { try {
de.superx.bin.Dosql.execute(myArgs);
e.printStackTrace(); } catch (Exception e) {
}
logger.info("Executed sqlFile: " + name); e.printStackTrace();
} }
} logger.info("Executed sqlFile: " + name);
}
private void extractTable(String name, String unl_file, String database, }
String version, String p_database, String p_version) {
if (isDatabaseAndVersionOk(p_database, p_version, database, version)) { private void extractTable(String name, String unl_file, String database, String version, String p_database,
String[] myArgs = new String[7]; String p_version) {
myArgs[0] = logfile; //logfile if (isDatabaseAndVersionOk(p_database, p_version, database, version)) {
myArgs[1] = dbpropfile; //db.properties String[] myArgs = new String[7];
myArgs[0] = logfile; // logfile
myArgs[2] = "select * from " + name; //_sql myArgs[1] = dbpropfile; // db.properties
myArgs[3] = outformat; //outformat
myArgs[4] = delim; //_delim myArgs[2] = "select * from " + name; // _sql
myArgs[5] = header; //header myArgs[3] = outformat; // outformat
if (unl_file.equals("")) { myArgs[4] = delim; // _delim
if (outformat.equals("txt")) myArgs[5] = header; // header
myArgs[6] = name + ".unl"; //outfile if (unl_file.equals("")) {
else if (outformat.equals("txt"))
myArgs[6] = name + "." + outformat; //outfile myArgs[6] = name + ".unl"; // outfile
} else else
myArgs[6] = unl_file; myArgs[6] = name + "." + outformat; // outfile
} else
try { myArgs[6] = unl_file;
Doquery.go(myArgs);
} catch (FileNotFoundException e) { try {
Doquery.go(myArgs);
e.printStackTrace(); } catch (FileNotFoundException e) {
} catch (ClassNotFoundException e) {
e.printStackTrace();
e.printStackTrace(); } catch (ClassNotFoundException e) {
} catch (IOException e) {
e.printStackTrace();
e.printStackTrace(); } catch (IOException e) {
} catch (SQLException e) {
e.printStackTrace();
e.printStackTrace(); } catch (SQLException e) {
}
e.printStackTrace();
logger.info("Unloaded Table " + name); }
} //if database & version correct
logger.info("Unloaded Table " + name);
} } // if database & version correct
public static void main(String args[]) { }
try {
SxExtractor test = new SxExtractor(args); public static void main(String args[]) {
} catch (Exception ex) { try {
System.err.println("Exception caught.\n" + ex); SxExtractor test = new SxExtractor(args);
ex.printStackTrace(); } catch (Exception ex) {
} System.err.println("Fehler: " + ex);
} ex.printStackTrace();
}
private void severeEnd(String txt) { }
logger.severe(txt);
System.exit(-1);
}
} }

654
src/de/superx/bin/SxJasper.java

@ -1,25 +1,23 @@
package de.superx.bin; package de.superx.bin;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
import java.util.Locale; import java.util.Locale;
import org.w3c.dom.Document; import java.util.Map;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import org.w3c.dom.Document;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter; import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JRParameter; import net.sf.jasperreports.engine.JRParameter;
@ -32,8 +30,9 @@ import net.sf.jasperreports.engine.export.JRCsvExporter;
import net.sf.jasperreports.engine.export.JRRtfExporter; import net.sf.jasperreports.engine.export.JRRtfExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter; import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.query.JRXPathQueryExecuterFactory; import net.sf.jasperreports.engine.query.JRXPathQueryExecuterFactory;
import net.sf.jasperreports.engine.util.JRXmlUtils;
import net.sf.jasperreports.engine.util.JRLoader; import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.util.JRXmlUtils;
/** /**
* @author Daniel Quathamer Projektgruppe SuperX * @author Daniel Quathamer Projektgruppe SuperX
* *
@ -68,338 +67,329 @@ import net.sf.jasperreports.engine.util.JRLoader;
//Änderungen //Änderungen
public class SxJasper { public class SxJasper {
private static Connection myDb; private static Connection myDb;
private static Statement st; // Our statement to run queries with
private static DatabaseMetaData dbmd; private static Statement st; // Our statement to run queries with
// This defines the structure of the database
private static boolean done = false; // Added by CWJ to permit \q command private static DatabaseMetaData dbmd;
private static String taskName = "run";
private static String jrxmlFileName = ""; // This defines the structure of the database
private static String jasperFileName = ""; private static boolean done = false; // Added by CWJ to permit \q command
private static String jrprintFileName = "";
private static String XMLfileName = ""; private static String taskName = "run";
private static String XSLfileName = "";
private static String ignorePagination = ""; private static String jrxmlFileName = "";
private static String params = "";
private static String logfile = "../conf/logging.properties"; private static String jasperFileName = "";
private static String dbpropfile = "../conf/db.properties";
private static SxConnection myConnection = null; private static String jrprintFileName = "";
private static String db_driver;
private static String outfile = ""; private static String XMLfileName = "";
private static Logger logger =
(Logger) Logger.getLogger(SxJasper.class.toString()); private static String XSLfileName = "";
private static final String TASK_COMPILE = "compile";
private static final String TASK_FILL = "fill"; private static String ignorePagination = "";
private static final String TASK_PRINT = "print";
private static final String TASK_PDF = "pdf"; private static String params = "";
private static final String TASK_RTF = "rtf";
private static final String TASK_XML = "xml"; private static String logfile = "../conf/logging.properties";
private static final String TASK_XML_EMBED = "xmlEmbed";
private static final String TASK_HTML = "html"; private static String dbpropfile = "../conf/db.properties";
private static final String TASK_XLS = "xls";
private static final String TASK_JXL = "jxl"; private static SxConnection myConnection = null;
private static final String TASK_CSV = "csv";
private static final String TASK_RUN = "run"; private static String db_driver;
private static final String TASK_FILL_IGNORE_PAGINATION = "fillIgnorePagination";
private static String outfile = "";
private static String usage =
"-------------------------------------\nGebrauch: java de.superx.bin.SxJasper -logger=<<Pfad zu logging.properties>> -JRXML=<<jrxml-Datei>> -OUT=<<Ausgabedatei>>(optional) \n---------------------------------------------------"; private static Logger logger = (Logger) Logger.getLogger(SxJasper.class.toString());
/** private static final String TASK_COMPILE = "compile";
* @param args
* @throws ClassNotFoundException private static final String TASK_FILL = "fill";
* @throws FileNotFoundException
* @throws IOException private static final String TASK_PRINT = "print";
* @throws SQLException
*/ private static final String TASK_PDF = "pdf";
public static void go(String args[])
throws private static final String TASK_RTF = "rtf";
ClassNotFoundException,
FileNotFoundException, private static final String TASK_XML = "xml";
IOException,
SQLException { private static final String TASK_XML_EMBED = "xmlEmbed";
if (args.length== 0) {
throw new IllegalArgumentException("Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, outfile) erfoderlich"); private static final String TASK_HTML = "html";
} private static final String TASK_XLS = "xls";
GetOpts.setOpts(args);
String isdrin = GetOpts.isAllRequiredOptionsPresent("-logger,-JRXML"); private static final String TASK_JXL = "jxl";
if (isdrin != null) {
System.err.println("Folgende Optionen fehlen: " + isdrin); private static final String TASK_CSV = "csv";
System.err.println(usage);
System.exit(1); private static final String TASK_RUN = "run";
}
if (GetOpts.isPresent("-logger")) private static final String TASK_FILL_IGNORE_PAGINATION = "fillIgnorePagination";
logfile = GetOpts.getValue("-logger");
if (GetOpts.isPresent("-JRXML")) private static String usage = "-------------------------------------\nGebrauch: java de.superx.bin.SxJasper -logger=<<Pfad zu logging.properties>> -JRXML=<<jrxml-Datei>> -OUT=<<Ausgabedatei>>(optional) \n---------------------------------------------------";
jrxmlFileName = GetOpts.getValue("-JRXML");
if (GetOpts.isPresent("-JASPER")) /**
jasperFileName = GetOpts.getValue("-JASPER"); * @param args
else * @throws ClassNotFoundException
jasperFileName=de.memtext.util.FileUtils.getFileNameWithoutSuffix(jrxmlFileName)+".jasper"; * @throws FileNotFoundException
if (GetOpts.isPresent("-JRPRINT")) * @throws IOException
jrprintFileName = GetOpts.getValue("-JRPRINT"); * @throws SQLException
*/
public static void go(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException {
if (args.length == 0) {
throw new IllegalArgumentException("Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, outfile) erfoderlich");
}
GetOpts.setOpts(args);
String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[] {Options.opt_logger,Options.opt_dbprops,Options.opt_jrxml});
if (isdrin != null) {
System.err.println("Folgende Optionen fehlen: " + isdrin);
System.err.println(usage);
System.exit(1);
}
if (GetOpts.isPresent(Options.opt_logger)) logfile = GetOpts.getValue(Options.opt_logger);
if (GetOpts.isPresent(Options.opt_jrxml)) jrxmlFileName = GetOpts.getValue(Options.opt_jrxml);
if (GetOpts.isPresent(Options.opt_jasper))
jasperFileName = GetOpts.getValue(Options.opt_jasper);
else else
jrprintFileName=de.memtext.util.FileUtils.getFileNameWithoutSuffix(jrxmlFileName)+".jrprint"; jasperFileName = de.memtext.util.FileUtils.getFileNameWithoutSuffix(jrxmlFileName) + ".jasper";
if (GetOpts.isPresent("-XML")) if (GetOpts.isPresent(Options.opt_jrPrint))
XMLfileName = GetOpts.getValue("-XML"); jrprintFileName = GetOpts.getValue(Options.opt_jrPrint);
if (GetOpts.isPresent("-IGNORE_PAGINATION")) else
ignorePagination = GetOpts.getValue("-IGNORE_PAGINATION"); jrprintFileName = de.memtext.util.FileUtils.getFileNameWithoutSuffix(jrxmlFileName) + ".jrprint";
if (GetOpts.isPresent("-XSL")) if (GetOpts.isPresent(Options.opt_xml)) XMLfileName = GetOpts.getValue(Options.opt_xml);
XSLfileName = GetOpts.getValue("-XSL"); if (GetOpts.isPresent(Options.opt_ignorePagination)) ignorePagination = GetOpts.getValue(Options.opt_ignorePagination);
if (GetOpts.isPresent("-OUT")) if (GetOpts.isPresent(Options.opt_xsl)) XSLfileName = GetOpts.getValue(Options.opt_xsl);
outfile = GetOpts.getValue("-OUT"); if (GetOpts.isPresent(Options.opt_out))
if (GetOpts.isPresent("-db_properties")) outfile = GetOpts.getValue(Options.opt_out);
dbpropfile = GetOpts.getValue("-db_properties"); if (GetOpts.isPresent(Options.opt_dbprops)) dbpropfile = GetOpts.getValue(Options.opt_dbprops);
if (GetOpts.isPresent("-param")) if (GetOpts.isPresent(Options.opt_param)) params = GetOpts.getValue(Options.opt_param);
params = GetOpts.getValue("-param");
File f = new File(logfile);
File f = new File(logfile); if (!f.exists()) {
if (!f.exists()) { throw new IOException("Datei nicht gefunden: " + logfile);
throw new IOException("Datei nicht gefunden: " + logfile); }
}
FileInputStream ins = new FileInputStream(logfile);
FileInputStream ins = new FileInputStream(logfile); LogManager MyLogManager = java.util.logging.LogManager.getLogManager();
LogManager MyLogManager = java.util.logging.LogManager.getLogManager(); MyLogManager.readConfiguration(ins);
MyLogManager.readConfiguration(ins); logfile = MyLogManager.getProperty(".level");
logfile = MyLogManager.getProperty(".level"); logger.info("Using Loggging-Level " + logfile);
logger.info("Using Loggging-Level " + logfile); try {
try long start = System.currentTimeMillis();
{ if (!jrxmlFileName.equals("")) {
long start = System.currentTimeMillis(); if (jasperFileName.equals(""))
if (!jrxmlFileName.equals("")) jasperFileName = JasperCompileManager.compileReportToFile(jrxmlFileName);
{ else
if (jasperFileName.equals("")) JasperCompileManager.compileReportToFile(jrxmlFileName, jasperFileName);
jasperFileName=JasperCompileManager.compileReportToFile(jrxmlFileName); logger.info("Compile time : " + (System.currentTimeMillis() - start));
else }
JasperCompileManager.compileReportToFile(jrxmlFileName,jasperFileName);
logger.info("Compile time : " + (System.currentTimeMillis() - start));
}
if (!jasperFileName.equals("") && if (!jasperFileName.equals("") &&
(GetOpts.isPresent("-db_properties") || GetOpts.isPresent("-XML") ) (GetOpts.isPresent(Options.opt_dbprops) || GetOpts.isPresent(Options.opt_xml) )
) )
{ {
logger.info("Filling " + jasperFileName); logger.info("Filling " + jasperFileName);
//Preparing parameters
Map parameters = new HashMap();
if(!XMLfileName.equals(""))
{
logger.info("XML-Source " + XMLfileName);
Document document = JRXmlUtils.parse(new File(XMLfileName));
parameters.put(JRXPathQueryExecuterFactory.PARAMETER_XML_DATA_DOCUMENT, document);
parameters.put(JRXPathQueryExecuterFactory.XML_DATE_PATTERN, "dd.MM.yyyy HH:mm:ss");
parameters.put(JRXPathQueryExecuterFactory.XML_NUMBER_PATTERN, "###0.00;-###0.00");
parameters.put(JRXPathQueryExecuterFactory.XML_LOCALE, Locale.GERMAN);
parameters.put(JRParameter.REPORT_LOCALE, Locale.GERMAN);
}
else
getConnection(logger, dbpropfile);
//parameters.put("ReportTitle", "Rektorenliste");
//parameters.put("FilterClause", "'Boston', 'Chicago', 'Oslo'");
//parameters.put("OrderClause", "City");
if (ignorePagination.equals("true"))
{
parameters.put(JRParameter.IS_IGNORE_PAGINATION, Boolean.TRUE);
}
if (jrprintFileName.equals(""))
jrprintFileName=JasperFillManager.fillReportToFile(jasperFileName, parameters, myDb);
else
JasperFillManager.fillReportToFile(jasperFileName, jrprintFileName, parameters, myDb);
logger.info("Filling time : " + (System.currentTimeMillis() - start));
}
if (outfile.endsWith(".prn"))
{
JasperPrintManager.printReport(jrprintFileName, true);
logger.info("Printing time : " + (System.currentTimeMillis() - start));
System.exit(0);
}
if (outfile.endsWith(".pdf"))
{
JasperExportManager.exportReportToPdfFile(jrprintFileName,outfile);
logger.info("PDF creation time : " + (System.currentTimeMillis() - start));
System.exit(0);
}
if (outfile.endsWith(".rtf"))
{
File sourceFile = new File(jrprintFileName);
JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
File destFile = new File(sourceFile.getParent(), outfile);
JRRtfExporter exporter = new JRRtfExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, destFile.toString());
exporter.exportReport();
logger.info("RTF creation time : " + (System.currentTimeMillis() - start));
System.exit(0);
}
if (outfile.endsWith(".xml"))
{
JasperExportManager.exportReportToXmlFile(jrprintFileName,outfile, false);
logger.info("XML creation time : " + (System.currentTimeMillis() - start));
System.exit(0);
}
/*else if (TASK_XML_EMBED.equals(taskName))
{
if(outfile.equals(""))
outfile=jrxmlFileName + ".xml";
JasperExportManager.exportReportToXmlFile(jrprintFileName,outfile, true);
logger.info("XML creation time : " + (System.currentTimeMillis() - start));
System.exit(0);
}*/
if (outfile.endsWith(".htm") || outfile.endsWith(".html"))
{
JasperExportManager.exportReportToHtmlFile(jrprintFileName,outfile);
logger.info("HTML creation time : " + (System.currentTimeMillis() - start));
System.exit(0);
}
if (outfile.endsWith(".xls"))
{
File sourceFile = new File(jrprintFileName);
JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
File destFile = new File(sourceFile.getParent(), outfile);
JRXlsExporter exporter = new JRXlsExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, destFile.toString());
//exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
exporter.exportReport();
logger.info("XLS creation time : " + (System.currentTimeMillis() - start));
System.exit(0);
}
/* else if (TASK_JXL.equals(taskName))
{
File sourceFile = new File(jrprintFileName);
JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile); //Preparing parameters
if(outfile.equals("")) Map parameters = new HashMap();
outfile=jasperPrint.getName() + ".jxl.xls"; if (!XMLfileName.equals("")) {
logger.info("XML-Source " + XMLfileName);
File destFile = new File(sourceFile.getParent(), outfile); Document document = JRXmlUtils.parse(new File(XMLfileName));
parameters.put(JRXPathQueryExecuterFactory.PARAMETER_XML_DATA_DOCUMENT, document);
parameters.put(JRXPathQueryExecuterFactory.XML_DATE_PATTERN, "dd.MM.yyyy HH:mm:ss");
parameters.put(JRXPathQueryExecuterFactory.XML_NUMBER_PATTERN, "###0.00;-###0.00");
parameters.put(JRXPathQueryExecuterFactory.XML_LOCALE, Locale.GERMAN);
parameters.put(JRParameter.REPORT_LOCALE, Locale.GERMAN);
} else
getConnection(logger, dbpropfile);
JExcelApiExporter exporter = new JExcelApiExporter(); //parameters.put("ReportTitle", "Rektorenliste");
//parameters.put("FilterClause", "'Boston', 'Chicago', 'Oslo'");
//parameters.put("OrderClause", "City");
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); if (ignorePagination.equals("true")) {
exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, destFile.toString()); parameters.put(JRParameter.IS_IGNORE_PAGINATION, Boolean.TRUE);
exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.TRUE); }
exporter.exportReport(); if (jrprintFileName.equals(""))
jrprintFileName = JasperFillManager.fillReportToFile(jasperFileName, parameters, myDb);
else
JasperFillManager.fillReportToFile(jasperFileName, jrprintFileName, parameters, myDb);
logger.info("XLS creation time : " + (System.currentTimeMillis() - start)); logger.info("Filling time : " + (System.currentTimeMillis() - start));
System.exit(0);
}*/ }
if (outfile.endsWith(".csv")) if (outfile.endsWith(".prn")) {
{ JasperPrintManager.printReport(jrprintFileName, true);
File sourceFile = new File(jrprintFileName); logger.info("Printing time : " + (System.currentTimeMillis() - start));
System.exit(0);
JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile); }
File destFile = new File(sourceFile.getParent(), outfile); if (outfile.endsWith(".pdf")) {
JasperExportManager.exportReportToPdfFile(jrprintFileName, outfile);
JRCsvExporter exporter = new JRCsvExporter(); logger.info("PDF creation time : " + (System.currentTimeMillis() - start));
System.exit(0);
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); }
exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, destFile.toString()); if (outfile.endsWith(".rtf")) {
File sourceFile = new File(jrprintFileName);
exporter.exportReport();
JasperPrint jasperPrint = (JasperPrint) JRLoader.loadObject(sourceFile);
logger.info("CSV creation time : " + (System.currentTimeMillis() - start)); File destFile = new File(sourceFile.getParent(), outfile);
System.exit(0);
} JRRtfExporter exporter = new JRRtfExporter();
/*else if (TASK_RUN.equals(taskName))
{ exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
//Preparing parameters exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, destFile.toString());
Map parameters = new HashMap();
//parameters.put("ReportTitle", "Address Report"); exporter.exportReport();
//parameters.put("FilterClause", "'Boston', 'Chicago'");
//parameters.put("OrderClause", "City"); logger.info("RTF creation time : " + (System.currentTimeMillis() - start));
if(outfile.equals("")) System.exit(0);
outfile=jrxmlFileName+".pdf"; }
getConnection(logger, dbpropfile); if (outfile.endsWith(".xml")) {
JasperRunManager.runReportToPdfFile(jrxmlFileName+".jasper",outfile, parameters, myDb); JasperExportManager.exportReportToXmlFile(jrprintFileName, outfile, false);
logger.info("PDF running time : " + (System.currentTimeMillis() - start)); logger.info("XML creation time : " + (System.currentTimeMillis() - start));
System.exit(0); System.exit(0);
}*/ }
} /*else if (TASK_XML_EMBED.equals(taskName))
catch (JRException e) {
{ if(outfile.equals(""))
e.printStackTrace(); outfile=jrxmlFileName + ".xml";
System.exit(1); JasperExportManager.exportReportToXmlFile(jrprintFileName,outfile, true);
} logger.info("XML creation time : " + (System.currentTimeMillis() - start));
catch (Exception e) System.exit(0);
{ }*/
e.printStackTrace(); if (outfile.endsWith(".htm") || outfile.endsWith(".html")) {
System.exit(1); JasperExportManager.exportReportToHtmlFile(jrprintFileName, outfile);
} logger.info("HTML creation time : " + (System.currentTimeMillis() - start));
//getConnection(logger, dbpropfile); System.exit(0);
}
if (outfile.endsWith(".xls")) {
logger.info("SxJasper erfolgreich beendet"); File sourceFile = new File(jrprintFileName);
} JasperPrint jasperPrint = (JasperPrint) JRLoader.loadObject(sourceFile);
/* File destFile = new File(sourceFile.getParent(), outfile);
* Display some instructions on how to run the example
*/ JRXlsExporter exporter = new JRXlsExporter();
public static void instructions() {
System.out.println("SuperX @version@\n"); exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
System.out.println( exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, destFile.toString());
"\nDieses Java-Programm führt einen SQL-Ausdruck aus und gibt das Ergebnis aus.\n"); //exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
System.out.println(
"Gebrauch:\n java doquery <Pfad zu logger-properties> <pfad zu db.properties> <sql-Ausdruck> <Ausgabeformat (txt | html | xml)>(optional) <delimiter> <mit Spaltenüberschriften (true | false)>(optional) <Ausgabedatei>(optional)\n"); exporter.exportReport();
System.exit(1);
} logger.info("XLS creation time : " + (System.currentTimeMillis() - start));
System.exit(0);
public static void main(String args[]) { }
//args=new String[7]; /* else if (TASK_JXL.equals(taskName))
//args[0]="e:\\superx\\logging.properties"; {
//args[1]="e:/superx/db.properties"; File sourceFile = new File(jrprintFileName);
//args[2]="select * from sos_stud_allg_cube";; ;
//args[3]="txt"; JasperPrint jasperPrint = (JasperPrint)JRLoader.loadObject(sourceFile);
//args[4]="^"; if(outfile.equals(""))
//args[5]="false"; outfile=jasperPrint.getName() + ".jxl.xls";
//args[6]="e:/superx/test.unl";
try { File destFile = new File(sourceFile.getParent(), outfile);
go(args);
} catch (Exception ex) { JExcelApiExporter exporter = new JExcelApiExporter();
System.err.println("SxJasper Aufruf fehlgeschlagen.\n" + ex);
ex.printStackTrace(); exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
System.exit(1); exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, destFile.toString());
} exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.TRUE);
}
public static void getConnection(Logger logger,String propFile) throws SQLException { exporter.exportReport();
myConnection = new SxConnection();
myConnection.setPropfile(propFile); logger.info("XLS creation time : " + (System.currentTimeMillis() - start));
logger.config("Starting Connection..."); System.exit(0);
try { }*/
myDb = myConnection.getConnection(); if (outfile.endsWith(".csv")) {
st = myDb.createStatement(); File sourceFile = new File(jrprintFileName);
//st = myDb.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
// java.sql.ResultSet.CONCUR_READ_ONLY); JasperPrint jasperPrint = (JasperPrint) JRLoader.loadObject(sourceFile);
//st.setFetchSize(100); File destFile = new File(sourceFile.getParent(), outfile);
dbmd = myDb.getMetaData();
//st = myDb.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, JRCsvExporter exporter = new JRCsvExporter();
//ResultSet.CONCUR_UPDATABLE);
} catch (Exception e) { exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
logger.severe("Keine DB-Verbindung: " + e.toString()); exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, destFile.toString());
throw new SQLException("Keine DB-Verbindung: " + e.toString());
} exporter.exportReport();
db_driver = myConnection.m_DriverClass;
logger.info("CSV creation time : " + (System.currentTimeMillis() - start));
} System.exit(0);
}
/*else if (TASK_RUN.equals(taskName))
{
//Preparing parameters
Map parameters = new HashMap();
//parameters.put("ReportTitle", "Address Report");
//parameters.put("FilterClause", "'Boston', 'Chicago'");
//parameters.put("OrderClause", "City");
if(outfile.equals(""))
outfile=jrxmlFileName+".pdf";
getConnection(logger, dbpropfile);
JasperRunManager.runReportToPdfFile(jrxmlFileName+".jasper",outfile, parameters, myDb);
logger.info("PDF running time : " + (System.currentTimeMillis() - start));
System.exit(0);
}*/
} catch (JRException e) {
e.printStackTrace();
System.exit(1);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
//getConnection(logger, dbpropfile);
logger.info("SxJasper erfolgreich beendet");
}
/*
* Display some instructions on how to run the example
*/
public static void instructions() {
System.out.println("SuperX @version@\n");
System.out.println("\nDieses Java-Programm führt einen SQL-Ausdruck aus und gibt das Ergebnis aus.\n");
System.out.println("Gebrauch:\n java doquery <Pfad zu logger-properties> <pfad zu db.properties> <sql-Ausdruck> <Ausgabeformat (txt | html | xml)>(optional) <delimiter> <mit Spaltenüberschriften (true | false)>(optional) <Ausgabedatei>(optional)\n");
System.exit(1);
}
public static void main(String args[]) {
try {
go(args);
} catch (Exception ex) {
System.err.println("Doquery Aufruf fehlgeschlagen.\n" + ex);
ex.printStackTrace();
System.exit(1);
}
}
public static void getConnection(Logger logger, String propFile) throws SQLException {
myConnection = new SxConnection();
myConnection.setPropfile(propFile);
logger.config("Starting Connection...");
try {
myDb = myConnection.getConnection();
st = myDb.createStatement();
//st = myDb.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
// java.sql.ResultSet.CONCUR_READ_ONLY);
//st.setFetchSize(100);
dbmd = myDb.getMetaData();
//st = myDb.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
//ResultSet.CONCUR_UPDATABLE);
} catch (Exception e) {
logger.severe("Keine DB-Verbindung: " + e.toString());
throw new SQLException("Keine DB-Verbindung: " + e.toString());
}
db_driver = myConnection.m_DriverClass.stringValue();
}
} }

2149
src/de/superx/bin/SxJdbcClient.java

File diff suppressed because it is too large Load Diff

156
src/de/superx/bin/SxTestXmlCreator.java

@ -1,79 +1,77 @@
package de.superx.bin; package de.superx.bin;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import org.xml.sax.SAXException; import org.apache.commons.io.FileUtils;
import org.xml.sax.SAXException;
import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.WebConversation; import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.WebRequest; import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebResponse; import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebTable; import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebTable;
import de.memtext.util.StringUtils;
import de.memtext.util.StringUtils;
public class SxTestXmlCreator {
public static void main(String args[]) { public class SxTestXmlCreator {
public static void main(String args[]) {
if (args.length != 1) {
System.out.println("usage SxTestXmlCreator filename (which contains url or sql)"); if (args.length != 1) {
System.exit(-1); System.out.println("usage SxTestXmlCreator filename (which contains url or sql)");
} System.exit(-1);
try { }
File f=new File(args[0]); try {
createTestXml(f); File f = new File(args[0]);
} catch (Exception e) { createTestXml(f);
System.out.println(e); } catch (Exception e) {
} System.out.println(e);
} }
}
private static void createTestXml(File f) throws MalformedURLException,
IOException, SAXException { private static void createTestXml(File f) throws MalformedURLException, IOException, SAXException {
String input=StringUtils.readFile(f); String input = StringUtils.readFile(f);
//if (input.startsWith("http")) //if (input.startsWith("http"))
String url=input; String url = input;
WebConversation wc = new WebConversation(); WebConversation wc = new WebConversation();
WebRequest req = new GetMethodWebRequest(url); WebRequest req = new GetMethodWebRequest(url);
WebResponse resp = wc.getResponse(req); WebResponse resp = wc.getResponse(req);
if (resp.getTables().length == 0) { if (resp.getTables().length == 0) {
System.out.println("Keine Tabelle geliefert\n" + resp.getText()); System.out.println("Keine Tabelle geliefert\n" + resp.getText());
System.exit(1); System.exit(1);
} }
WebTable table = resp.getTables()[1]; WebTable table = resp.getTables()[1];
String params=url.substring(url.indexOf("?")+1); String params = url.substring(url.indexOf("?") + 1);
params=params.trim(); params = params.trim();
if (params.charAt(params.length()-1)=='\n') params=params.substring(0,params.length()-2); if (params.charAt(params.length() - 1) == '\n') params = params.substring(0, params.length() - 2);
StringBuffer erg = new StringBuffer( StringBuffer erg = new StringBuffer("<webtest name=\"\">\n <params><![CDATA[" + params + "]]></params>\n");
"<webtest name=\"\">\n <params><![CDATA[" + params + "]]></params>\n"); for (int col = 0; col < table.getColumnCount(); col++) {
for (int col = 0; col < table.getColumnCount(); col++) { for (int row = 0; row < table.getRowCount(); row++) {
for (int row = 0; row < table.getRowCount(); row++) { String val = table.getTableCell(row, col).getText();
String val = table.getTableCell(row, col).getText(); //wenn \n vorkommt test auskommentieren
//wenn \n vorkommt test auskommentieren if (val.indexOf("\n") > -1) erg.append("<!-- ");
if (val.indexOf("\n")> -1) erg.append("<!-- "); erg.append("<valuetest row=\"" + (row + 1) + "\" col=\"" + (col + 1) + "\" val=\"" + val + "\"/>\n");
erg.append("<valuetest row=\"" + (row + 1) + "\" col=\"" if (val.indexOf("\n") > -1) erg.append(" -->");
+ (col + 1) + "\" val=\"" + val + "\"/>\n"); }
if (val.indexOf("\n")> -1) erg.append(" -->"); }
}
} erg.append("</webtest>\n");
erg.append("</webtest>\n");
FileUtils.writeStringToFile(new File("temp.xml"), erg.toString());
System.out.println("XML ist in temp.xml");
StringUtils.write(new File("temp.xml"),erg.toString()); }
System.out.println("XML ist in temp.xml");
} }
} //Created on 27.04.2006 at 14:47:18
//Created on 27.04.2006 at 14:47:18

11
src/de/superx/bin/SxTransformer.java

@ -22,12 +22,12 @@ import java.util.logging.Logger;
import javax.xml.transform.Result; import javax.xml.transform.Result;
import javax.xml.transform.Source; import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver; import javax.xml.transform.URIResolver;
import javax.xml.transform.sax.SAXResult; import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource; import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.Transformer;
import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop; import org.apache.fop.apps.Fop;
@ -90,6 +90,8 @@ public class SxTransformer {
public String params = ""; public String params = "";
public String[] XslPipeline; public String[] XslPipeline;
public String mandantenID;
public String stylesheet = ""; public String stylesheet = "";
@ -108,7 +110,7 @@ public class SxTransformer {
public void setFopxconfFile(File fopxconfFile) { public void setFopxconfFile(File fopxconfFile) {
this.fopxconfFile = fopxconfFile; this.fopxconfFile = fopxconfFile;
} }
public String mandantenID;
Logger myLogger; Logger myLogger;
String loglevel; String loglevel;
@ -334,11 +336,7 @@ public class SxTransformer {
public void transformFile(String methode) throws TransformerException, Exception public void transformFile(String methode) throws TransformerException, Exception
{ {
/*javax.xml.transform.TransformerFactory tFactory = javax.xml.transform.TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", null);
javax.xml.transform.Transformer transformer = tFactory.newTransformer(new javax.xml.transform.stream.StreamSource(this.stylesheet));*/
Transformer transformer = TransletCache.getTransformer(this.mandantenID, this.stylesheet); Transformer transformer = TransletCache.getTransformer(this.mandantenID, this.stylesheet);
//StringReader s1 = new StringReader(quellstring);
transformer.setOutputProperty(javax.xml.transform.OutputKeys.ENCODING, SqlStringUtils.getEncoding()); transformer.setOutputProperty(javax.xml.transform.OutputKeys.ENCODING, SqlStringUtils.getEncoding());
if (methode.equals("pdf") || methode.equals("rtf")) if (methode.equals("pdf") || methode.equals("rtf"))
transformer.setOutputProperty(javax.xml.transform.OutputKeys.METHOD, "xml"); transformer.setOutputProperty(javax.xml.transform.OutputKeys.METHOD, "xml");
@ -883,6 +881,7 @@ public class SxTransformer {
public class ClasspathUriResolver implements URIResolver { public class ClasspathUriResolver implements URIResolver {
@Override
public Source resolve(String href, String base) throws TransformerException { public Source resolve(String href, String base) throws TransformerException {
Source source = null; Source source = null;
InputStream inputStream = ClassLoader.getSystemResourceAsStream(href); InputStream inputStream = ClassLoader.getSystemResourceAsStream(href);

545
src/de/superx/bin/SxValidate.java

@ -1,284 +1,261 @@
package de.superx.bin; package de.superx.bin;
/* /*
* Copyright 1999-2004 The Apache Software Foundation. * Copyright 1999-2004 The Apache Software Foundation.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/*
* $Id: Validate.java,v 1.5 2004/02/17 19:11:45 minchau Exp $ /*
* * $Id: Validate.java,v 1.5 2004/02/17 19:11:45 minchau Exp $
* Erweitert für SuperX von Daniel Quathamer *
* 16.11.2006 * Erweitert für SuperX von Daniel Quathamer
*/ * 16.11.2006
*/
import java.io.File;
import java.io.FileInputStream; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileInputStream;
import java.io.FilenameFilter; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.FilenameFilter;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException; import org.xml.sax.SAXException;
import org.xml.sax.XMLReader; import org.xml.sax.SAXParseException;
import org.xml.sax.ext.LexicalHandler; import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.DefaultHandler;
/* Use JAXP SAXParser to parse 1 .xml file or all the .xml files in a directory.
* Takes 1 or 2 command-line arguments: /* Use JAXP SAXParser to parse 1 .xml file or all the .xml files in a directory.
* Argument 1 (required) is a file name or directory name. * Takes 1 or 2 command-line arguments:
* Argument 2 (optional) is a log file name. If ommitted, messages are written to screen. * Argument 1 (required) is a file name or directory name.
*/ * Argument 2 (optional) is a log file name. If ommitted, messages are written to screen.
public class SxValidate */
{ public class SxValidate {
static int numXMLFiles = 0; static int numXMLFiles = 0;
static int numValidFiles = 0;
static int numInvalidFiles = 0; static int numValidFiles = 0;
static int numFilesMissingDoctype = 0;
static int numMalformedFiles = 0; static int numInvalidFiles = 0;
static boolean useSchema = false;
static StringBuffer buff = new StringBuffer(); static int numFilesMissingDoctype = 0;
public static void main(String[] args) static int numMalformedFiles = 0;
throws FileNotFoundException, IOException, ParserConfigurationException, SAXException
{ static boolean useSchema = false;
if (args.length == 0 || args.length > 2)
{ static StringBuffer buff = new StringBuffer();
System.out.println("\nGeben Sie 'sx_validate.x -help' für Information über SxValidate");
System.exit(1); public static void main(String[] args) throws FileNotFoundException, IOException, ParserConfigurationException, SAXException {
} if (args.length == 0 || args.length > 2) {
if (args[0].toLowerCase().equals("-help")) System.out.println("\nGeben Sie 'sx_validate.x -help' für Information über SxValidate");
{ return;
String sep = "\n====================================================\n"; }
String a = "sx_validate <Datei oder Pfad> [SCHEMA] \nValidate nutzt Xerces um einen einzelnen XML-File zu validieren bzw. die xml Files in dem Verzeichnis das Sie spezifizieren. Der Parser validiert jedes Dokument (Konformität zum DOCTYPE oder XMLSchema).\n"; if (args[0].toLowerCase().equals("-help")) {
String b = "Jede xml Datei sollte eine DOCTYPE declaration oder einen XMLSchema-Verweis enthalten.\n\n"; String sep = "\n====================================================\n";
String c = "SxValidate nimmt 1 oder 2 Argumente:\n"; String a = "sx_validate <Datei oder Pfad> [SCHEMA] \nValidate nutzt Xerces um einen einzelnen XML-File zu validieren bzw. die xml Files in dem Verzeichnis das Sie spezifizieren. Der Parser validiert jedes Dokument (Konformität zum DOCTYPE oder XMLSchema).\n";
String d = " Argument 1 spezifiziert das Verzeichnis oder die Datei.\n"; String b = "Jede xml Datei sollte eine DOCTYPE declaration oder einen XMLSchema-Verweis enthalten.\n\n";
String e = " Argument 2 (einfach 'SCHEMA') spezifiziert, ob nach XML-Schema validiert werden soll.\n"; String c = "SxValidate nimmt 1 oder 2 Argumente:\n";
System.out.println(sep+a+b+c+d+e+sep); String d = " Argument 1 spezifiziert das Verzeichnis oder die Datei.\n";
return; String e = " Argument 2 (einfach 'SCHEMA') spezifiziert, ob nach XML-Schema validiert werden soll.\n";
} System.out.println(sep + a + b + c + d + e + sep);
try return;
{ }
SxValidate v = new SxValidate(); try {
v.validate(args); SxValidate v = new SxValidate();
System.exit(0); v.validate(args);
} } catch (Exception e) {
catch (Exception e) e.printStackTrace();
{ }
e.printStackTrace(); }
System.exit(1);
} void validate(String[] args) throws FileNotFoundException, IOException, ParserConfigurationException, SAXException {
} File dir = new File(args[0]);
void validate(String[] args) // User may include a 2nd argument for the validation method
throws Exception
{ useSchema = false;
File dir = new File(args[0]); if (args.length == 2 && args[1].equalsIgnoreCase("SCHEMA")) useSchema = true;
// User may include a 2nd argument for the validation method if (dir.isFile()) // Just checking one file.
{
useSchema = false; parse(null, args[0], useSchema);
if(args.length == 2 && args[1].equalsIgnoreCase("SCHEMA")) } else if (dir.isDirectory()) // Checking the contents of a directory.
useSchema=true; {
// Only interested in .xml files.
if (dir.isFile()) // Just checking one file. XMLFileFilter filter = new XMLFileFilter();
{ String[] files = dir.list(filter);
parse(null,args[0],useSchema); for (int i = 0; i < files.length; i++) {
} parse(dir.toString(), files[i], useSchema); // All the work is done here.
else if (dir.isDirectory()) // Checking the contents of a directory.
{ System.out.print(buff.toString());
// Only interested in .xml files. buff = new StringBuffer();
XMLFileFilter filter = new XMLFileFilter();
String [] files = dir.list(filter); }
for (int i = 0; i <files.length; i++) } else // Command-line argument is no good!
{ {
parse(dir.toString(),files[i],useSchema); // All the work is done here. System.out.println(args[0] + " not found!");
return;
System.out.print(buff.toString()); }
buff = new StringBuffer(); // Provide user with a summary.
buff.append("================SUMMARY=============================\n");
} if (numXMLFiles > 1) buff.append("Parsed " + numXMLFiles + " .xml files in " + args[0] + ".\n");
} if (numValidFiles > 1)
else // Command-line argument is no good! buff.append(numValidFiles + " files are valid.\n");
{ else if (numValidFiles == 1) buff.append(numValidFiles + " file is valid.\n");
System.out.println(args[0] + " not found!"); if (numInvalidFiles > 1)
System.exit(1); buff.append(numInvalidFiles + " files are not valid.\n");
} else if (numInvalidFiles == 1) buff.append(numInvalidFiles + " file is not valid.\n");
// Provide user with a summary. if (numMalformedFiles > 1)
buff.append("================SUMMARY=============================\n"); buff.append(numMalformedFiles + " files are not well-formed.\n");
if (numXMLFiles > 1) else if (numMalformedFiles == 1) buff.append(numMalformedFiles + " file is not well-formed.\n");
buff.append("Parsed " + numXMLFiles + " .xml files in " + args[0] + ".\n"); if (numFilesMissingDoctype > 1)
if (numValidFiles > 1) buff.append(numFilesMissingDoctype + " files do not contain a DOCTYPE declaration.\n");
buff.append( numValidFiles + " files are valid.\n"); else if (numFilesMissingDoctype == 1) buff.append(numFilesMissingDoctype + " file does not contain a DOCTYPE declaration.\n");
else if (numValidFiles == 1)
buff.append( numValidFiles + " file is valid.\n"); System.out.print(buff.toString());
if (numInvalidFiles > 1)
buff.append(numInvalidFiles + " files are not valid.\n"); }
else if (numInvalidFiles == 1)
buff.append( numInvalidFiles + " file is not valid.\n"); // Parse each XML file.
if (numMalformedFiles > 1) void parse(String dir, String filename, boolean useSchema) throws FileNotFoundException, IOException, ParserConfigurationException, SAXException {
buff.append(numMalformedFiles + " files are not well-formed.\n"); try {
else if (numMalformedFiles == 1) File f = new File(dir, filename);
buff.append( numMalformedFiles + " file is not well-formed.\n"); StringBuffer errorBuff = new StringBuffer();
if (numFilesMissingDoctype > 1) InputSource input = new InputSource(new FileInputStream(f));
buff.append(numFilesMissingDoctype + " files do not contain a DOCTYPE declaration.\n"); // Set systemID so parser can find the dtd with a relative URL in the source document.
else if (numFilesMissingDoctype == 1) input.setSystemId(f.toString());
buff.append(numFilesMissingDoctype + " file does not contain a DOCTYPE declaration.\n");
SAXParserFactory spfact = SAXParserFactory.newInstance();
System.out.print(buff.toString());
spfact.setValidating(true);
} spfact.setNamespaceAware(true);
// Parse each XML file. SAXParser parser = spfact.newSAXParser();
void parse(String dir, String filename,boolean useSchema) XMLReader reader = parser.getXMLReader();
throws Exception
{ //Instantiate inner-class error and lexical handler.
try Handler handler = new Handler(filename, errorBuff);
{ reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
File f = new File(dir, filename); if (useSchema) {
StringBuffer errorBuff = new StringBuffer(); parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
InputSource input = new InputSource(new FileInputStream(f)); buff.append("Nutze XML-Schema Validierung\n");
// Set systemID so parser can find the dtd with a relative URL in the source document. }
input.setSystemId(f.toString()); parser.parse(input, handler);
if (handler.containsDTD && !handler.errorOrWarning) // valid
SAXParserFactory spfact = SAXParserFactory.newInstance(); {
buff.append("VALID " + filename + "\n");
spfact.setValidating(true); numValidFiles++;
spfact.setNamespaceAware(true); } else if (handler.containsDTD) // not valid
{
SAXParser parser = spfact.newSAXParser(); buff.append("NOT VALID " + filename + "\n");
XMLReader reader = parser.getXMLReader(); buff.append(errorBuff.toString());
numInvalidFiles++;
//Instantiate inner-class error and lexical handler. } else // no DOCTYPE to use for validation
Handler handler = new Handler(filename, errorBuff); {
reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler); if (handler.errorOrWarning) {
if(useSchema) buff.append("Datei " + filename + " wurde validiert:\n" + errorBuff.toString());
{ numInvalidFiles++;
parser.setProperty( } else {
"http://java.sun.com/xml/jaxp/properties/schemaLanguage", buff.append("Datei " + filename + " wurde validiert:\n" + errorBuff.toString());
"http://www.w3.org/2001/XMLSchema"); numValidFiles++;
buff.append("Nutze XML-Schema Validierung\n");
} }
parser.parse(input, handler);
if (handler.containsDTD && !handler.errorOrWarning) // valid }
{ } catch (Exception e) // Serious problem!
buff.append("VALID " + filename +"\n"); {
numValidFiles++; buff.append("NOT WELL-FORMED " + filename + ". " + e.getMessage() + "\n");
} numMalformedFiles++;
else if (handler.containsDTD) // not valid } finally {
{ numXMLFiles++;
buff.append ("NOT VALID " + filename + "\n"); }
buff.append(errorBuff.toString()); }
numInvalidFiles++; // Inner classes
}
else // no DOCTYPE to use for validation // Only interested in parsing .xml files.
{ class XMLFileFilter implements FilenameFilter {
if(handler.errorOrWarning) @Override
{ public boolean accept(File dir, String fileName) {
buff.append("Datei " + filename +" wurde validiert:\n"+errorBuff.toString()); return fileName.toLowerCase().endsWith(".xml") && new File(dir.toString(), fileName).isFile();
numInvalidFiles++; }
} }
else
{ // Catch any errors or warnings, and verify presence of doctype statement.
buff.append("Datei " + filename +" wurde validiert:\n"+errorBuff.toString()); class Handler extends DefaultHandler implements LexicalHandler {
numValidFiles++; boolean errorOrWarning;
} boolean containsDTD;
} String sourceFile;
}
catch (Exception e) // Serious problem! StringBuffer errorBuff;
{
buff.append("NOT WELL-FORMED " + filename + ". " + e.getMessage() + "\n"); Handler(String sourceFile, StringBuffer errorBuff) {
numMalformedFiles++; super();
throw new Exception(e); this.sourceFile = sourceFile;
} this.errorBuff = errorBuff;
finally errorOrWarning = false;
{ containsDTD = false;
numXMLFiles++; }
}
} @Override
// Inner classes public void error(SAXParseException exc) {
errorBuff.append(sourceFile + " Error: " + exc.getMessage() + "\n");
// Only interested in parsing .xml files. errorOrWarning = true;
class XMLFileFilter implements FilenameFilter }
{
public boolean accept(File dir, String fileName) @Override
{ public void warning(SAXParseException exc) {
return fileName.toLowerCase().endsWith(".xml") && new File(dir.toString(),fileName).isFile(); errorBuff.append(sourceFile + " Warning:" + exc.getMessage() + "\n");
} errorOrWarning = true;
} }
// Catch any errors or warnings, and verify presence of doctype statement. // LexicalHandler methods; all no-op except startDTD().
class Handler extends DefaultHandler implements LexicalHandler
{ // Set containsDTD to true when startDTD event occurs.
boolean errorOrWarning; @Override
boolean containsDTD; public void startDTD(String name, String publicId, String systemId) throws SAXException {
String sourceFile; containsDTD = true;
StringBuffer errorBuff; }
Handler(String sourceFile, StringBuffer errorBuff) @Override
{ public void endDTD() throws SAXException {
super(); }
this.sourceFile = sourceFile;
this.errorBuff = errorBuff; @Override
errorOrWarning = false; public void startEntity(String name) throws SAXException {
containsDTD = false; }
}
@Override
public void error(SAXParseException exc) public void endEntity(String name) throws SAXException {
{ }
errorBuff.append(sourceFile + " Error: " + exc.getMessage()+ "\n");
errorOrWarning = true; @Override
} public void startCDATA() throws SAXException {
public void warning(SAXParseException exc) }
{
errorBuff.append(sourceFile + " Warning:" + exc.getMessage()+ "\n"); @Override
errorOrWarning = true; public void endCDATA() throws SAXException {
} }
// LexicalHandler methods; all no-op except startDTD(). @Override
public void comment(char ch[], int start, int length) throws SAXException {
// Set containsDTD to true when startDTD event occurs. }
public void startDTD (String name, String publicId, String systemId) }
throws SAXException }
{
containsDTD = true;
}
public void endDTD () throws SAXException
{}
public void startEntity (String name) throws SAXException
{}
public void endEntity (String name) throws SAXException
{}
public void startCDATA () throws SAXException
{}
public void endCDATA () throws SAXException
{}
public void comment (char ch[], int start, int length) throws SAXException
{}
}
}

456
src/de/superx/bin/SxXmlTester.java

@ -1,242 +1,214 @@
package de.superx.bin; package de.superx.bin;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.Date; import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Vector; import java.util.Vector;
import org.w3c.dom.Document; import org.apache.commons.io.FileUtils;
import org.w3c.dom.Node; import org.w3c.dom.Document;
import org.w3c.dom.NodeList; import org.w3c.dom.Node;
import org.xml.sax.SAXException; import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.WebConversation; import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.WebRequest; import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebResponse; import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebTable; import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebTable;
import de.memtext.db.ConnectionCreator;
import de.memtext.util.EqualsUtil; import de.memtext.db.ConnectionCreator;
import de.memtext.util.StringUtils; import de.memtext.util.EqualsUtil;
import de.memtext.util.XMLUtils; import de.memtext.util.XMLUtils;
public class SxXmlTester { public class SxXmlTester {
Document document; Document document;
List webserverlist = new LinkedList();
List dbserverConnections = new LinkedList(); List webserverlist = new LinkedList();
StringBuffer errors = new StringBuffer();
List dbserverConnections = new LinkedList();
private void readdbServers() throws IOException, SQLException, ClassNotFoundException {
NodeList nl = document.getElementsByTagName("dbserver"); StringBuffer errors = new StringBuffer();
for (int i = 0; i < nl.getLength(); i++) { private void readdbServers() throws IOException, SQLException, ClassNotFoundException {
Node serverNode = (Node) nl.item(i); NodeList nl = document.getElementsByTagName("dbserver");
Connection con=ConnectionCreator.getConnectionCryptPassword(XMLUtils.getAttribValue(serverNode, "db_properties"),
"driverName", "connectionURL", "connectionName", for (int i = 0; i < nl.getLength(); i++) {
"connectionPassword"); Node serverNode = (Node) nl.item(i);
System.out.println("Found 1 db.properties node"); Connection con = ConnectionCreator.getConnectionCryptPassword(XMLUtils.getAttribValue(serverNode, "db_properties"), "driverName", "connectionURL", "connectionName",
dbserverConnections.add(con); "connectionPassword");
} System.out.println("Found 1 db.properties node");
} dbserverConnections.add(con);
}
private void readWebServers() { }
NodeList nl = document.getElementsByTagName("webserver");
private void readWebServers() {
for (int i = 0; i < nl.getLength(); i++) { NodeList nl = document.getElementsByTagName("webserver");
Node serverNode = (Node) nl.item(i);
webserverlist.add(XMLUtils.getAttribValue(serverNode, "url")); for (int i = 0; i < nl.getLength(); i++) {
System.out.println("Found 1 webserver node"); Node serverNode = (Node) nl.item(i);
} webserverlist.add(XMLUtils.getAttribValue(serverNode, "url"));
} System.out.println("Found 1 webserver node");
}
private void runDbTests() throws IOException, SQLException, ClassNotFoundException }
{
readdbServers(); private void runDbTests() throws IOException, SQLException, ClassNotFoundException {
NodeList nl = document.getElementsByTagName("dbtest"); readdbServers();
for (int i = 0; i < nl.getLength(); i++) { NodeList nl = document.getElementsByTagName("dbtest");
Node testNode = (Node) nl.item(i); for (int i = 0; i < nl.getLength(); i++) {
Node testNode = (Node) nl.item(i);
String name = XMLUtils.getAttribValue(testNode, "name");
System.out.println("Db-Testnr "+(i+1)+" :"+name); String name = XMLUtils.getAttribValue(testNode, "name");
String sql = XMLUtils.getAttribValue(testNode, "sql"); System.out.println("Db-Testnr " + (i + 1) + " :" + name);
for (Iterator it = dbserverConnections.iterator(); it.hasNext();) { String sql = XMLUtils.getAttribValue(testNode, "sql");
Connection con= (Connection) it.next(); for (Iterator it = dbserverConnections.iterator(); it.hasNext();) {
Statement stm=con.createStatement(); Connection con = (Connection) it.next();
ResultSet rs=stm.executeQuery(sql); Statement stm = con.createStatement();
Vector result=new Vector(); ResultSet rs = stm.executeQuery(sql);
int colcount=0; Vector result = new Vector();
while (rs.next()) int colcount = 0;
{ while (rs.next()) {
colcount=rs.getMetaData().getColumnCount(); colcount = rs.getMetaData().getColumnCount();
Vector row=new Vector(); Vector row = new Vector();
for (int col=1;col<=colcount;col++) for (int col = 1; col <= colcount; col++) {
{ row.add(rs.getObject(col));
row.add(rs.getObject(col)); }
} result.add(row);
result.add(row); }
}
for (Iterator it2 = XMLUtils.getChildNodeIterator(testNode); it2.hasNext();) {
for (Iterator it2 = XMLUtils.getChildNodeIterator(testNode); it2 Node childNode = (Node) it2.next();
.hasNext();) { if (childNode.getNodeName().equals("valuetest")) {
Node childNode = (Node) it2.next(); String rowStr = XMLUtils.getAttribValue(childNode, "row");
if (childNode.getNodeName().equals("valuetest")) { int row = Integer.parseInt(rowStr);
String rowStr = XMLUtils.getAttribValue(childNode, String colStr = XMLUtils.getAttribValue(childNode, "col");
"row"); int col = Integer.parseInt(colStr);
int row = Integer.parseInt(rowStr); String val = XMLUtils.getAttribValue(childNode, "val");
String colStr = XMLUtils.getAttribValue(childNode,
"col"); if (col > colcount) {
int col = Integer.parseInt(colStr); errors.append("Test " + name + " Versuch Spalte " + col + " zu lesen, Tabelle hat nur " + colcount + " Spalten\n");
String val = XMLUtils.getAttribValue(childNode, "val"); continue;
}
if (col>colcount) if (row > result.size()) {
{ errors.append("Test " + name + " Versuch Zeile " + row + " zu lesen, ResultSet hat nur " + result.size() + " Zeilen\n");
errors.append("Test " + name continue;
+ " Versuch Spalte "+col+" zu lesen, Tabelle hat nur " + colcount+" Spalten\n" ); }
continue; Vector arow = (Vector) result.get(row - 1);
} String gefunden = arow.get(col - 1).toString();
if (row>result.size())
{ if (!EqualsUtil.areEqual(val, gefunden)) {
errors.append("Test " + name
+ " Versuch Zeile "+row+" zu lesen, ResultSet hat nur " + result.size()+" Zeilen\n" ); errors.append("Test " + name + " Falscher Wert Zeile " + row + " Spalte " + col + " erwartet:" + val + " gefunden:" + gefunden + "\n(sql:" + sql
continue; + "\n\n");
} }
Vector arow=(Vector)result.get(row-1); }
String gefunden = arow.get(col - 1).toString() }
;
}
if (!EqualsUtil.areEqual(val, gefunden)) { }
}
errors.append("Test " + name
+ " Falscher Wert Zeile " + row public void go(String args[]) throws SAXException, IOException, SQLException, ClassNotFoundException {
+ " Spalte " + col + " erwartet:" + val document = XMLUtils.buildDocument(new File(args[0]));
+ " gefunden:" + gefunden + "\n(sql:"+sql+"\n\n"); runDbTests();
} runWebtests();
} if (errors.length() > 0) {
} System.out.println("Es sind Fehler aufgetaucht siehe output-errors.txt");
FileUtils.writeStringToFile(new File("output-errors.txt"), new Date() + "\n" + errors.toString());
}
} } else {
} System.out.println("Keine Fehler aufgefallen");
public void go(String args[]) throws SAXException, IOException, SQLException, ClassNotFoundException { }
XMLUtils.getExceptionHandler().setWithGui(false); }
document = XMLUtils.buildDocument(new File(args[0]));
runDbTests();
runWebtests(); private void runWebtests() throws SAXException, IOException {
if (errors.length()>0) readWebServers();
{
System.out.println("Es sind Fehler aufgetaucht siehe output-errors.txt"); NodeList nl = document.getElementsByTagName("webtest");
StringUtils.write(new File("output-errors.txt"),new Date()+"\n"+errors.toString()); WebConversation wc = new WebConversation();
for (int i = 0; i < nl.getLength(); i++) {
} Node testNode = (Node) nl.item(i);
else
{ String name = XMLUtils.getAttribValue(testNode, "name");
System.out.println("Keine Fehler aufgefallen"); System.out.println("Webserver-Testnr " + (i + 1) + " :" + name);
} String params = XMLUtils.getChildNodeValue(testNode, "params");
} for (Iterator it = webserverlist.iterator(); it.hasNext();) {
String serverUrl = (String) it.next();
serverUrl += params;
private void runWebtests() throws SAXException, IOException {
readWebServers(); WebRequest req = new GetMethodWebRequest(serverUrl);
WebResponse resp;
NodeList nl = document.getElementsByTagName("webtest"); try {
WebConversation wc = new WebConversation(); resp = wc.getResponse(req);
for (int i = 0; i < nl.getLength(); i++) { } catch (IOException e) {
Node testNode = (Node) nl.item(i); System.err.println("Aufruf fehlgeschlagen von " + serverUrl);
throw e;
String name = XMLUtils.getAttribValue(testNode, "name"); }
System.out.println("Webserver-Testnr "+(i+1)+" :"+name); FileUtils.writeStringToFile(new File("output_" + name + ".htm"), resp.getText());
String params = XMLUtils.getChildNodeValue(testNode, "params"); if (resp.getTables().length < 2) {
for (Iterator it = webserverlist.iterator(); it.hasNext();) { errors.append("Test " + name + " Keine Ergebnistabelle geliefert\n ");
String serverUrl = (String) it.next(); continue;
serverUrl += params;
}
WebRequest req = new GetMethodWebRequest(serverUrl); for (Iterator it2 = XMLUtils.getChildNodeIterator(testNode); it2.hasNext();) {
WebResponse resp; Node childNode = (Node) it2.next();
try { if (childNode.getNodeName().equals("valuetest")) {
resp = wc.getResponse(req); String rowStr = XMLUtils.getAttribValue(childNode, "row");
} catch (IOException e) { int row = Integer.parseInt(rowStr);
System.err.println("Aufruf fehlgeschlagen von "+serverUrl); String colStr = XMLUtils.getAttribValue(childNode, "col");
throw e; int col = Integer.parseInt(colStr);
} String val = XMLUtils.getAttribValue(childNode, "val");
StringUtils.write(new File("output_" + name WebTable table = resp.getTables()[1];
+ ".htm"), resp.getText()); if (col > table.getColumnCount()) {
if (resp.getTables().length <2) { FileUtils.writeStringToFile(new File("output_" + name + ".htm"), resp.getText());
errors.append("Test " + name errors.append("Test " + name + " Versuch Spalte " + col + " zu lesen, Tabelle hat nur " + table.getColumnCount() + " Spalten\n");
+ " Keine Ergebnistabelle geliefert\n "); continue;
continue; }
if (row > table.getRowCount()) {
} FileUtils.writeStringToFile(new File("output_" + name + ".htm"), resp.getText());
for (Iterator it2 = XMLUtils.getChildNodeIterator(testNode); it2 errors.append("Test " + name + " Versuch Zeile " + row + " zu lesen, Tabelle hat nur " + table.getRowCount() + " Zeilen\n");
.hasNext();) { continue;
Node childNode = (Node) it2.next(); }
if (childNode.getNodeName().equals("valuetest")) {
String rowStr = XMLUtils.getAttribValue(childNode, String gefunden = table.getTableCell(row - 1, col - 1).getText();
"row");
int row = Integer.parseInt(rowStr); if (!EqualsUtil.areEqual(val, gefunden)) {
String colStr = XMLUtils.getAttribValue(childNode,
"col"); errors.append("Test " + name + " Falscher Wert Zeile " + row + " Spalte " + col + " erwartet:" + val + " gefunden:" + gefunden + "\n(url:" + serverUrl
int col = Integer.parseInt(colStr); + "\n\n");
String val = XMLUtils.getAttribValue(childNode, "val"); }
WebTable table = resp.getTables()[1]; }
if (col>table.getColumnCount()) }
{
StringUtils.write(new File("output_" + name }
+ ".htm"), resp.getText()); }
errors.append("Test " + name }
+ " Versuch Spalte "+col+" zu lesen, Tabelle hat nur " + table.getColumnCount()+" Spalten\n" );
continue; public static void main(String[] args) {
}
if (row>table.getRowCount()) System.out.println("");
{ if (args.length != 1) {
StringUtils.write(new File("output_" + name System.err.println("usage SxXmlTester test.xml");
+ ".htm"), resp.getText()); System.exit(-1);
errors.append("Test " + name }
+ " Versuch Zeile "+row+" zu lesen, Tabelle hat nur " + table.getRowCount()+" Zeilen\n" ); try {
continue; new SxXmlTester().go(args);
} } catch (Exception e) {
System.out.println(e);
String gefunden = table.getTableCell(row - 1, col - 1) e.printStackTrace();
.getText();
}
if (!EqualsUtil.areEqual(val, gefunden)) { }
// junit.textui.TestRunner.run(AutoTest.class);
errors.append("Test " + name }
+ " Falscher Wert Zeile " + row
+ " Spalte " + col + " erwartet:" + val //Created on 27.04.2006 at 10:25:34
+ " gefunden:" + gefunden + "\n(url:"+serverUrl+"\n\n");
}
}
}
}
}
}
public static void main(String[] args) {
System.out.println("");
if (args.length != 1) {
System.err.println("usage SxXmlTester test.xml");
System.exit(-1);
}
try {
new SxXmlTester().go(args);
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
// junit.textui.TestRunner.run(AutoTest.class);
}
//Created on 27.04.2006 at 10:25:34

358
src/de/superx/bin/UnlFileConverter.java

@ -12,7 +12,7 @@ package de.superx.bin;
* 26.8.04 MB XMLUtils.buildDocumentFromFile -> buildDocument * 26.8.04 MB XMLUtils.buildDocumentFromFile -> buildDocument
*/ */
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -28,80 +28,115 @@ import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import de.memtext.util.ExceptionHandler;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
import de.memtext.util.XMLUtils; import de.memtext.util.XMLUtils;
public class UnlFileConverter { public class UnlFileConverter {
/* Klassenvariablen */ /* Klassenvariablen */
private static String _dateiPfad = ""; private static String _dateiPfad = "";
private static String DELIMITER = "^"; private static String DELIMITER = "^";
private static String _outDateiPfad = ""; private static String _outDateiPfad = "";
private static String _tabelle = ""; private static String _tabelle = "";
private static String _indescr = ""; private static String _indescr = "";
private static String _outdescr = ""; private static String _outdescr = "";
private static String logfile = "../conf/logging.properties"; private static String logfile = "../conf/logging.properties";
private static String dbpropfile = ""; private static String dbpropfile = "";
private static String usage =
"-------------------------------------\n" private static String usage = "-------------------------------------\n"
+ "Gebrauch: java de.superx.bin.UnlFileConverter -logger:<Pfad zu logging.properties> -IN:<Pfad zur unl-Datei> -OUT:<Pfad zur Ausgabedatei> -INDESCR:<Pfad zum Eingabe-Descriptor> -OUTDESCR:<Pfad zum Ausgabe-Descriptor> -dbproperties:<Pfad zu db.properties> " + "Gebrauch: java de.superx.bin.UnlFileConverter -logger:<Pfad zu logging.properties> -IN:<Pfad zur unl-Datei> -OUT:<Pfad zur Ausgabedatei> -INDESCR:<Pfad zum Eingabe-Descriptor> -OUTDESCR:<Pfad zum Ausgabe-Descriptor> -dbproperties:<Pfad zu db.properties> "
+ "-table:<Tabellenname (wenn auch die Tabelle auf Typkompatitibilität gechekct werden soll>." + "-table:<Tabellenname (wenn auch die Tabelle auf Typkompatitibilität gechekct werden soll>."
+ "\n---------------------------------------------------"; + "\n---------------------------------------------------";
private static String indescr_name = ""; private static String indescr_name = "";
private static String indescr_dbsystem = ""; private static String indescr_dbsystem = "";
private static String indescr_app = ""; private static String indescr_app = "";
private static String indescr_cmd = ""; private static String indescr_cmd = "";
private static String in_rec_sep = ""; private static String in_rec_sep = "";
private static String in_line_sep = ""; private static String in_line_sep = "";
private static String in_rec_header = ""; private static String in_rec_header = "";
private static String in_rec_footer = ""; private static String in_rec_footer = "";
private static String in_header = ""; private static String in_header = "";
private static String in_header_delim = ""; private static String in_header_delim = "";
private static boolean in_fixedwidth = false; private static boolean in_fixedwidth = false;
private static String in_escapemode = ""; private static String in_escapemode = "";
private static String in_chmod = ""; private static String in_chmod = "";
private static String out_rec_sep = ""; private static String out_rec_sep = "";
private static String out_line_sep = ""; private static String out_line_sep = "";
private static String out_rec_header = ""; private static String out_rec_header = "";
private static String out_rec_footer = ""; private static String out_rec_footer = "";
private static String out_header = ""; private static String out_header = "";
private static String out_header_delim = ""; private static String out_header_delim = "";
private static boolean out_fixedwidth = false; private static boolean out_fixedwidth = false;
private static String out_escapemode = ""; private static String out_escapemode = "";
private static String out_chmod = ""; private static String out_chmod = "";
private static int plaintextcount = 0; private static int plaintextcount = 0;
private static Document inDocument; private static Document inDocument;
private static Document outDocument; private static Document outDocument;
private static String plaintextTag = "plaintext"; private static String plaintextTag = "plaintext";
private static String[] searchtext = new String[10]; private static String[] searchtext = new String[10];
private static String[] replacetext = new String[10]; private static String[] replacetext = new String[10];
private static final String newline = "{newline}"; private static final String newline = "{newline}";
private static final String tab = "{tab}"; private static final String tab = "{tab}";
Logger logger =
(Logger) Logger.getLogger(UnlFileConverter.class.toString()); Logger logger = (Logger) Logger.getLogger(UnlFileConverter.class.toString());
private ExceptionHandler exceptionHandler = new ExceptionHandler(false);
public UnlFileConverter() { public UnlFileConverter() {
} }
public static void main(String[] args)
throws FileNotFoundException, IOException { public static void main(String[] args) throws FileNotFoundException, IOException {
UnlFileConverter r = new UnlFileConverter(); UnlFileConverter r = new UnlFileConverter();
GetOpts.setOpts(args); GetOpts.setOpts(args);
String isdrin = String isdrin = GetOpts
GetOpts.isAllRequiredOptionsPresent("-logger,-IN,-I_DESCR"); .isAllRequiredOptionsPresent(new Options[] { Options.opt_logger, Options.opt_in, Options.opt_idescr });
if (isdrin != null) { if (isdrin != null) {
System.err.println( System.err.println("Datei-Pfade werden als Parameter erwartet. Folgende Optionen fehlen: " + isdrin);
"Datei-Pfade werden als Parameter erwartet. Folgende Optionen fehlen: "
+ isdrin);
r.zeige_hilfe(); r.zeige_hilfe();
System.exit(1); System.exit(1);
} }
//GetOpts myOpts=new GetOpts(); // GetOpts myOpts=new GetOpts();
if (GetOpts.isPresent("-logger")) if (GetOpts.isPresent(Options.opt_logger))
logfile = GetOpts.getValue("-logger"); logfile = GetOpts.getValue(Options.opt_logger);
File f = new File(logfile); File f = new File(logfile);
if (!f.exists()) { if (!f.exists()) {
throw new IOException("Datei nicht gefunden: " + logfile); throw new IOException("Datei nicht gefunden: " + logfile);
@ -110,108 +145,87 @@ public class UnlFileConverter {
LogManager MyLogManager = java.util.logging.LogManager.getLogManager(); LogManager MyLogManager = java.util.logging.LogManager.getLogManager();
MyLogManager.readConfiguration(ins); MyLogManager.readConfiguration(ins);
logfile = MyLogManager.getProperty(".level"); logfile = MyLogManager.getProperty(".level");
//logger.info("Using Loggging-Level " + logfile); // logger.info("Using Loggging-Level " + logfile);
if (GetOpts.isPresent("-IN")) if (GetOpts.isPresent(Options.opt_in))
_dateiPfad = GetOpts.getValue("-IN"); _dateiPfad = GetOpts.getValue(Options.opt_in);
if (GetOpts.isPresent("-OUT")) if (GetOpts.isPresent(Options.opt_out))
_outDateiPfad = GetOpts.getValue("-OUT"); _outDateiPfad = GetOpts.getValue(Options.opt_out);
if (GetOpts.isPresent("-I_DESCR")) if (GetOpts.isPresent(Options.opt_idescr))
_indescr = GetOpts.getValue("-I_DESCR"); _indescr = GetOpts.getValue(Options.opt_idescr);
if (GetOpts.isPresent("-O_DESCR")) if (GetOpts.isPresent(Options.opt_odescr))
_outdescr = GetOpts.getValue("-O_DESCR"); _outdescr = GetOpts.getValue(Options.opt_odescr);
if (GetOpts.isPresent("-dbproperties")) if (GetOpts.isPresent(Options.opt_dbprops))
dbpropfile = GetOpts.getValue("-dbproperties"); dbpropfile = GetOpts.getValue(Options.opt_dbprops);
if (GetOpts.isPresent("-table")) if (GetOpts.isPresent(Options.opt_table))
if (dbpropfile.equals("")) { if (dbpropfile.equals("")) {
System.err.println( System.err.println(
"Wenn auch die Ziel-Tabelle geprüft werden soll, dann muss dbproperties gesetzt sein."); "Wenn auch die Ziel-Tabelle geprüft werden soll, dann muss dbproperties gesetzt sein.");
System.err.println(usage); System.err.println(usage);
System.exit(1); System.exit(1);
} else } else
_tabelle = GetOpts.getValue("-table"); _tabelle = GetOpts.getValue(Options.opt_table);
if (args[0].toString().equals("?") if (args[0].toString().equals("?") || args[0].toString().equals("/?") || args[0].toString().equals("\\?")
|| args[0].toString().equals("/?") || args[0].toString().toLowerCase().equals("-h") || args[0].toString().toLowerCase().equals("--h")) {
|| args[0].toString().equals("\\?")
|| args[0].toString().toLowerCase().equals("-h")
|| args[0].toString().toLowerCase().equals("--h")) {
r.zeige_hilfe(); r.zeige_hilfe();
System.exit(1); System.exit(1);
} }
init_descr();
try { try {
init_descr();
r.updateFile(_dateiPfad, _outDateiPfad); r.updateFile(_dateiPfad, _outDateiPfad);
System.out.println( System.out.println("Datei: " + _dateiPfad + " nach " + _outDateiPfad + " umgesetzt");
"Datei: "
+ _dateiPfad
+ " nach "
+ _outDateiPfad
+ " umgesetzt");
} catch (Exception e) { } catch (Exception e) {
System.err.println(e.toString()); System.err.println(e.toString());
} }
//} // }
} // Ende der Methode } // Ende der Methode
private void updateFile(String inDateiPfad, String outDateiPfad) private void updateFile(String inDateiPfad, String outDateiPfad) throws IOException, Exception {
throws IOException, Exception {
File f = new File(inDateiPfad); File f = new File(inDateiPfad);
if (!f.exists()) { if (!f.exists()) {
throw new Exception("Datei nicht gefunden: " + inDateiPfad); throw new Exception("Datei nicht gefunden: " + inDateiPfad);
} }
BufferedReader in; BufferedReader in;
BufferedWriter out; BufferedWriter out;
//--- File-Instanz für temporäre Ergebnis-Datei anlegen ---// // --- File-Instanz für temporäre Ergebnis-Datei anlegen ---//
File out_tmp; File out_tmp;
if (inDateiPfad.equals(outDateiPfad)) if (inDateiPfad.equals(outDateiPfad))
out_tmp = new File(inDateiPfad + ".tmp2"); out_tmp = new File(inDateiPfad + ".tmp2");
else else
out_tmp = new File(outDateiPfad); out_tmp = new File(outDateiPfad);
//--- IputStream und OutputStream generieren ---// // --- IputStream und OutputStream generieren ---//
in = new BufferedReader(new InputStreamReader(new FileInputStream(f))); in = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
//--- Output-Stream der temporären Datei erzeugen ---// // --- Output-Stream der temporären Datei erzeugen ---//
out = out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(out_tmp)));
new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(out_tmp)));
//--- Verarbeiten der Datei ---// // --- Verarbeiten der Datei ---//
String text; String text;
String text2; String text2;
String tt; String tt;
/*char[] cbuf = new char[1024]; /*
while(true) * char[] cbuf = new char[1024]; while(true) { int status =
{ * in.read(cbuf,0,1024); if(status == -1) break; //text=cbuf.toString();
int status = in.read(cbuf,0,1024); * text=String.valueOf(cbuf); if (text.startsWith(in_rec_header)) text =
if(status == -1) * StringUtils.substringAfter(text, in_rec_header); text = createRow(in, text +
break; * out_rec_header); //in text steht ein Datensatz text = StringUtils.chomp(text,
//text=cbuf.toString(); * in_rec_footer); text += out_rec_footer; text = replacePlainText(text);
text=String.valueOf(cbuf); * checkTable(text); //Wenn Tabelle gecheckt werden sollte
if (text.startsWith(in_rec_header)) *
text = StringUtils.substringAfter(text, in_rec_header); * out.write(text, 0, text.length()); out.write(out_rec_sep); // muss NeuLine
text = createRow(in, text + out_rec_header); * schreiben da die Zeile ohne eingelesen wird out.flush(); }
//in text steht ein Datensatz */
text = StringUtils.chomp(text, in_rec_footer);
text += out_rec_footer;
text = replacePlainText(text);
checkTable(text); //Wenn Tabelle gecheckt werden sollte
out.write(text, 0, text.length());
out.write(out_rec_sep);
// muss NeuLine schreiben da die Zeile ohne eingelesen wird
out.flush();
}*/
text = in.readLine(); text = in.readLine();
while (text != null) { //Datei nicht leer while (text != null) { // Datei nicht leer
if (text.startsWith(in_rec_header)) if (text.startsWith(in_rec_header))
text = StringUtils.substringAfter(text, in_rec_header); text = StringUtils.substringAfter(text, in_rec_header);
text = createRow(in, text + out_rec_header); text = createRow(in, text + out_rec_header);
//in text steht ein Datensatz // in text steht ein Datensatz
text = StringUtils.chomp(text, in_rec_footer); text = StringUtils.chomp(text, in_rec_footer);
text += out_rec_footer; text += out_rec_footer;
text = replacePlainText(text); text = replacePlainText(text);
checkTable(text); //Wenn Tabelle gecheckt werden sollte checkTable(text); // Wenn Tabelle gecheckt werden sollte
out.write(text, 0, text.length()); out.write(text, 0, text.length());
out.write(out_rec_sep); out.write(out_rec_sep);
@ -220,53 +234,50 @@ public class UnlFileConverter {
text = in.readLine(); text = in.readLine();
} //Ende der While-Schleife,alle records bearbeitet. } // Ende der While-Schleife,alle records bearbeitet.
in.close(); in.close();
out.close(); out.close();
//--- Umbenennen Quell-Dateien ---// // --- Umbenennen Quell-Dateien ---//
/*String alt = inDateiPfad + ".in"; /*
File altFile = new File(alt); * String alt = inDateiPfad + ".in"; File altFile = new File(alt); if
if (altFile.exists()) * (altFile.exists()) altFile.delete();
altFile.delete(); *
* f.renameTo(altFile);
f.renameTo(altFile);*/ */
//--- Umformatierte temporäre Datei unter dem ursprünglichen Namen ablegen ---// // --- Umformatierte temporäre Datei unter dem ursprünglichen Namen ablegen
// ---//
if (inDateiPfad.equals(outDateiPfad)) { if (inDateiPfad.equals(outDateiPfad)) {
File neuFile = new File(outDateiPfad); File neuFile = new File(outDateiPfad);
if (neuFile.isFile()) if (neuFile.isFile())
neuFile.delete(); neuFile.delete();
if (!out_tmp.renameTo(neuFile)) if (!out_tmp.renameTo(neuFile))
logger.severe( logger.severe("Kann " + outDateiPfad
"Kann "
+ outDateiPfad
+ " nicht erzeugen! Existiert die Datei bereits? Die umgesetzte Datei befindet sich in " + " nicht erzeugen! Existiert die Datei bereits? Die umgesetzte Datei befindet sich in "
+ out_tmp.getPath() + out_tmp.getPath() + System.getProperty("file.separator") + out_tmp.getName());
+ System.getProperty("file.separator")
+ out_tmp.getName());
else else
out_tmp.delete(); out_tmp.delete();
} }
//--- Berechtigung für die neu angelegete Datei neu Vergeben ---// // --- Berechtigung für die neu angelegete Datei neu Vergeben ---//
if (!out_chmod.equals("")) { if (!out_chmod.equals("")) {
if (!chmode(out_chmod, outDateiPfad)) { if (!chmode(out_chmod, outDateiPfad)) {
logger.severe("Kann Berechtigung nicht ändern " + outDateiPfad); logger.severe("Kann Berechtigung nicht ändern " + outDateiPfad);
} }
} }
//--- Schliessen der Streams und Löschen der temporären Datei ---// // --- Schliessen der Streams und Löschen der temporären Datei ---//
in.close(); in.close();
out.close(); out.close();
} }
private String createRow(BufferedReader in, String text)
throws IOException { private String createRow(BufferedReader in, String text) throws IOException {
String tt; String tt;
try { try {
//System.out.println(text); // System.out.println(text);
if (text.endsWith(in_line_sep) && !in_line_sep.equals("")) { if (text.endsWith(in_line_sep) && !in_line_sep.equals("")) {
text = StringUtils.chomp(text, in_line_sep); text = StringUtils.chomp(text, in_line_sep);
text += out_line_sep; text += out_line_sep;
tt = in.readLine(); tt = in.readLine();
@ -276,39 +287,36 @@ public class UnlFileConverter {
tt = in.readLine(); tt = in.readLine();
if (tt != null) { if (tt != null) {
text += out_line_sep text += out_line_sep + StringUtils.chomp(tt, in_line_sep);
+ StringUtils.chomp(tt, in_line_sep);
} }
//(tt.substring(0,tt.length())); // (tt.substring(0,tt.length()));
} }
} }
} else } else
text = SxDBUtils.replaceString(text, in_line_sep, out_line_sep); text = SxDBUtils.replaceString(text, in_line_sep, out_line_sep);
} catch (Exception e) { } catch (Exception e) {
logger.severe( logger.severe("Fehler beim Umsetzen: " + e.toString() + "\n" + text);
"Fehler beim Umsetzen: " + e.toString() + "\n" + text);
throw new IOException(); throw new IOException();
} }
//Sonderzeichen in xil_proplist abfangen: // Sonderzeichen in xil_proplist abfangen:
//text=SxDBUtils.replaceString(text,"\\000" , "\\\\000"); // text=SxDBUtils.replaceString(text,"\\000" , "\\\\000");
return text; return text;
} }
private void checkTable(String text) throws Exception { private void checkTable(String text) throws Exception {
if (!_tabelle.equals("") && !_tabelle.equals("null")) { if (!_tabelle.equals("") && !_tabelle.equals("null")) {
//Die Datei ist eine entladene Tabelle // Die Datei ist eine entladene Tabelle
//int start=_dateiPfad.indexOf("_",_dateiPfad.length()-4); // int start=_dateiPfad.indexOf("_",_dateiPfad.length()-4);
//if(start <0 ) // if(start <0 )
// start=0; // start=0;
// String tabname=_dateiPfad.substring(start,_dateiPfad.length()-4); // String tabname=_dateiPfad.substring(start,_dateiPfad.length()-4);
int numFelder = 0; int numFelder = 0;
//System.out.println("Tabelle "+_tabelle+ " DELIM " + DELIMITER); // System.out.println("Tabelle "+_tabelle+ " DELIM " + DELIMITER);
try { try {
numFelder = SxDBUtils.fieldCount(_tabelle); numFelder = SxDBUtils.fieldCount(_tabelle);
//System.out.println("Felderanzahl:"+numFelder); // System.out.println("Felderanzahl:"+numFelder);
} catch (Exception e) { } catch (Exception e) {
System.err.println( System.err.println("Fehler beim Abfragen der Tabellen-Metadaten: " + e.toString());
"Fehler beim Abfragen der Tabellen-Metadaten: "
+ e.toString());
} }
int k = 0; int k = 0;
int i = 0; int i = 0;
@ -322,16 +330,12 @@ public class UnlFileConverter {
} while (p > 0); } while (p > 0);
if (k != numFelder) { if (k != numFelder) {
throw new Exception( throw new Exception("unl-Datei entspricht nicht der Tabelle in der Datenbank;\nDie Tabelle hat "
"unl-Datei entspricht nicht der Tabelle in der Datenbank;\nDie Tabelle hat " + numFelder + " Felder, die unl-Datei hat " + k + " Felder ");
+ numFelder
+ " Felder, die unl-Datei hat "
+ k
+ " Felder ");
} }
} }
} //Ende der Methode } // Ende der Methode
private boolean chmode(String inBerechtigung, String inDat) { private boolean chmode(String inBerechtigung, String inDat) {
String befehl = "chmod " + inBerechtigung + " " + inDat; String befehl = "chmod " + inBerechtigung + " " + inDat;
@ -345,16 +349,15 @@ public class UnlFileConverter {
} }
return true; return true;
} //Ende der Methode } // Ende der Methode
private String replacePlainText(String inS) { private String replacePlainText(String inS) {
String outS = ""; String outS = "";
for (int i = 0; i <= plaintextcount-1; i++) { for (int i = 0; i <= plaintextcount - 1; i++) {
if ((searchtext[i].equals("") && replacetext[i].equals("")) if ((searchtext[i].equals("") && replacetext[i].equals("")) || (searchtext[i].equals(replacetext[i])))
|| (searchtext[i].equals(replacetext[i])))
outS = inS; outS = inS;
else else
outS = outS = SxDBUtils.replaceString(inS, searchtext[i], replacetext[i]);
SxDBUtils.replaceString(inS, searchtext[i], replacetext[i]);
inS = outS; inS = outS;
} }
return outS; return outS;
@ -362,44 +365,45 @@ public class UnlFileConverter {
/** /**
* Liefert den Teilsstring von 0 bis zu letzten Delimiterzeichen(Exclusive) * Liefert den Teilsstring von 0 bis zu letzten Delimiterzeichen(Exclusive)
*
* @param inS * @param inS
* @return String * @return String
*/ */
private String reorgString(String inS) throws Exception { private String reorgString(String inS) throws Exception {
int ldPos = inS.lastIndexOf(DELIMITER); int ldPos = inS.lastIndexOf(DELIMITER);
//--- Wenn Delimiter-Zeichen nicht letztes Zeichen im String ist, // --- Wenn Delimiter-Zeichen nicht letztes Zeichen im String ist,
//--- muss die Verarbeitung abgebrochen werden---// // --- muss die Verarbeitung abgebrochen werden---//
if ((ldPos + 1) < inS.length() || ldPos == -1) if ((ldPos + 1) < inS.length() || ldPos == -1)
//throw new Exception("Datei ist bereits umgesetzt!"); // throw new Exception("Datei ist bereits umgesetzt!");
return inS; return inS;
else else
return inS.substring(0, ldPos); return inS.substring(0, ldPos);
} //Ende der Methode } // Ende der Methode
public boolean check_param_ok(String[] inTab) { //--- Anzahl der übergebenen Parameter prüfen ---// public boolean check_param_ok(String[] inTab) { // --- Anzahl der übergebenen Parameter prüfen ---//
//System.out.println(inTab.length); // System.out.println(inTab.length);
if (inTab.length < 2) { if (inTab.length < 2) {
System.out.println( System.out.println("Mindestens 2 Parameter erwartet! Mit -h oder ? rufen sie Hilfe auf.");
"Mindestens 2 Parameter erwartet! Mit -h oder ? rufen sie Hilfe auf.");
return false; return false;
} }
//--- Dateinpfad übernehmen ---// // --- Dateinpfad übernehmen ---//
_dateiPfad = inTab[0].trim(); _dateiPfad = inTab[0].trim();
_outDateiPfad = inTab[1].trim(); _outDateiPfad = inTab[1].trim();
if (inTab.length >= 3) if (inTab.length >= 3)
DELIMITER = inTab[2].trim(); DELIMITER = inTab[2].trim();
//---Wenn Delimiter-Zeichen übergeben wurde dann übernehmen ---// // ---Wenn Delimiter-Zeichen übergeben wurde dann übernehmen ---//
if (inTab.length > 3) if (inTab.length > 3)
_tabelle = inTab[3].toString().trim(); _tabelle = inTab[3].toString().trim();
return true; return true;
} //Ende der Methode } // Ende der Methode
/** /**
* Prüfen der Datei auf Vorhandensein und Leseberechrigung * Prüfen der Datei auf Vorhandensein und Leseberechrigung
*
* @param inFile * @param inFile
*/ */
private boolean check_Directory(File inFile) { private boolean check_Directory(File inFile) {
@ -414,16 +418,14 @@ public class UnlFileConverter {
} }
return true; return true;
} //Ende der Methode } // Ende der Methode
private void progEnde() { private void progEnde() {
System.runFinalization(); System.runFinalization();
System.exit(0); System.exit(0);
} //Ende der Methode } // Ende der Methode
private static void init_descr() { private static void init_descr() throws IOException, SAXException {
XMLUtils.getExceptionHandler().setWithGui(false);
XMLUtils.getExceptionHandler().setExitWanted(true);
inDocument = XMLUtils.buildDocument(new File(_indescr), false); inDocument = XMLUtils.buildDocument(new File(_indescr), false);
NodeList myInNodes = inDocument.getElementsByTagName(plaintextTag); NodeList myInNodes = inDocument.getElementsByTagName(plaintextTag);
outDocument = XMLUtils.buildDocument(new File(_outdescr), false); outDocument = XMLUtils.buildDocument(new File(_outdescr), false);
@ -439,31 +441,29 @@ public class UnlFileConverter {
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
searchtext[i] = ""; searchtext[i] = "";
} }
searchtext[i]=SxDBUtils.replaceString(searchtext[i], tab, "\t"); searchtext[i] = SxDBUtils.replaceString(searchtext[i], tab, "\t");
searchtext[i]=SxDBUtils.replaceString(searchtext[i], newline, "\n"); searchtext[i] = SxDBUtils.replaceString(searchtext[i], newline, "\n");
/*if (searchtext[i].equals(tab)) /*
searchtext[i] = "\t"; * if (searchtext[i].equals(tab)) searchtext[i] = "\t"; if
if (searchtext[i].equals(newline)) * (searchtext[i].equals(newline)) searchtext[i] = "\n";
searchtext[i] = "\n";*/ */
for (int k = 0; k < myOutNodes.getLength(); k++) { for (int k = 0; k < myOutNodes.getLength(); k++) {
Node myOutNode = myOutNodes.item(k); Node myOutNode = myOutNodes.item(k);
if (XMLUtils if (XMLUtils.getAttribValue(myOutNode, "type").equals(plaintexttype)) {
.getAttribValue(myOutNode, "type")
.equals(plaintexttype)) {
try { try {
replacetext[i] = XMLUtils.getTheValue(myOutNode); replacetext[i] = XMLUtils.getTheValue(myOutNode);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
replacetext[i] = ""; replacetext[i] = "";
} }
replacetext[i]=SxDBUtils.replaceString(replacetext[i], tab, "\t"); replacetext[i] = SxDBUtils.replaceString(replacetext[i], tab, "\t");
replacetext[i]=SxDBUtils.replaceString(replacetext[i], newline, "\n"); replacetext[i] = SxDBUtils.replaceString(replacetext[i], newline, "\n");
/*if (replacetext[i].equals(tab)) /*
replacetext[i] = "\t"; * if (replacetext[i].equals(tab)) replacetext[i] = "\t";
*
if (replacetext[i].equals(newline)) * if (replacetext[i].equals(newline)) replacetext[i] = "\n";
replacetext[i] = "\n";*/ */
} }
} }
@ -479,8 +479,7 @@ public class UnlFileConverter {
in_rec_sep = StringUtils.chomp(in_rec_sep, newline); in_rec_sep = StringUtils.chomp(in_rec_sep, newline);
try { try {
Node myNode = Node myNode = XMLUtils.getFirstNode(outDocument, "record-separator");
XMLUtils.getFirstNode(outDocument, "record-separator");
out_rec_sep = XMLUtils.getTheValue(myNode); out_rec_sep = XMLUtils.getTheValue(myNode);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
out_rec_sep = newline; out_rec_sep = newline;
@ -497,7 +496,7 @@ public class UnlFileConverter {
} }
if (in_line_sep.endsWith(newline)) if (in_line_sep.endsWith(newline))
in_line_sep = StringUtils.chomp(in_line_sep, newline)+"\n"; in_line_sep = StringUtils.chomp(in_line_sep, newline) + "\n";
try { try {
Node myNode = XMLUtils.getFirstNode(outDocument, "line-separator"); Node myNode = XMLUtils.getFirstNode(outDocument, "line-separator");
out_line_sep = XMLUtils.getTheValue(myNode); out_line_sep = XMLUtils.getTheValue(myNode);
@ -612,21 +611,22 @@ public class UnlFileConverter {
} }
} }
private void zeige_hilfe() { private void zeige_hilfe() {
System.out.println( System.out.println("\n Diese Klasse bereinigt die Zeilen der angegebenen ASCII-Dateien.");
"\n Diese Klasse bereinigt die Zeilen der angegebenen ASCII-Dateien."); System.out.println(" Es wird der letzte Delimeter-Zeichen aus jeder Zeile entfernt.");
System.out.println(
" Es wird der letzte Delimeter-Zeichen aus jeder Zeile entfernt.");
System.out.println("\n Parameter: "); System.out.println("\n Parameter: ");
System.out.println("1. Eingabe-Dateiname mit Pfadangabe "); System.out.println("1. Eingabe-Dateiname mit Pfadangabe ");
System.out.println("2. Ausgabe-Dateiname mit Pfadangabe"); System.out.println("2. Ausgabe-Dateiname mit Pfadangabe");
System.out.println("3. Delimiter-Zeichen(optional)"); System.out.println("3. Delimiter-Zeichen(optional)");
System.out.println( System.out.println(
"4. Tabellenname in der Datenbank, der auf Übereistimmung der Felderanzahl geprüft werden soll (optional, wenn keine Überprüfung, dann 'none')."); "4. Tabellenname in der Datenbank, der auf Übereistimmung der Felderanzahl geprüft werden soll (optional, wenn keine Überprüfung, dann 'none').");
//System.out.println(" Wenn in einer Zeile Zeichen hinter dem letzten Delimiter-Zeichen "); // System.out.println(" Wenn in einer Zeile Zeichen hinter dem letzten
//System.out.println(" wird die Bearbeitung abgebrochen, da es anzunehmen ist daß diese Datei"); // Delimiter-Zeichen ");
//System.out.println(" bereits umgesetzt ist!"); // System.out.println(" wird die Bearbeitung abgebrochen, da es anzunehmen ist
// daß diese Datei");
// System.out.println(" bereits umgesetzt ist!");
System.out.println(" Defaultwert fuer Delimiter ist ^. \n"); System.out.println(" Defaultwert fuer Delimiter ist ^. \n");
} // Ende der Methode } // Ende der Methode
} //Ende der Klasse } // Ende der Klasse

250
src/de/superx/bin/UnloadSqlFromXml.java

@ -1,5 +1,6 @@
package de.superx.bin; package de.superx.bin;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
@ -9,10 +10,12 @@ import java.util.logging.Logger;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import de.memtext.util.ExceptionHandler;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
import de.memtext.util.XMLUtils; import de.memtext.util.XMLUtils;
/** /**
* @author Daniel Quathamer Projektgruppe SuperX * @author Daniel Quathamer Projektgruppe SuperX
* UnloadFromXml.java * UnloadFromXml.java
@ -27,128 +30,125 @@ import de.memtext.util.XMLUtils;
*/ */
public class UnloadSqlFromXml { public class UnloadSqlFromXml {
String delim = "^"; String delim = "^";
String header = "false";
String logfile = "../conf/logging.properties"; String header = "false";
String tabelle = "";
String dbpropfile = "../conf/db.properties"; String logfile = "../conf/logging.properties";
String myElement = "table";
String mySqlAttrib = "script"; String tabelle = "";
String myOutfileAttrib = "unl";
String outformat="txt"; String dbpropfile = "../conf/db.properties";
String outfile="";
private static Document document; String myElement = "table";
//LogUtils logger=null;
public Logger logger = (Logger) Logger.getLogger(SxExtractor.class.toString()); String mySqlAttrib = "script";
//static Logger logger = Logger.getLogger(dosql.class);
private ExceptionHandler exceptionHandler = new ExceptionHandler(false); String myOutfileAttrib = "unl";
private static String usage="-------------------------------------\n"
+"Gebrauch: java de.superx.bin.UnloadTableFromXml -logger=<<Pfad zu logging.properties>> -dbproperties=<<Pfad zu db.properties>> " String outformat = "txt";
+"-xml:<xml-Datei> -element:<XML-Element> -attribute:<XML-Attribut mit Tabellenname> -outFormat:<Ausgabeformat (txt | html | xml)>(optional) "
+" -delim:<delimiter> -header:<mit Spaltenüberschriften (true | false)>(optional) -outfile:<Ausgabedatei>(optional) \n---------------------------------------------------"; String outfile = "";
public UnloadSqlFromXml(String args[]) throws IOException { private static Document document;
String sql="";
String unl=""; //LogUtils logger=null;
String _dateiPfad = ""; public Logger logger = (Logger) Logger.getLogger(SxExtractor.class.toString());
GetOpts.setOpts(args);
String isdrin= GetOpts.isAllRequiredOptionsPresent("-logger,-dbproperties,-xml,-element,-sqlattribute,-outfileattribute"); //static Logger logger = Logger.getLogger(dosql.class);
if(isdrin != null)
{
System.err.println("Folgende Optionen fehlen: " + isdrin); private static String usage = "-------------------------------------\n"
System.err.println(usage); + "Gebrauch: java de.superx.bin.UnloadTableFromXml -logger=<<Pfad zu logging.properties>> -dbproperties=<<Pfad zu db.properties>> "
System.exit(1); + "-xml:<xml-Datei> -element:<XML-Element> -attribute:<XML-Attribut mit Tabellenname> -outFormat:<Ausgabeformat (txt | html | xml)>(optional) "
} + " -delim:<delimiter> -header:<mit Spaltenüberschriften (true | false)>(optional) -outfile:<Ausgabedatei>(optional) \n---------------------------------------------------";
//GetOpts myOpts=new GetOpts(); public UnloadSqlFromXml(String args[]) throws IOException, SAXException {
if (GetOpts.isPresent("-logger")) String sql = "";
logfile=GetOpts.getValue("-logger" ); String unl = "";
if (GetOpts.isPresent("-dbproperties")) String _dateiPfad = "";
dbpropfile=GetOpts.getValue("-dbproperties" ); GetOpts.setOpts(args);
if (GetOpts.isPresent("-xml")) //String isdrin = GetOpts.isAllRequiredOptionsPresent("-logger,-dbproperties,-xml,-element,-sqlattribute,-outfileattribute");
_dateiPfad=GetOpts.getValue("-xml" ); String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[] {Options.opt_logger,
if (GetOpts.isPresent("-element")) Options.opt_dbprops,
myElement=GetOpts.getValue("-element" ); Options.opt_xml,
if (GetOpts.isPresent("-sqlattribute")) Options.opt_element,
mySqlAttrib=GetOpts.getValue("-sqlattribute" ); Options.opt_sqlAttribute,
if (GetOpts.isPresent("-outfileattribute")) Options.opt_outfileAttribute});
myOutfileAttrib=GetOpts.getValue("-outfileattribute" ); if (isdrin != null) {
System.err.println("Folgende Optionen fehlen: " + isdrin);
if (GetOpts.isPresent("-outFormat")) System.err.println(usage);
outformat=GetOpts.getValue("-outFormat" ); System.exit(1);
if (GetOpts.isPresent("-delim")) }
delim=GetOpts.getValue("-delim" );
if (GetOpts.isPresent("-header")) //GetOpts myOpts=new GetOpts();
header=GetOpts.getValue("-header" ); if (GetOpts.isPresent(Options.opt_logger)) logfile = GetOpts.getValue(Options.opt_logger);
if (args.length > 0) { if (GetOpts.isPresent(Options.opt_dbprops)) dbpropfile = GetOpts.getValue(Options.opt_dbprops);
logfile = args[0].trim(); if (GetOpts.isPresent(Options.opt_xml)) _dateiPfad = GetOpts.getValue(Options.opt_xml);
} else { if (GetOpts.isPresent(Options.opt_element)) myElement = GetOpts.getValue(Options.opt_element);
System.err.println( if (GetOpts.isPresent(Options.opt_sqlAttribute)) mySqlAttrib = GetOpts.getValue(Options.opt_sqlAttribute);
"Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, Pfad zur SQL-Datei) erfoderlich"); if (GetOpts.isPresent(Options.opt_outfileAttribute)) myOutfileAttrib = GetOpts.getValue(Options.opt_outfileAttribute);
System.exit(1);
} if (GetOpts.isPresent(Options.opt_outFormat)) outformat = GetOpts.getValue(Options.opt_outFormat);
//logger.initRaw(dosql.class) if (GetOpts.isPresent(Options.opt_delim)) delim = GetOpts.getValue(Options.opt_delim);
//PropertyConfigurator.configure(logfile); if (GetOpts.isPresent(Options.opt_header)) header = GetOpts.getValue(Options.opt_header);
File f = new File(logfile); if (args.length > 0) {
if (!f.exists()) { logfile = args[0].trim();
throw new IOException("Datei nicht gefunden: " + logfile); } else {
} System.err.println("Mindestens drei Parameter (Pfad zu den logger.properties, Pfad zu den db.properties, Pfad zur SQL-Datei) erfoderlich");
FileInputStream ins = new FileInputStream(logfile); System.exit(1);
LogManager MyLogManager = java.util.logging.LogManager.getLogManager(); }
MyLogManager.readConfiguration(ins); //logger.initRaw(dosql.class)
logfile = MyLogManager.getProperty(".level"); //PropertyConfigurator.configure(logfile);
logger.info("Using Loggging-Level " + logfile); File f = new File(logfile);
if (!f.exists()) {
throw new IOException("Datei nicht gefunden: " + logfile);
}
//XMLUtils myUtils=new XMLUtils(); FileInputStream ins = new FileInputStream(logfile);
XMLUtils.getExceptionHandler().setWithGui(false); LogManager MyLogManager = java.util.logging.LogManager.getLogManager();
XMLUtils.getExceptionHandler().setExitWanted(true); MyLogManager.readConfiguration(ins);
logfile = MyLogManager.getProperty(".level");
document = XMLUtils.buildDocument(new File(_dateiPfad), false); logger.info("Using Loggging-Level " + logfile);
NodeList myNodes = document.getElementsByTagName(myElement);
document = XMLUtils.buildDocument(new File(_dateiPfad), false);
for (int i = 0; i < myNodes.getLength(); i++) { NodeList myNodes = document.getElementsByTagName(myElement);
Node myNode = myNodes.item(i);
if (myNode.getNodeType() == Node.TEXT_NODE) for (int i = 0; i < myNodes.getLength(); i++) {
continue; Node myNode = myNodes.item(i);
sql = XMLUtils.getAttribValue(myNode, mySqlAttrib); if (myNode.getNodeType() == Node.TEXT_NODE) continue;
unl = XMLUtils.getAttribValue(myNode, myOutfileAttrib); sql = XMLUtils.getAttribValue(myNode, mySqlAttrib);
if(!sql.equals("") && !unl.equals("")) unl = XMLUtils.getAttribValue(myNode, myOutfileAttrib);
{ if (!sql.equals("") && !unl.equals("")) {
String[] myArgs= new String[10]; String[] myArgs = new String[10];
myArgs[0]=args[0].trim(); //logfile myArgs[0] = args[0].trim(); //logfile
myArgs[1]=args[1].trim(); //db.properties myArgs[1] = args[1].trim(); //db.properties
myArgs[2]=sql; myArgs[2] = sql;
myArgs[3]=outformat; //outformat myArgs[3] = outformat; //outformat
myArgs[4]=delim; //_delim myArgs[4] = delim; //_delim
myArgs[5]=header; //header myArgs[5] = header; //header
myArgs[6]=unl; myArgs[6] = unl;
try { try {
de.superx.bin.Dosql.execute(myArgs); de.superx.bin.Dosql.execute(myArgs);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
System.out.println(sql); System.out.println(sql);
} }
} }
} }
public static void main(String args[]) { public static void main(String args[]) {
try { try {
UnloadSqlFromXml test = new UnloadSqlFromXml(args); UnloadSqlFromXml test = new UnloadSqlFromXml(args);
} catch (Exception ex) { } catch (Exception ex) {
System.err.println("Exception caught.\n" + ex); System.err.println("Fehler: " + ex);
ex.printStackTrace(); ex.printStackTrace();
} }
} }
private void severeEnd(String txt) {
logger.severe(txt); }
System.exit(-1);
}
}

79
src/de/superx/bin/Upgrade.java

@ -11,48 +11,47 @@ import java.util.StringTokenizer;
*/ */
public class Upgrade { public class Upgrade {
/** /**
* @param args Datei obsoletfiles.txt mit zu löschenden Dateien * @param args Datei obsoletfiles.txt mit zu löschenden Dateien
* eine Datei obsoletfiles.txt in superx/WEB-INF/conf anlegen. * eine Datei obsoletfiles.txt in superx/WEB-INF/conf anlegen.
~Darin immer eine Zeile pro alter Jar ausgehend von Verzeichnis tomcat/webapps/superx, also z.B. ~Darin immer eine Zeile pro alter Jar ausgehend von Verzeichnis tomcat/webapps/superx, also z.B.
WEB-INF/lib/poixxx.jar WEB-INF/lib/poixxx.jar
* @throws IOException * @throws IOException
*/ */
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
if (args.length == 0) { if (args.length == 0) {
System.out System.out.println("Aufruf java -cp superx4.1.jar de.superx.bin.Upgrade /path/to/superx/WEB-INF/conf/obsoletfiles.txt");
.println("Aufruf java -cp superx4.1.jar de.superx.bin.Upgrade /path/to/superx/WEB-INF/conf/obsoletfiles.txt"); System.out.println("In der Datei können zu löschende Dateien ausgehend von tomcat/webapps/superx angegeben werden, z.B. WEB-INF/lib/poi2.5.jar (keine * moeglich)");
System.out.println("In der Datei können zu löschende Dateien ausgehend von tomcat/webapps/superx angegeben werden, z.B. WEB-INF/lib/poi2.5.jar (keine * moeglich)");
} else { } else {
deleteObsoleteFiles(args[0]); deleteObsoleteFiles(args[0]);
} }
} }
/** /**
* auch in WebFrontendForModuleInstall enthalten * auch in WebFrontendForModuleInstall enthalten
* gut wäre verlagerung nach hosu * gut wäre verlagerung nach hosu
* @param filename * @param filename
* @throws IOException * @throws IOException
*/ */
private static void deleteObsoleteFiles(String filename) throws IOException { private static void deleteObsoleteFiles(String filename) throws IOException {
File f = new File(filename); File f = new File(filename);
String pfad=f.getParentFile().getParentFile().getParentFile().getAbsolutePath(); String pfad = f.getParentFile().getParentFile().getParentFile().getAbsolutePath();
if (f.exists()) { if (f.exists()) {
String obfiles = de.memtext.util.StringUtils.readFile(f); String obfiles = de.memtext.util.StringUtils.readFile(f);
StringTokenizer st = new StringTokenizer(obfiles, "\n"); StringTokenizer st = new StringTokenizer(obfiles, "\n");
while (st.hasMoreTokens()) { while (st.hasMoreTokens()) {
String afilename = st.nextToken();
if (afilename.startsWith("#")) continue;
File fi = new File(pfad+File.separator+afilename.trim());
if (fi.exists())
{ fi.delete();
System.out.println(fi+" deleted");
}
}
} String afilename = st.nextToken();
} if (afilename.startsWith("#")) continue;
File fi = new File(pfad + File.separator + afilename.trim());
if (fi.exists()) {
fi.delete();
System.out.println(fi + " deleted");
}
}
}
}
} }
// created at 16.8.2011 // created at 16.8.2011

171
src/de/superx/bin/UploadRecords.java

@ -1,85 +1,86 @@
package de.superx.bin; package de.superx.bin;
import de.superx.common.FileToTableUploader; import de.superx.common.FileToTableUploader;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
/*
* @author Daniel Quathamer Projektgruppe SuperX /*
* upload_records.java * @author Daniel Quathamer Projektgruppe SuperX
* Dieses Javaprogramm lädt Inhalte einer Datei in eine Tabelle hoch") * upload_records.java
* DQ 5.1.2006 Upload vom XML-Dateien möglich * Dieses Javaprogramm lädt Inhalte einer Datei in eine Tabelle hoch")
* * DQ 5.1.2006 Upload vom XML-Dateien möglich
*/ *
*/
public class UploadRecords {
private static String usage = public class UploadRecords {
"-------------------------------------\n" private static String usage =
+ "Gebrauch: java de.superx.bin.UploadRecords \n-dbproperties:<Pfad zu db.properties> \n" "-------------------------------------\n"
+ "-table:<Tabellenname> \n-unl:<Dateipfad Quelldatei>(optional, default ist Tabellenname.unl) \n-delim:<delimiter>(optional, default ist ^) \n-header:<true|false>(optional, mit Feldüberschriften, default ist false)\n" + "Gebrauch: java de.superx.bin.UploadRecords \n-dbproperties:<Pfad zu db.properties> \n"
+ "-mode:<stop|exclude-row>(optional, default is stop) #Bei Fehlerhaften Daten kann das Hochladen gestoppt werden, oder der Datensatz wird übersprungen" + "-table:<Tabellenname> \n-unl:<Dateipfad Quelldatei>(optional, default ist Tabellenname.unl) \n-delim:<delimiter>(optional, default ist ^) \n-header:<true|false>(optional, mit Feldüberschriften, default ist false)\n"
+ "\n-inserts:<false|simple|batch>(optional, default is false) #Bei -inserts:simple und batch werden Die Rohdaten in Insert-sql-Statements übersetzt (nur für Debugging-Zwecke, sehr langsam. Der Modus exclude-field ist darüberhinaus nicht anwendbar)" + "-mode:<stop|exclude-row>(optional, default is stop) #Bei Fehlerhaften Daten kann das Hochladen gestoppt werden, oder der Datensatz wird übersprungen"
+ "\n-encoding:<utf8,ISO-8859-1, default ist System.file.encoding>" + "\n-inserts:<false|simple|batch>(optional, default is false) #Bei -inserts:simple und batch werden Die Rohdaten in Insert-sql-Statements übersetzt (nur für Debugging-Zwecke, sehr langsam. Der Modus exclude-field ist darüberhinaus nicht anwendbar)"
+ "\n---------------------------------------------------"; + "\n-encoding:<utf8,ISO-8859-1, default ist System.file.encoding>"
+ "\n---------------------------------------------------";
public static void main(String args[]) {
try { public static void main(String args[]) {
GetOpts.setOpts(args); try {
String isdrin = GetOpts.setOpts(args);
GetOpts.isAllRequiredOptionsPresent("-dbproperties,-table,-unl"); String isdrin =
if (isdrin != null) { GetOpts.isAllRequiredOptionsPresent(new Options[] {Options.opt_dbprops,Options.opt_table,Options.opt_unl});
System.err.println("Folgende Optionen fehlen: " + isdrin); if (isdrin != null) {
System.err.println(usage); System.err.println("Folgende Optionen fehlen: " + isdrin);
System.exit(1); System.err.println(usage);
} System.exit(1);
FileToTableUploader myUploader=new FileToTableUploader(); }
//GetOpts myOpts=new GetOpts(); FileToTableUploader myUploader=new FileToTableUploader();
if (GetOpts.isPresent("-dbproperties")) //GetOpts myOpts=new GetOpts();
myUploader.setDbpropfile(GetOpts.getValue("-dbproperties")); if (GetOpts.isPresent(Options.opt_dbprops))
if (GetOpts.isPresent("-informat")) myUploader.setDbpropfile(GetOpts.getValue(Options.opt_dbprops));
myUploader.setInFormat(GetOpts.getValue("-informat")); if (GetOpts.isPresent(Options.opt_inFormat))
if (GetOpts.isPresent("-table")) myUploader.setInFormat(GetOpts.getValue(Options.opt_inFormat));
myUploader.setTargetTable( GetOpts.getValue("-table")); if (GetOpts.isPresent(Options.opt_table))
myUploader.setTargetTable( GetOpts.getValue(Options.opt_table));
if (GetOpts.isPresent("-unl"))
myUploader.setSrcFile(GetOpts.getValue("-unl")); if (GetOpts.isPresent(Options.opt_unl))
else myUploader.setSrcFile(GetOpts.getValue(Options.opt_unl));
myUploader.setSrcFile(myUploader.getTargetTable() + ".unl"); else
if (GetOpts.isPresent("-header")) myUploader.setSrcFile(myUploader.getTargetTable() + ".unl");
myUploader.setHeader(GetOpts.getValue("-header").equalsIgnoreCase("true")?true:false); if (GetOpts.isPresent(Options.opt_header))
if (GetOpts.isPresent("-delim")) myUploader.setHeader(GetOpts.getValue(Options.opt_header).equalsIgnoreCase("true")?true:false);
myUploader.setDelim(GetOpts.getValue("-delim")); if (GetOpts.isPresent(Options.opt_delim))
if (GetOpts.isPresent("-encoding")) myUploader.setDelim(GetOpts.getValue(Options.opt_delim));
{ if (GetOpts.isPresent(Options.opt_encoding))
String encodingParam=GetOpts.getValue("-encoding"); {
String encodingParam=GetOpts.getValue(Options.opt_encoding);
if(encodingParam != null && !encodingParam.equals("") )
myUploader.setEncoding(encodingParam); if(encodingParam != null && !encodingParam.equals("") )
} myUploader.setEncoding(encodingParam);
else }
myUploader.setEncoding(System.getProperty("file.encoding")); else
if (GetOpts.isPresent("-mode")) { myUploader.setEncoding(System.getProperty("file.encoding"));
myUploader.setMode(GetOpts.getValue("-mode").toLowerCase()); if (GetOpts.isPresent(Options.opt_mode)) {
myUploader.setMode(GetOpts.getValue(Options.opt_mode).toLowerCase());
}
if (GetOpts.isPresent("-inserts")) }
myUploader.setInserts(GetOpts.getValue("-inserts")); if (GetOpts.isPresent(Options.opt_inserts))
long jetzt = new java.util.Date().getTime() ; myUploader.setInserts(GetOpts.getValue(Options.opt_inserts));
myUploader.setUploadConnection(myUploader.getConnection(null,myUploader.getDbpropfile())); long jetzt = new java.util.Date().getTime() ;
String protokoll=myUploader.uploadFile(); myUploader.setUploadConnection(myUploader.getConnection(null,myUploader.getDbpropfile()));
long erstrecht = new java.util.Date().getTime() ; String protokoll=myUploader.uploadFile();
System.out.println(myUploader.numberOfRows+" lines loaded"); long erstrecht = new java.util.Date().getTime() ;
System.out.println("File "+myUploader.getSrcFile() +" uploaded"); System.out.println(myUploader.numberOfRows+" lines loaded");
if(protokoll.equals("")) System.out.println("File "+myUploader.getSrcFile() +" uploaded");
protokoll= " in "+(erstrecht-jetzt)/1000 +" Sec."; if(protokoll.equals(""))
System.out.println(protokoll); protokoll= " in "+(erstrecht-jetzt)/1000 +" Sec.";
System.out.println(protokoll);
} catch (Exception ex) {
System.err.println("Upload fehlgeschlagen: " + ex); } catch (Exception ex) {
System.exit(1); System.err.println("Upload fehlgeschlagen: " + ex);
} System.exit(1);
} }
} }
}

143
src/de/superx/bin/WebserviceChecker.java

@ -1,97 +1,110 @@
package de.superx.bin; package de.superx.bin;
import java.io.BufferedReader; import java.io.BufferedWriter;
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileReader; import java.io.FileWriter;
import java.io.IOException; import java.util.logging.Logger;
import java.io.StringWriter;
import java.nio.charset.Charset;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPConnection; import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory; import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage; import javax.xml.soap.SOAPMessage;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer; import de.memtext.util.LogUtils;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
public class WebserviceChecker extends AbstractWebserviceClient { public class WebserviceChecker extends AbstractWebserviceClient {
public static String[] args; public static String[] args;
public void run() private static final Logger log = Logger.getLogger("wc");
{
public void run() {
String testparam = "";
if (args.length > 3)
testparam = args[3];
if (testparam.equals("multipletests"))
multipletests();
else {
singlerun();
}
}
private void singlerun() {
SOAPMessage soapResponse = null;
try { try {
// Create SOAP Connection // Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
.newInstance(); SOAPConnection soapConnection = soapConnectionFactory.createConnection();
SOAPConnection soapConnection = soapConnectionFactory
.createConnection();
// Send SOAP Message to SOAP Server // Send SOAP Message to SOAP Server
String url = readFile(new File(args[1])); StringBuffer url = readFile(new File(args[1]));
SOAPMessage sr = getSoapMessageFromString(readFile(new File(args[0]))); SOAPMessage sr = getSoapMessageFromString(readFile(new File(args[0])).toString());
sr.getMimeHeaders().addHeader("SOAPAction",
"http://sap.com/xi/WebService/soap1.1");
SOAPMessage soapResponse = soapConnection.call(sr, url); addAuthentification(sr);
sr.getMimeHeaders().addHeader("SOAPAction", "http://sap.com/xi/WebService/soap1.1");
soapResponse = soapConnection.call(sr, adaptURL(url.toString()));
ByteArrayOutputStream out = new ByteArrayOutputStream();
Transformer transformer = TransformerFactory.newInstance() soapResponse.writeTo(out);
.newTransformer(); String strMsg = new String(out.toByteArray());
// optional indenting
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(new DOMSource(soapResponse.getSOAPPart()), /**
new StreamResult(new File(args[2]))); * old code problem with namespace when using OpenJDK 15 Transformer transformer
* = TransformerFactory.newInstance() .newTransformer();
*
* // optional indenting transformer.setOutputProperty(OutputKeys.INDENT,
* "yes"); transformer.setOutputProperty(
* "{http://xml.apache.org/xslt}indent-amount", "2"); //new
* DOMSource(soapResponse.getSOAPPart().
*
* transformer.transform(new DOMSource(soapResponse.getSOAPPart()), new
* StreamResult(new File(args[2])));
*
*/
BufferedWriter writer = new BufferedWriter(new FileWriter(args[2]));
writer.write(format(strMsg));
writer.close();
soapConnection.close(); soapConnection.close();
} catch (Exception e) { } catch (Exception e) {
System.out.println("Es ist ein Fehler aufgetreten: " + e);
try {
System.out.println(soapResponse.getSOAPPart().getChildNodes().item(0));
} catch (Exception e1) {
}
e.printStackTrace();
}
}
private void multipletests() {
System.out.println("Versuche ggfs. mehrfach aufzurufen");
try {
LogUtils.initRawFileDateTime("wc", "WebserviceClient.log", 100000, 1, true, false);
StringBuffer url = readFile(new File(args[1]));
File f = createSoapFile(readFile(new File(args[0])).toString(), adaptURL(url.toString()));
System.out.println("Outfile: " + f);
} catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static void main(String a[])
{ public static void main(String a[]) {
args=a; args = a;
if (args.length != 3) { if (args.length < 3 || args.length > 4) {
System.out System.out
.println("Usage path/to/envelope.xml path/to/urlfile /path/to/ouputfile.xml"); .println("Usage path/to/envelope.xml path/to/urlfile /path/to/ouputfile.xml optional:multipleruns");
System.exit(-1); System.exit(-1);
} }
WebserviceChecker wc=new WebserviceChecker(); WebserviceChecker wc = new WebserviceChecker();
wc.run(); wc.run();
} }
private static SOAPMessage getSoapMessageFromString(String xml)
throws SOAPException, IOException {
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory
.createMessage(
new MimeHeaders(),
new ByteArrayInputStream(xml.getBytes(Charset
.forName("UTF-8"))));
return message;
}
private static String readFile(File f) throws IOException {
FileReader fr = new FileReader(f);
BufferedReader bfr = new BufferedReader(fr);
String line;
StringBuffer result = new StringBuffer();
while ((line = bfr.readLine()) != null) {
result.append(line + "\n");
}
bfr.close();
fr.close();
return result.toString();
}
} }

271
src/de/superx/bin/WebserviceClient.java

@ -2,10 +2,8 @@ package de.superx.bin;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.PrintWriter; import java.io.IOException;
import java.io.StringWriter; import java.nio.file.Files;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -14,13 +12,16 @@ import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.transform.TransformerException;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import de.memtext.util.DateUtils; import de.memtext.util.DateUtils;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
import de.memtext.util.LogUtils; import de.memtext.util.LogUtils;
import de.memtext.util.StringUtils; import de.memtext.util.StringUtils;
import de.memtext.util.XMLUtils; import de.memtext.util.XMLUtils;
@ -43,7 +44,7 @@ public class WebserviceClient extends AbstractWebserviceClient{
private String stammdatenstart=null; private String stammdatenstart=null;
private boolean isDeleteTmpXmlFileWanted = true; private boolean isDeleteTmpXmlFileWanted = true;
private static final Logger log = Logger.getLogger("wc");
private static final String FISTL_HIERARCHIE_INFO = "<EX_FMHISV> \n" + private static final String FISTL_HIERARCHIE_INFO = "<EX_FMHISV> \n" +
" <item> \n" + " <item> \n" +
@ -61,32 +62,24 @@ public class WebserviceClient extends AbstractWebserviceClient{
public static void main(String args[]) { public static void main(String args[]) {
System.out.println("SuperX-WebserviceClient Version 0.9.8"); System.out.println("SuperX-WebserviceClient Version 1.4 (2025-02-25)");
WebserviceClient tc = new WebserviceClient(); WebserviceClient tc = new WebserviceClient();
tc.run(args); tc.run(args);
} }
public WebserviceClient() public WebserviceClient()
{ {
} }
public void run(String args[]) { public void run(String args[]) {
try { try {
initLogging();
XMLUtils.getExceptionHandler().setWithGui(false);
XMLUtils.getExceptionHandler().setExitWanted(true);
// LogUtils.initRaw(log);
LogUtils.initRawFileDateTime("wc", "WebserviceClient.log", 100000,
1, true, false);
log.setLevel(Level.FINEST);
log.getHandlers()[0].setLevel(Level.FINEST);
GetOpts.setOpts(args); GetOpts.setOpts(args);
String isdrin = GetOpts String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[] {Options.opt_dbprops,
.isAllRequiredOptionsPresent("-dbproperties,-xmlconfig,-xsl,-hsnr,-out"); Options.opt_xmlconfig,
Options.opt_xsl,
Options.opt_hsnr,
Options.opt_out});
if (isdrin != null) { if (isdrin != null) {
System.err.println("Folgende Optionen fehlen: " + isdrin); System.err.println("Folgende Optionen fehlen: " + isdrin);
// System.err.println(usage); // System.err.println(usage);
@ -106,12 +99,12 @@ public class WebserviceClient extends AbstractWebserviceClient{
String msg = "Error: Aufruf von Webservice für " + xmlConfig String msg = "Error: Aufruf von Webservice für " + xmlConfig
+ " fehlgeschlagen"; + " fehlgeschlagen";
System.out.println(msg); System.out.println(msg);
log.severe(msg); logger.severe(msg);
LogUtils.close("wc"); LogUtils.close("wc");
System.exit(-1); System.exit(-1);
} }
} catch (Exception e) { } catch (Exception e) {
log.severe(e.getMessage()); logger.severe(e.getMessage());
System.out.println("Error " + e.getMessage()); System.out.println("Error " + e.getMessage());
e.printStackTrace(); e.printStackTrace();
LogUtils.close("wc"); LogUtils.close("wc");
@ -125,42 +118,39 @@ public class WebserviceClient extends AbstractWebserviceClient{
String soapString = StringUtils.replace(changesSOAP, String soapString = StringUtils.replace(changesSOAP,
"XXOBJECT_CLASSXX", objectClass); "XXOBJECT_CLASSXX", objectClass);
String startDatum = getStartDatum(); String startDatum = getStartDatum();
log.log(Level.INFO, "Startdatum " + startDatum); logger.log(Level.INFO, "Startdatum " + startDatum);
System.out.println("Startdatum " + startDatum); System.out.println("Startdatum " + startDatum);
soapString = StringUtils.replace(soapString, "XXSTARTDATEXX", soapString = StringUtils.replace(soapString, "XXSTARTDATEXX",
startDatum); startDatum);
soapString = StringUtils.replace(soapString, "XXTODAYXX", soapString = StringUtils.replace(soapString, "XXTODAYXX",
new java.sql.Date(new java.util.Date().getTime()).toString()); new java.sql.Date(new java.util.Date().getTime()).toString());
log.fine("SOAP Aufruf:\n" + soapString); logger.fine("SOAP Aufruf:\n" + soapString);
String result= readSOAP(soapString, changesURL).toString(); String result= readSOAP(soapString, changesURL).toString();
document = XMLUtils.buildDocumentFromString(result, false); document = XMLUtils.buildDocumentFromString(result, false);
log.finest("Geaenderte Objekte Klasse " + objectClass);
// log.finest(sw.toString()); logger.finest("Geaenderte Objekte Klasse " + objectClass);
// log.finest(
// "-----------------------------------------");
} }
private void readConfig() { private void readConfig() throws IOException, SAXException {
dbpropfile = GetOpts.getValue("-dbproperties"); dbpropfile = GetOpts.getValue(Options.opt_dbprops);
xmlConfig = GetOpts.getValue("-xmlconfig"); xmlConfig = GetOpts.getValue(Options.opt_xmlconfig);
outfile = GetOpts.getValue("-out"); outfile = GetOpts.getValue(Options.opt_out);
xsl = GetOpts.getValue("-xsl"); xsl = GetOpts.getValue(Options.opt_xsl);
hsnr = GetOpts.getValue("-hsnr"); hsnr = GetOpts.getValue(Options.opt_hsnr);
System.out.println("\n" + DateUtils.getTodayString() + " " System.out.println("\n" + DateUtils.getTodayString() + " "
+ DateUtils.getNowString() + "\nHochschulnummer " + hsnr); + DateUtils.getNowString() + "\nHochschulnummer " + hsnr);
log.info("\nHochschulnummer " + hsnr); logger.info("\nHochschulnummer " + hsnr);
if (GetOpts.isPresent("-nodelete")) if (GetOpts.isPresent(Options.opt_noDelete))
isDeleteTmpXmlFileWanted = false; isDeleteTmpXmlFileWanted = false;
if (GetOpts.isPresent("-pause")) { if (GetOpts.isPresent(Options.opt_pause)) {
String p = GetOpts.getValue("-pause"); String p = GetOpts.getValue(Options.opt_pause);
pause = Integer.parseInt(p); pause = Integer.parseInt(p);
System.out.println("Pause between soap calls " + pause); System.out.println("Pause between soap calls " + pause);
} }
log.log(Level.INFO, "Verarbeite " + xmlConfig); logger.log(Level.INFO, "Verarbeite " + xmlConfig);
System.out.println("Verarbeite " + xmlConfig); System.out.println("Verarbeite " + xmlConfig);
Document dconf = XMLUtils.buildDocument(new File(xmlConfig)); Document dconf = XMLUtils.buildDocument(new File(xmlConfig));
@ -182,9 +172,6 @@ public class WebserviceClient extends AbstractWebserviceClient{
detailSOAP = XMLUtils.getTheValue(n); detailSOAP = XMLUtils.getTheValue(n);
n = XMLUtils.getFirstNode(dconf, "replacenode"); n = XMLUtils.getFirstNode(dconf, "replacenode");
replaceNodeName = XMLUtils.getAttribValue(n, "from"); replaceNodeName = XMLUtils.getAttribValue(n, "from");
} }
@ -205,88 +192,165 @@ public class WebserviceClient extends AbstractWebserviceClient{
} }
System.out.println("Zu loeschen " + deletedObjects.size() System.out.println("Zu loeschen " + deletedObjects.size()
+ " neu/geaendert " + newOrUpdatedObjects.size()); + " neu/geaendert " + newOrUpdatedObjects.size());
log.info("Anzahl zu loeschender Objekte " + deletedObjects.size()); logger.info("Anzahl zu loeschender Objekte " + deletedObjects.size());
log.info("Anzahl zu neuer/geaenderter Objekte " logger.info("Anzahl zu neuer/geaenderter Objekte "
+ newOrUpdatedObjects.size()); + newOrUpdatedObjects.size());
} }
private boolean isJestWanted()
{
return objectClass.equals("PRPS");
}
private void writeChangeXml() throws Exception { private void writeChangeXml() throws Exception {
File f = File.createTempFile("webservicedata", ".xml"); File f = File.createTempFile("webservicedata", ".xml");
// File f=new File("tmpwebservice.xml"); File fjest=null;
if (isJestWanted()) fjest=File.createTempFile("webservicedatajest",".xml");
if (!isDeleteTmpXmlFileWanted) { if (!isDeleteTmpXmlFileWanted) {
System.out.println("Temp Datei: " + f.getAbsolutePath()); System.out.println("Temp Datei: " + f.getAbsolutePath());
log.info("Temp Datei: " + f.getAbsolutePath()); logger.info("Temp Datei: " + f.getAbsolutePath());
if (isJestWanted())
{
System.out.println("Temp Datei: " + fjest.getAbsolutePath());
logger.info("Temp Datei: " + fjest.getAbsolutePath());
}
} }
if (f.exists()) if (f.exists())
f.delete(); f.delete();
// FileWriter fw = new FileWriter(f); if (fjest!=null&&fjest.exists()) fjest.delete();
PrintWriter fw = new PrintWriter(f, "UTF-8"); BufferedWriter bfw= Files.newBufferedWriter(f.toPath());
// FileOutputStream fos = new FileOutputStream(f, false);
// BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(fos));
BufferedWriter bfw = new BufferedWriter(fw);
bfw.write("<newdata>\n"); bfw.write("<newdata>\n");
BufferedWriter bfwjest=null;
if (isJestWanted())
{
bfwjest= Files.newBufferedWriter(fjest.toPath());
bfwjest.write("<newdata>\n");
}
int i = 0; int i = 0;
int rownr=1; int rownr=0;
System.out.println(DateUtils.getTodayString() + " " System.out.println(DateUtils.getTodayString() + " "
+ DateUtils.getNowString()); + DateUtils.getNowString());
String reply=null,replyjest=null;
for (Iterator<String> it = newOrUpdatedObjects.iterator(); it.hasNext();) { for (Iterator<String> it = newOrUpdatedObjects.iterator(); it.hasNext();) {
String objectId = it.next(); String objectId = it.next();
//für Debugging Tests
//if (objectId.indexOf("0000131400")==-1) continue;
// Hier wird Detailrequest aufgerufen // Hier wird Detailrequest aufgerufen
String reply = getSoapDetailRequest(objectId, i); reply = getSoapDetailRequest(objectId, i);
i++; i++;
if (i % 10 == 0) if (i % 10 == 0)
System.out.print(i + " "); System.out.print(i + " ");
//bei nicht vollstaendig angelegten Kostenarten ueberspringen //bei nicht vollstaendig angelegten Kostenarten ueberspringen
if (objectClass.equals("KSTAR")&&reply.indexOf("<EX_CSKB/>")>-1) if (objectClass.equals("KSTAR")&&reply.indexOf("<EX_CSKB/>")>-1)
continue; continue;
if (reply.indexOf("<MESSAGE>Es wurden 0000 S")>-1) if (reply.indexOf("<MESSAGE>Es wurden 0000")>-1)
continue; continue;
//bei Finanzstellen ggfs. fehlende Hierarchieinformation durch Dummy ersetzen //bei Finanzstellen ggfs. fehlende Hierarchieinformation durch Dummy ersetzen
if (objectClass.equals("FMFCTR")) if (objectClass.equals("FMFCTR"))
reply=patchMissingFistlHierarchieInfo(reply); reply=patchMissingFistlHierarchieInfo(reply);
reply = purge(reply);
reply=StringUtils.replace(reply, "<SOAP:Envelope","<SOAP:Envelope rownr=\""+rownr+"\" "); if (isJestWanted())
{
replyjest = adaptJestData(reply, objectId);
}
rownr++; rownr++;
if (!isDebug && reply.indexOf("<TYPE>I</TYPE>") == -1) { if (!isDebug && reply.indexOf("<TYPE>I</TYPE>") == -1) {
System.out.println("Fehler bei Lesen von Object " + objectId); System.out.println("Fehler bei Lesen von Object " + objectId);
System.out.println(reply); System.out.println(reply);
bfw.close(); bfw.close();
fw.close();
if (f.exists()) if (f.exists())
f.delete(); f.delete();
if (isJestWanted())
{ bfwjest.close();if (fjest.exists()) fjest.delete();};
System.exit(-1); System.exit(-1);
} }
//Nachbearbeitung
bfw.write(reply.replaceAll( reply=StringUtils.replace(reply, "<Envelope","<Envelope rownr=\""+rownr+"\" ");
"<\\?xml version=\"1.0\" encoding=\".*>", "")); reply = nachbearbeiten(reply);
// System.out.println(objectId + " xxx" + reply); bfw.write(reply);
if (isJestWanted())
// if (i > 20) break; {
}
replyjest=purge(replyjest,"RETURN");
replyjest=nachbearbeiten(replyjest);
bfwjest.write(replyjest);
}
}
System.out.println(""); System.out.println("");
bfw.write("\n</newdata>\n"); bfw.write("\n</newdata>\n");
bfw.close(); bfw.close();
fw.close();
if (isJestWanted())
{
bfwjest.write("\n</newdata>\n");
bfwjest.close();
}
transformXmlToCSV(f, fjest);
if (isDeleteTmpXmlFileWanted)
{f.delete();
if (isJestWanted()) fjest.delete();
}
SxTransformer sxTrans = new SxTransformer(log, outfile); System.out.println(" fertig: " + DateUtils.getTodayString() + " "
+ DateUtils.getNowString());
}
private void transformXmlToCSV(File f, File fjest) throws TransformerException, Exception {
SxTransformer sxTrans = new SxTransformer(logger, outfile);
sxTrans.quellstring = f.getAbsolutePath(); sxTrans.quellstring = f.getAbsolutePath();
sxTrans.stylesheet = xsl; sxTrans.stylesheet = xsl;
sxTrans.params = "ignoreElements=EX_JEST"; sxTrans.params = "ignoreElements=EX_JEST";
sxTrans.transformFile("text"); sxTrans.transformFile("text");
if (isDeleteTmpXmlFileWanted) if (isJestWanted()) {
f.delete(); sxTrans = new SxTransformer(logger, StringUtils.replace(outfile,".","jest."));
sxTrans.quellstring = fjest.getAbsolutePath();
System.out.println(" fertig: " + DateUtils.getTodayString() + " " String xsljest="";
+ DateUtils.getNowString()); if (objectClass.equals("PRPS"))
xsljest=StringUtils.replace(xsl, "soap_to_csv.xsl", "psp_jest.xsl");
sxTrans.stylesheet = xsljest;
sxTrans.params = "";
sxTrans.transformFile("text");
}
}
private String adaptJestData(String reply, String objectId) {
String replyjest;
replyjest=purge(reply,false);
replyjest=replyjest.replaceAll("<Envelope>","");
replyjest=replyjest.replaceAll("<Header>","");
replyjest=replyjest.replaceAll("</Header>","");
replyjest=StringUtils.replace(replyjest, "<Header/>", "");
replyjest=replyjest.replaceAll("</Envelope>","");
replyjest=replyjest.replaceAll("<SOAP:Body>","");
replyjest=replyjest.replaceAll("</SOAP:Body>","");
replyjest=replyjest.replaceAll("<response>","");
replyjest=replyjest.replaceAll("</response>","");
replyjest=purge(replyjest,"EX_PROJ");
replyjest=purge(replyjest,"EX_PRPS");
replyjest=purge(replyjest,"EX_PRHI");
replyjest=StringUtils.replace(replyjest,"<EX_JEST>", "");
replyjest=StringUtils.replace(replyjest,"<EX_JEST/>", "");
replyjest=StringUtils.replace(replyjest,"</EX_JEST>", "");
replyjest=replyjest.replaceAll("<item>","<item>\n<POSID>"+objectId+"</POSID>\n");
//replyjest=replyjest.replaceAll("</item>","</EX_JEST>");
return replyjest;
}
private String nachbearbeiten(String reply) {
reply = purge(reply, true);
reply=adaptDatePattern(reply);
reply=removeXmlHeader(reply);
reply=format(reply);
return reply;
} }
private String patchMissingFistlHierarchieInfo(String input) { private String patchMissingFistlHierarchieInfo(String input) {
String output=StringUtils.replace(input, "<EX_FMHISV/>", FISTL_HIERARCHIE_INFO); return StringUtils.replace(input, "<EX_FMHISV/>", FISTL_HIERARCHIE_INFO);
return output;
} }
private String getStartDatum() throws Exception { private String getStartDatum() throws Exception {
String result = "2000-01-01"; String result = "2000-01-01";
@ -336,51 +400,33 @@ public class WebserviceClient extends AbstractWebserviceClient{
} }
pst.close(); pst.close();
con.close(); con.close();
} }
private String getSoapDetailRequest(String objectid, int i) private String getSoapDetailRequest(String objectid, int i)
throws Exception { throws Exception {
String idpart1="";
if (objectid.length()>=4) idpart1=objectid.substring(0, 4);
String id = objectid.substring(4); String idpart2 ="";
//zum Testen einzelner KSTAR if (!id.equals("0000906510")) return "<TYPE>I</TYPE>"; if (objectid.length()>=5) idpart2=objectid.substring(4);
// if (id.startsWith("0")) String idpart3 = "";
// id = id.substring(1);
String id3 = "";
if (objectid.length() > 8) if (objectid.length() > 8)
id3 = objectid.substring(8); idpart3 = objectid.substring(8);
String soapxml = de.memtext.util.StringUtils.replace(detailSOAP, String soapxml = de.memtext.util.StringUtils.replace(detailSOAP,
"IDPART1", objectid.substring(0, 4)); "IDPART1", idpart1);
soapxml = de.memtext.util.StringUtils.replace(soapxml, "IDPART2", id); soapxml = de.memtext.util.StringUtils.replace(soapxml, "IDPART2", idpart2);
soapxml = de.memtext.util.StringUtils.replace(soapxml, "IDPART3", id3); soapxml = de.memtext.util.StringUtils.replace(soapxml, "IDPART3", idpart3);
soapxml = de.memtext.util.StringUtils.replace(soapxml, "XXOBJECTIDXX", soapxml = de.memtext.util.StringUtils.replace(soapxml, "XXOBJECTIDXX",
objectid); objectid);
soapxml = de.memtext.util.StringUtils soapxml = de.memtext.util.StringUtils
.replace(soapxml, "XXHSNRXX", hsnr); .replace(soapxml, "XXHSNRXX", hsnr);
// System.out.println("looking for "+objectid.substring(0,4)+" "+id);
/*
* soapxml =
* "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:sap-com:document:sap:rfc:functions\"> \n"
* + " <soapenv:Header/> \n" + " <soapenv:Body> \n" +
* " <urn:ZVMWSCO_GET_KOSTL> \n" + " <IM_KOKRS>" +
* objectid.substring(0, 4) + "</IM_KOKRS> \n" + " <IM_KOSTL>" +
* id + "</IM_KOSTL> \n" + " <RETURN/> \n" +
* " </urn:ZVMWSCO_GET_KOSTL> \n" + " </soapenv:Body> \n" +
* "</soapenv:Envelope>";
*/
// String url =
// "https://kpi-nsi.landbw.de/sap/xi/engine?type=entry&amp;version=3.0&amp;Sender.Service=WsHAWCcGetDetailSyn&amp;Interface=http%3A%2F%2Fnsi-cc.bwl.de%2Fhaw%2Fco%5EMiCcGetDetailSynOut";
if (i == 0) if (i == 0)
log.finest("1. SOAP Detailaufruf:\n" + soapxml); logger.finest("1. SOAP Detailaufruf:\n" + soapxml);
String res = readSOAP(soapxml, detailURL).toString(); String res = readSOAP(soapxml, detailURL).toString();
// Document doc=XMLUtils.buildDocumentFromString(sw.toString(), false);
String result = StringUtils.replace(res, replaceNodeName, String result = StringUtils.replace(res, replaceNodeName,
"response"); "response");
return result; return result;
} }
@ -390,9 +436,20 @@ public class WebserviceClient extends AbstractWebserviceClient{
* TODO eigentlich sicherheitshalber gucken unter <RETURN> <item> * TODO eigentlich sicherheitshalber gucken unter <RETURN> <item>
* <TYPE>I</TYPE> TYPE kommt aber nur einmal vor * <TYPE>I</TYPE> TYPE kommt aber nur einmal vor
*/ */
try {
Node type = XMLUtils.getFirstNode(document, "TYPE"); Node type = XMLUtils.getFirstNode(document, "TYPE");
if (XMLUtils.getTheValue(type).equals("I")) if (XMLUtils.getTheValue(type).equals("I"))
result = true; result = true;}
catch (Exception e)
{
logger.severe("Kein Konten TYPE gefunden mit Value I - Result:\n");
try {
logger.severe(XMLUtils.documentToString(document,null));
} catch (Exception ex) {
logger.severe("Fehler bei XML Ausgabe "+ex);
}
}
return result; return result;
} }

749
src/de/superx/bin/WebserviceClientBewegungsdaten.java

@ -1,409 +1,394 @@
package de.superx.bin; package de.superx.bin;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.net.Authenticator.RequestorType;
import java.nio.charset.Charset;
import java.util.Calendar; import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import de.memtext.util.DateUtils; import de.memtext.util.DateUtils;
import de.memtext.util.GetOpts; import de.memtext.util.GetOpts;
import de.memtext.util.GetOpts.Options;
import de.memtext.util.LogUtils; import de.memtext.util.LogUtils;
import de.memtext.util.StringUtils; import de.memtext.util.StringUtils;
import de.memtext.util.XMLUtils; import de.memtext.util.XMLUtils;
public class WebserviceClientBewegungsdaten extends AbstractWebserviceClient { public class WebserviceClientBewegungsdaten extends AbstractWebserviceClient {
private Document configDocument; private Document configDocument;
private XMLInputFactory factory = XMLInputFactory.newInstance(); private XMLInputFactory factory = XMLInputFactory.newInstance();
private String hsnr;
private String hsnr; private String xmlConfig, datentyp;
private String url;
private String xmlConfig, datentyp; private String soap;
private String url;
private String outfilename;
private String soap; private boolean columnNamesWritten = false, columnNamesHdWritten = false;
private File tmpFile, outFile, outFileHd;
private String outfilename; private String jahr;
private boolean columnNamesWritten = false, columnNamesHdWritten = false; private PrintWriter fw, fwhd;
private File tmpFile, outFile, outFileHd; private BufferedWriter bfw, bfwhd;
private String jahr;
private PrintWriter fw, fwhd; private Calendar cal = Calendar.getInstance();
private BufferedWriter bfw, bfwhd;
private static final Logger log = Logger.getLogger("wc"); public static void main(String args[]) {
System.out
public static void main(String args[]) { .println("SuperX-WebserviceClientBewegungsdaten Version 1.4 (2.2.2023)");
System.out WebserviceClientBewegungsdaten tc = new WebserviceClientBewegungsdaten();
.println("SuperX-WebserviceClientBewegungsdaten Version 0.9.3"); tc.run(args);
WebserviceClientBewegungsdaten tc = new WebserviceClientBewegungsdaten(); }
tc.run(args);
} /**
* @deprecated
public WebserviceClientBewegungsdaten() { * @return
*/
} private boolean isWorkaroundNeeded() {
return hsnr.contentEquals("3001")&&jahr.contentEquals("2021") && datentyp.equals("fmifiit");
public void run(String args[]) { }
try { public WebserviceClientBewegungsdaten() {
}
XMLUtils.getExceptionHandler().setWithGui(false);
XMLUtils.getExceptionHandler().setExitWanted(true); public void run(String args[]) {
// LogUtils.initRaw(log); try {
LogUtils.initRawFileDateTime("wc", "WebserviceClient.log", 100000, initLogging();
1, true, false); GetOpts.setOpts(args);
String isdrin = GetOpts.isAllRequiredOptionsPresent(new Options[] {Options.opt_xmlconfig,
log.setLevel(Level.FINEST); Options.opt_hsnr,
log.getHandlers()[0].setLevel(Level.FINEST); Options.opt_jahr,
GetOpts.setOpts(args); Options.opt_out,
String isdrin = GetOpts Options.opt_datentyp});
.isAllRequiredOptionsPresent("-xmlconfig,-hsnr,-jahr,-out,-datentyp"); if (isdrin != null) {
if (isdrin != null) { System.err.println("Folgende Optionen fehlen: " + isdrin);
System.err.println("Folgende Optionen fehlen: " + isdrin); // System.err.println(usage);
// System.err.println(usage); System.exit(1);
System.exit(1); }
} readConfig();
readConfig();
perform();
perform();
String msg = " fertig: " + DateUtils.getTodayString() + " "
String msg = " fertig: " + DateUtils.getTodayString() + " " + DateUtils.getNowString();
+ DateUtils.getNowString(); logger.info(msg);
log.info(msg); System.out.println(msg);
System.out.println(msg); } catch (Exception e) {
} catch (Exception e) { logger.severe(e.getMessage());
log.severe(e.getMessage()); System.out.println("Error " + e.getMessage());
System.out.println("Error " + e.getMessage()); e.printStackTrace();
e.printStackTrace(); LogUtils.close("wc");
LogUtils.close("wc"); System.exit(1);
System.exit(1); } finally {
} finally { LogUtils.close("wc");
LogUtils.close("wc");
}
} }
}
private void perform() throws Exception {
private void perform() throws Exception {
Node n = XMLUtils.getFirstNode(configDocument, datentyp + "detailurl");
Node n = XMLUtils.getFirstNode(configDocument, datentyp + "detailurl"); url = XMLUtils.getTheValue(n);
url = XMLUtils.getTheValue(n); url = adaptURL(url);
url = adaptURL(url); logger.fine("URL:" + url);
n = XMLUtils.getFirstNode(configDocument, datentyp + "detailsoap"); System.out.println("URL:" + url);
soap = XMLUtils.getTheValue(n); n = XMLUtils.getFirstNode(configDocument, datentyp + "detailsoap");
soap = soap.replace("XXHSNRXX", hsnr); soap = XMLUtils.getTheValue(n);
soap = soap.replace("XXJAHRXX", jahr); soap = soap.replace("XXHSNRXX", hsnr);
System.out.println(datentyp + "\n12x " + soap); soap = soap.replace("XXJAHRXX", jahr);
//n = XMLUtils.getFirstNode(configDocument, datentyp + "detailreplacenode"); System.out.println(datentyp + "\nVorlage " + soap);
//n = XMLUtils.getFirstNode(configDocument, datentyp + "detailreplacenode");
initOutFile();
initOutFile();
//Laut Herrn Schweitzer (SAP) keine Daten für Vorjahr und Folgejahr abrufen //Laut Herrn Schweitzer (SAP) keine Daten für Vorjahr und Folgejahr abrufen
// monat 0 ist Vorjahr, Monat 13 ist Folgejahr //sagt aber, dass dann Buchungen im Folgejahr fehlen, daher wieder aktiviert
for (int monat = 1; monat <= 12; monat++) { //Ticket https://hiszilla.his.de/hiszilla/show_bug.cgi?id=169286
//Nach Besprechung/Test mit Herren Kowalke/Weil (BitBw) nicht korrekt, Vor- und Folgejahr müssen abgerufen werden (5/2020)
String monatssoap = getMonatsoap(monat); //nicht ein Geschäftsjahr betreffende Buchungen später per delete entfernt
log.fine(datentyp + "\nSOAP Aufruf:\n" + monatssoap); //https://hiszilla.his.de/hiszilla/show_bug.cgi?id=237395
String msg = "starte Aufruf " + (monat ); // 11/2021 #237395 statt vorjahr und folgejahr längerer Zeitraum
int vorjahr = Integer.parseInt(jahr) - 1;
System.out.print(msg);
tmpFile = createSoapFile(monatssoap, url); runAbruf("1970-01-01", vorjahr + "-01-01");
msg =" - empfangen "; runAbruf(vorjahr + "-01-02", vorjahr + "-01-31");
if (!isDeleteTmpXmlFileWanted) runAbruf(vorjahr + "-02-01", vorjahr + "-03-01");
msg += " (" + tmpFile+")"; runAbruf(vorjahr + "-03-02", vorjahr + "-03-31");
msg+=" "+DateUtils.getNowString(); runAbruf(vorjahr + "-04-01", vorjahr + "-04-30");
System.out.println(msg); runAbruf(vorjahr + "-05-01", vorjahr + "-05-31");
runAbruf(vorjahr + "-06-01", vorjahr + "-06-30");
String nodeName = "EX_" + datentyp.toUpperCase(); runAbruf(vorjahr + "-07-01", vorjahr + "-07-31");
runAbruf(vorjahr + "-08-01", vorjahr + "-08-31");
if (isReplyOk()) { runAbruf(vorjahr + "-09-01", vorjahr + "-09-30");
String columnNames = getColumnNames(nodeName).toString(); runAbruf(vorjahr + "-10-01", vorjahr + "-10-31");
if (!columnNamesWritten && !columnNames.equals("")) { runAbruf(vorjahr + "-11-01", vorjahr + "-11-30");
bfw.write(columnNames); runAbruf(vorjahr + "-12-01", vorjahr + "-12-31");
columnNamesWritten = true; //jetzt jeden Tag einzeln
} int jahrint = Integer.parseInt(jahr);
String data = getData(nodeName).toString(); cal.set(jahrint, 0, 1);
if (!data.equals("")) while (cal.get(1) == jahrint) {
bfw.write(data); String datum = getDateString();
bfw.flush(); runAbruf(datum, datum);
cal.add(6, 1);
// Header }
if (datentyp.equals("fmifiit")) { //jetzt Folgejahre
columnNames = getColumnNames("EX_FMIFIHD").toString(); int folgejahr = Integer.parseInt(jahr) + 1;
if (!columnNamesHdWritten && !columnNames.equals("")) { runAbruf(folgejahr + "-01-01", folgejahr + "-01-31");
bfwhd.write(columnNames); runAbruf(folgejahr + "-02-01", folgejahr + "-03-01");
columnNamesHdWritten = true; runAbruf(folgejahr + "-03-02", folgejahr + "-03-31");
} runAbruf(folgejahr + "-04-01", folgejahr + "-04-30");
data = getData("EX_FMIFIHD").toString(); runAbruf(folgejahr + "-05-01", folgejahr + "-05-31");
if (!data.equals("")) runAbruf(folgejahr + "-06-01", folgejahr + "-06-30");
bfwhd.write(data); runAbruf(folgejahr + "-07-01", folgejahr + "-07-31");
bfwhd.flush(); runAbruf(folgejahr + "-08-01", folgejahr + "-08-31");
} runAbruf(folgejahr + "-09-01", folgejahr + "-09-30");
if (isDeleteTmpXmlFileWanted) runAbruf(folgejahr + "-10-01", folgejahr + "-10-31");
tmpFile.delete(); runAbruf(folgejahr + "-11-01", folgejahr + "-11-30");
runAbruf(folgejahr + "-12-01", folgejahr + "-12-31");
} else { int folgejahr2 = Integer.parseInt(jahr) + 2;
msg = "Error: Aufruf von Webservice für Bewegungsdaten " runAbruf(folgejahr2 + "-01-01", "2100-12-31");
+ datentyp + " (" + xmlConfig + ") fehlgeschlagen";
System.out.println(msg); closeFile();
System.out.println(StringUtils.readFile(tmpFile)); }
log.severe(msg);
LogUtils.close("wc");
System.exit(-1); private String getDateString() {
} int month = cal.get(2) + 1;
String monthstr = "" + month + "";
} if (month < 10) {
closeFile(); monthstr = "0" + month;
} }
int day = cal.get(5);
private String getMonatsoap(int monat) { String daystring = "" + day + "";
String tempsoap = soap; if (day < 10) {
if (monat == 0) { daystring = "0" + day;
int vorjahr = Integer.parseInt(jahr); }
vorjahr--; String result = "" + cal.get(1) + "-" + monthstr + "-" + daystring;
tempsoap = tempsoap.replaceAll("XXSTARTXX", vorjahr + "-01-01"); return result;
tempsoap = tempsoap.replaceAll("XXENDEXX", vorjahr + "-12-31"); }
}
if (monat >= 1 && monat <= 12) { protected void runAbruf(String datevon, String datebis) throws Exception, XMLStreamException, IOException {
int jahrint = Integer.parseInt(jahr); String soap = getSoap(datevon, datebis);
GregorianCalendar cal = new GregorianCalendar(jahrint,monat-1, 1); logger.fine(datentyp + "\nSOAP Aufruf:\n" + soap);
String monatstr; String msg = "starte Aufruf fuer " + datevon + " bis " + datebis;
if (monat < 10)
monatstr = "0" + monat; System.out.println(msg);
else
monatstr = monat + ""; tmpFile = createSoapFile(soap, url);
tempsoap = tempsoap.replaceAll("XXSTARTXX", jahr + "-" + monatstr msg = " - empfangen ";
+ "-01"); if (!isDeleteTmpXmlFileWanted)
int maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH); msg += " (" + tmpFile + ")";
// System.out.println(maxDay); msg += " " + DateUtils.getNowString();
tempsoap = tempsoap.replaceAll("XXENDEXX", jahr + "-" + monatstr System.out.println(msg);
+ "-" + maxDay);
} String nodeName = "EX_" + datentyp.toUpperCase();
if (monat == 13) { if (isReplyOk(tmpFile)) {
int folgejahr = Integer.parseInt(jahr); String columnNames = getColumnNames(nodeName).toString();
folgejahr++; if (!columnNamesWritten && !columnNames.equals("")) {
tempsoap = tempsoap.replaceAll("XXSTARTXX", folgejahr + "-01-01"); bfw.write(columnNames);
tempsoap = tempsoap.replaceAll("XXENDEXX", folgejahr + "-12-31"); columnNamesWritten = true;
} }
return tempsoap; String data = getData(nodeName).toString();
} if (!data.equals(""))
bfw.write(data);
private void readConfig() { bfw.flush();
xmlConfig = GetOpts.getValue("-xmlconfig"); // Header
outfilename = GetOpts.getValue("-out"); if (datentyp.equals("fmifiit")) {
columnNames = getColumnNames("EX_FMIFIHD").toString();
hsnr = GetOpts.getValue("-hsnr"); if (!columnNamesHdWritten && !columnNames.equals("")) {
jahr = GetOpts.getValue("-jahr"); bfwhd.write(columnNames);
datentyp = GetOpts.getValue("-datentyp"); columnNamesHdWritten = true;
System.out.println("\n" + DateUtils.getTodayString() + " " }
+ DateUtils.getNowString() + "\nHochschulnummer " + hsnr); data = getData("EX_FMIFIHD").toString();
log.info("\nHochschulnummer " + hsnr); if (!data.equals(""))
if (GetOpts.isPresent("-nodelete")) bfwhd.write(data);
isDeleteTmpXmlFileWanted = false; bfwhd.flush();
log.log(Level.INFO, "Geschaeftsjahr " + jahr); }
System.out.println("Geschaeftsjahr " + jahr); if (isDeleteTmpXmlFileWanted)
tmpFile.delete();
log.log(Level.INFO, "Verarbeite " + xmlConfig);
System.out.println("Verarbeite " + xmlConfig); } else {
configDocument = XMLUtils.buildDocument(new File(xmlConfig)); msg = "Error: Aufruf von Webservice für Bewegungsdaten " + datentyp + " (" + xmlConfig
+ ") fehlgeschlagen";
} System.out.println(msg);
System.out.println(StringUtils.readFile(tmpFile));
private void initOutFile() throws Exception { logger.severe(msg);
outFile = new File(outfilename); LogUtils.close("wc");
if (outFile.exists()) System.exit(-1);
outFile.delete(); }
// FileWriter fw = new FileWriter(f); }
fw = new PrintWriter(outFile);
// FileOutputStream fos = new FileOutputStream(f, false); private String getSoap(String datevon, String datebis) {
// BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(fos)); String tempsoap = soap;
tempsoap = tempsoap.replaceAll("XXSTARTXX", datevon);
bfw = new BufferedWriter(fw); tempsoap = tempsoap.replaceAll("XXENDEXX", datebis);
return tempsoap;
if (datentyp.equals("fmifiit")) {
}
String hdfilename = StringUtils.replace(outfilename, ".", "hd.");
outFileHd = new File(hdfilename); private void readConfig() throws IOException, SAXException {
String msg = "Erzeuge zusaetzliche Header_Datei " + hdfilename;
log.log(Level.INFO, msg); xmlConfig = GetOpts.getValue(Options.opt_xmlconfig);
System.out.println(msg); outfilename = GetOpts.getValue(Options.opt_out);
fwhd = new PrintWriter(outFileHd);
bfwhd = new BufferedWriter(fwhd); hsnr = GetOpts.getValue(Options.opt_hsnr);
} jahr = GetOpts.getValue(Options.opt_jahr);
datentyp = GetOpts.getValue(Options.opt_datentyp);
} System.out.println("\n" + DateUtils.getTodayString() + " "
+ DateUtils.getNowString() + "\nHochschulnummer " + hsnr);
private void closeFile() throws Exception { logger.info("\nHochschulnummer " + hsnr);
if (GetOpts.isPresent(Options.opt_noDelete))
bfw.close(); isDeleteTmpXmlFileWanted = false;
fw.close(); logger.log(Level.INFO, "Geschaeftsjahr " + jahr);
System.out.println("Geschaeftsjahr " + jahr);
if (datentyp.equals("fmifiit")) {
bfwhd.close(); logger.log(Level.INFO, "Verarbeite " + xmlConfig);
fwhd.close(); System.out.println("Verarbeite " + xmlConfig);
} configDocument = XMLUtils.buildDocument(new File(xmlConfig));
if (isDeleteTmpXmlFileWanted) }
if (tmpFile.exists()) tmpFile.delete();
} private void initOutFile() throws Exception {
outFile = new File(outfilename);
private boolean isReplyOk() throws XMLStreamException, IOException { if (outFile.exists())
InputStream in = new FileInputStream(tmpFile); outFile.delete();
XMLStreamReader parser = factory.createXMLStreamReader(in); // FileWriter fw = new FileWriter(f);
boolean checkReturn = false; fw = new PrintWriter(outFile);
String result = ""; // FileOutputStream fos = new FileOutputStream(f, false);
while (parser.hasNext()) { // BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(fos));
switch (parser.getEventType()) {
case XMLStreamConstants.START_ELEMENT: bfw = new BufferedWriter(fw);
if (parser.getLocalName().equals("RETURN")) {
checkReturn = true; if (datentyp.equals("fmifiit")) {
} String hdfilename = StringUtils.replace(outfilename, ".", "hd.");
break; outFileHd = new File(hdfilename);
String msg = "Erzeuge zusaetzliche Header_Datei " + hdfilename;
case XMLStreamConstants.CHARACTERS: logger.log(Level.INFO, msg);
if (checkReturn && !parser.isWhiteSpace()) { System.out.println(msg);
result = parser.getText(); fwhd = new PrintWriter(outFileHd);
checkReturn = false; bfwhd = new BufferedWriter(fwhd);
} }
break;
case XMLStreamConstants.END_DOCUMENT: }
parser.close(); private void closeFile() throws Exception {
break;
bfw.close();
} fw.close();
parser.next(); if (datentyp.equals("fmifiit")) {
bfwhd.close();
} fwhd.close();
in.close(); }
return result.equals("I");
} if (isDeleteTmpXmlFileWanted)
if (tmpFile.exists()) tmpFile.delete();
private StringBuilder getData(String topnode) throws XMLStreamException, }
IOException {
InputStream in = new FileInputStream(tmpFile);
XMLStreamReader parser = factory.createXMLStreamReader(in);
final String datumspattern = "(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)"; private StringBuilder getData(String topnode) throws XMLStreamException,
IOException {
StringBuilder result = new StringBuilder(); InputStream in = new FileInputStream(tmpFile);
boolean getData = false; XMLStreamReader parser = factory.createXMLStreamReader(in);
while (parser.hasNext()) {
switch (parser.getEventType()) { StringBuilder result = new StringBuilder();
case XMLStreamConstants.START_ELEMENT: boolean getData = false;
String name = parser.getLocalName(); while (parser.hasNext()) {
if (name.equals(topnode))
getData = true; switch (parser.getEventType()) {
// Spaltennamen zu Debugzwecken anzeigen case XMLStreamConstants.START_ELEMENT:
// else if (getData && !name.equals("item")) String name = parser.getLocalName();
// result.append(prefix + "_" + parser.getLocalName()); if (name.equals(topnode))
break; getData = true;
case XMLStreamConstants.CHARACTERS: // Spaltennamen zu Debugzwecken anzeigen
if (getData && !parser.isWhiteSpace()) { // else if (getData && !name.equals("item"))
String data = parser.getText(); // result.append(prefix + "_" + parser.getLocalName());
break;
if (data.matches(datumspattern)) case XMLStreamConstants.CHARACTERS:
data = data.replaceAll(datumspattern, "$3.$2.$1"); if (getData && !parser.isWhiteSpace()) {
else String data = parser.getText();
data = purge(data); if (data.matches(DATUMSPATTERN))
data = adaptDatePattern(data);
result.append(data); else
} data = purge(data, true);
break;
case XMLStreamConstants.END_ELEMENT: result.append(data);
if (parser.getLocalName().equals(topnode)) }
getData = false; break;
else if (getData && parser.getLocalName().equals("item")) case XMLStreamConstants.END_ELEMENT:
result.append("\n"); if (parser.getLocalName().equals(topnode))
else if (getData) { getData = false;
result.append("^"); else if (getData && parser.getLocalName().equals("item"))
} result.append("\n");
break; else if (getData) {
result.append("^");
case XMLStreamConstants.END_DOCUMENT: }
parser.close(); break;
break;
} case XMLStreamConstants.END_DOCUMENT:
parser.next(); parser.close();
} break;
in.close(); }
// abschließendes ^ entfernen parser.next();
//if (result.length() > 0) result.setLength(result.length() - 1); }
return result; in.close();
// abschließendes ^ entfernen
} //if (result.length() > 0) result.setLength(result.length() - 1);
return result;
private String getColumnNames(String topnode)
throws XMLStreamException, IOException { }
InputStream in = new FileInputStream(tmpFile);
XMLStreamReader parser = factory.createXMLStreamReader(in); private String getColumnNames(String topnode)
throws XMLStreamException, IOException {
String prefix = topnode.replaceAll("EX_", ""); InputStream in = new FileInputStream(tmpFile);
StringBuilder result = new StringBuilder(); XMLStreamReader parser = factory.createXMLStreamReader(in);
boolean getNames = false;
while (parser.hasNext()) { String prefix = topnode.replaceAll("EX_", "");
StringBuilder result = new StringBuilder();
switch (parser.getEventType()) { boolean getNames = false;
case XMLStreamConstants.START_ELEMENT: while (parser.hasNext()) {
String name = parser.getLocalName();
if (parser.getLocalName().equals(topnode)) switch (parser.getEventType()) {
getNames = true; case XMLStreamConstants.START_ELEMENT:
else if (getNames && !name.equals("item")) String name = parser.getLocalName();
result.append(prefix + "_" + parser.getLocalName() + "^"); if (parser.getLocalName().equals(topnode))
break; getNames = true;
case XMLStreamConstants.END_ELEMENT: else if (getNames && !name.equals("item"))
if (parser.getLocalName().equals(topnode)||parser.getLocalName().equals("item")) result.append(prefix + "_" + parser.getLocalName() + "^");
getNames = false; break;
break; case XMLStreamConstants.END_ELEMENT:
if (parser.getLocalName().equals(topnode)||parser.getLocalName().equals("item"))
case XMLStreamConstants.END_DOCUMENT: getNames = false;
parser.close(); break;
break;
} case XMLStreamConstants.END_DOCUMENT:
parser.next(); parser.close();
} break;
in.close(); }
// abschließendes ^ entfernen parser.next();
if (result.length() > 0) }
result.setLength(result.length() - 1); in.close();
if (result.length() > 0) // abschließendes ^ entfernen
result.append("\n"); if (result.length() > 0)
return result.toString().toLowerCase(); result.setLength(result.length() - 1);
} if (result.length() > 0)
} result.append("\n");
return result.toString().toLowerCase();
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save