SuperX-Kernmodul
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1750 lines
62 KiB

package de.superx.servlet;
import static de.superx.servlet.SxSQL_Server.DEFAULT_MANDANTEN_ID;
import java.io.File;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.sql.DataSource;
import javax.xml.transform.TransformerConfigurationException;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDriver;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.log4j.Appender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.slf4j.LoggerFactory;
import com.zaxxer.hikari.HikariDataSource;
import de.memtext.baseobjects.NamedObjectI;
import de.memtext.baseobjects.coll.IdObjectCollection;
import de.memtext.baseobjects.coll.NamedIdObjectSet;
import de.memtext.baseobjects.coll.NamedObjectList;
import de.memtext.baseobjects.coll.NamedObjectSet;
import de.memtext.rights.NewPasswordChecker;
import de.memtext.tree.KeyParentEqualException;
import de.memtext.tree.NoMainEntryException;
import de.memtext.util.DSAHandler;
import de.memtext.util.DateUtils;
import de.memtext.util.LogUtils;
import de.superx.common.AbstractSicht;
import de.superx.common.DBServletException;
import de.superx.common.Field;
import de.superx.common.FieldContainer;
import de.superx.common.GraphicFormat;
import de.superx.common.MacroFieldSelection;
import de.superx.common.Maske;
import de.superx.common.OrgUnitMapping;
import de.superx.common.SichtException;
import de.superx.common.SxFinRechte;
import de.superx.common.SxKontierungsrechte;
import de.superx.common.SxResultRow;
import de.superx.common.SxResultSet;
import de.superx.common.SxUser;
import de.superx.common.TemplateProcessor;
import de.superx.common.TranslationContainer;
import de.superx.conf.InitStatus;
import de.superx.conf.InitStatus.SubSystem;
import de.superx.spring.AppConfig;
import de.superx.spring.batch.His1DataSources;
import de.superx.spring.service.ApplicationContextHolder;
import de.superx.util.PropsReader;
import de.superx.util.SqlStringUtils;
import freemarker.template.TemplateException;
import net.sf.jasperreports.engine.DefaultJasperReportsContext;
import net.sf.jasperreports.engine.JRPropertiesUtil;
/**
* eigentlich MemtextPool in Memtext-Packet nutzen! TODO als Erweiterung von
* MemtextPool A new Connection pool making use of Jakarta Commons dbcp. Also
* caches Masks and other data.
*/
public class SxPool extends GenericObjectPool implements NamedObjectI {
private String name;
private int finRightVariant = 0;
private NamedObjectList sichtartRechteDefinitionen = new NamedObjectList();
private boolean isErweitertesProtokollWanted = false;
private int passwortGültigkeit = 0;
private Properties props = new Properties();
private FieldElementCache fieldElementCache = new FieldElementCache();
private IdObjectCollection graphicformats = new IdObjectCollection();
private IdObjectCollection translations = new IdObjectCollection();
private Collection makroFieldSelections = new LinkedList();
public NamedIdObjectSet userpool = new NamedIdObjectSet();
private NamedIdObjectSet maskenpool = new NamedIdObjectSet();
private ServletTemplateProcessor templateProcessor;
// TODO: Add type parameters
private HashMap repositoryMap = new HashMap();
private String privateKeyEncoded = null;
private String publicKeyEncoded = null;
private boolean isRestrictedConnection = false;
private DSAHandler dsaHandler;
private NewPasswordChecker newPasswordChecker;
private boolean hasImplicitOrgUnitRightsTable = false;
// ist 0 auch für SxFinRechte ein Joker
private boolean is0FINJoker = true;
private boolean hasKontierungsrechte = false;
private String excelVorlage;
private boolean hasCustomPdfFile = false;
private NamedObjectSet externalPools = new NamedObjectSet();
private boolean hasFinUserKamRestrictionFields = false;
private Map<String, OrgUnitMapping> orgUnitMappings = new HashMap<String, OrgUnitMapping>();
private static org.slf4j.Logger logger = LoggerFactory.getLogger(SxPool.class);
public boolean hasFinUserKamRestrictionFields() {
return hasFinUserKamRestrictionFields;
}
private DataSource eduetlDataSource;
private String databaseAbbrevation;
/**
* Create and initialize a connection pool.
*
* @param name MandantenID
* @param dbProperties optional Properties to initialize connection for test
* purposes, if null db.properties is read
* @throws SQLException
* @throws IOException
* @throws DBServletException
*/
SxPool(String name, Properties dbProperties) throws SQLException, IOException, DBServletException {
setName(name);
initProperties(dbProperties);
initLogging(true, Level.ERROR);
templateProcessor = new ServletTemplateProcessor(name);
if (DEFAULT_MANDANTEN_ID.equals(name) || "test".equals(name)) {
initHikariPool();
} else {
configureDbcp();
}
initDbcpPoolingDriver();
try {
setDatabaseAbbreviation();
initFromDB();
} catch (SQLException e) {
String msg = "Fehler beim Aufbau des ConnectionPools ";
if (!getName().equals(DEFAULT_MANDANTEN_ID))
msg += " für Mandant: " + getName();
msg += "\nKonnte keine Connection aus dem Pool holen.DETAILS:\n" + e;
e.printStackTrace();
throw new SQLException(msg);
}
if (privateKeyEncoded != null)
initDSAHandler();
}
SxPool(String name, DataSource dataSource) throws SecurityException, IOException, SQLException, DBServletException {
setName(name);
initLogging(true, Level.DEBUG);
templateProcessor = new ServletTemplateProcessor(name);
this.eduetlDataSource = dataSource;
try {
setDatabaseAbbreviation();
initFromDB();
} catch (SQLException e) {
String msg = "Fehler beim Aufbau des ConnectionPools ";
if (!getName().equals(DEFAULT_MANDANTEN_ID))
msg += " für Mandant: " + getName();
msg += "\nKonnte keine Connection aus dem Pool holen.DETAILS:\n" + e;
e.printStackTrace();
throw new SQLException(msg);
}
if (privateKeyEncoded != null)
initDSAHandler();
}
public String getConnectionUrl() {
if (props == null)
throw new IllegalStateException("Noch keine Properties eingelesen!");
return props.getProperty("connectionURL");
}
private void setKernMaskHtmlXsl(Statement st) throws SQLException {
int count = 0;
ResultSet rs = st.executeQuery("select count(*) from konstanten where beschreibung='KernMaskHtmlXsl' ");
while (rs.next()) {
count = rs.getInt(1);
}
rs.close();
if (count == 0) {
rs = st.executeQuery("select max(tid) from konstanten");
int newtid = 999;
while (rs.next()) {
newtid = rs.getInt(1);
}
newtid++;
rs.close();
st.executeUpdate(
"insert into konstanten (tid,beschreibung,apnr) values (" + newtid + ", 'KernMaskHtmlXsl',0)");
}
int tablehtml = 1;
if (!SuperXManager.defaultMaskXsl.equals("maske_html.xsl"))
tablehtml = 2;
st.executeUpdate("update konstanten set apnr=" + tablehtml + " where beschreibung='KernMaskHtmlXsl' ");
}
/**
* Add customizable entries to sx_repository if not present.
*
* @return result of initialization (Optional.empty(): success, otherwise
* contains the Exception thrown)
*/
private Optional<Throwable> initHeaderFooterDB() {
try (Connection con = this.getConnection(); Statement stmt = con.createStatement()) {
ResultSet rs = stmt.executeQuery("select id from sx_repository where art='HEADER_FOOTER'");
HashMap ids = new HashMap();
while (rs.next()) {
String id = rs.getString(1);
ids.put(id.trim(), "found");
}
rs.close();
rs = stmt.executeQuery("select max(tid) from sx_repository ");
int tid = 0;
while (rs.next()) {
tid = rs.getInt(1) + 1;
}
try (PreparedStatement pst = getDatabaseAbbr().equals("PG")
? con.prepareStatement("insert into sx_repository"
+ "(tid,id,caption,sachgebiete_id,art,aktiv,gueltig_seit,gueltig_bis)"
+ " values (?,?,?,0,'HEADER_FOOTER',1,DATE '1900-01-01',DATE '3000-01-01')")
: con.prepareStatement("insert into sx_repository"
+ "(tid,id,caption,sachgebiete_id,art,aktiv,gueltig_seit,gueltig_bis)"
+ " values (?,?,?,0,'HEADER_FOOTER',1,DATE '1900-01-01',DATE '3000-01-01')")) {
if (!ids.containsKey("HTML_HEADER")) {
pst.setInt(1, tid++);
pst.setString(2, "HTML_HEADER");
pst.setString(3, "HTML Kopfzeile");
pst.execute();
}
if (!ids.containsKey("HTML_FOOTER")) {
pst.setInt(1, tid++);
pst.setString(2, "HTML_FOOTER");
pst.setString(3, "HTML Fußzeile");
pst.execute();
}
if (!ids.containsKey("CUSTOM_PDF")) {
pst.setInt(1, tid++);
pst.setString(2, "CUSTOM_PDF");
pst.setString(3, "individuelle PDF Anpassung");
pst.execute();
}
}
} catch (Exception e) {
return Optional.of(e);
}
return Optional.empty();
}
/**
* public/private key newPasswordChecker
*
* @throws SQLException
*/
private void initFromDB() throws SQLException {
try (Connection con = this.getConnection(); Statement st = con.createStatement()) {
setKernMaskHtmlXsl(st);
ResultSet rs = st.executeQuery("select content from sx_repository where id='privatekey'");
while (rs.next()) {
privateKeyEncoded = rs.getString(1);
}
rs = st.executeQuery("select content from sx_repository where id='publickey'");
while (rs.next()) {
publicKeyEncoded = rs.getString(1);
}
rs = st.executeQuery("select apnr from konstanten where beschreibung='Passwortgültigkeit (Tage)'");
while (rs.next()) {
passwortGültigkeit = rs.getInt(1);
}
rs = st.executeQuery("select apnr from konstanten where beschreibung='Passwort Groß- u. Kleinb.'");
int großklein = 0;
while (rs.next()) {
großklein = rs.getInt(1);
}
int ziffernötig = 0;
rs = st.executeQuery("select apnr from konstanten where beschreibung='Passwort erfordert Ziffer'");
while (rs.next()) {
ziffernötig = rs.getInt(1);
}
rs = st.executeQuery("select apnr from konstanten where beschreibung='Passwortlänge (Minimum)'");
int minLänge = 0;
while (rs.next()) {
minLänge = rs.getInt(1);
}
newPasswordChecker = new NewPasswordChecker(minLänge, großklein, ziffernötig);
rs = st.executeQuery("select apnr from konstanten where beschreibung='Erweitertes Protokoll'");
int loginP = 0;
while (rs.next()) {
loginP = rs.getInt(1);
}
isErweitertesProtokollWanted = loginP == 1;
}
}
/**
*
* @return int in Tagen
*/
public int getPasswortGültigkeit() {
return passwortGültigkeit;
}
public boolean isErweitertesProtokollWanted() {
return isErweitertesProtokollWanted;
}
public void initLogging(boolean append, Level defaultLevel) throws SecurityException, IOException {
String loggerSqlName = String.format("superx_%s", getName());
String loggerXmlName = String.format("superx_%s_xml", getName());
String fileNameSql = String.format("%s/superx_%s.log", getLogDir(), name);
String fileNameXml = String.format("%s/superx_%s_xml.log", getLogDir(), name);
LogUtils.initRawFile(loggerSqlName, fileNameSql, 20000, 1, append, true);
LogUtils.initRawFile(loggerXmlName, fileNameXml, 20000, 1, append, true);
setLoggingLevel(loggerSqlName, "logLevelSQL", defaultLevel);
setLoggingLevel(loggerXmlName, "logLevelXML", defaultLevel);
}
private void setLoggingLevel(String loggerName, String propertyName, Level defaultLevel) {
Level dbPropsLevel = null;
try {
if (props.getProperty(propertyName) != null)
dbPropsLevel = Level.toLevel(props.getProperty(propertyName));
} catch (IllegalArgumentException e) {
String msg = "Ungültiger Level für Logger " + loggerName;
if (!this.getName().equals(DEFAULT_MANDANTEN_ID))
msg += "(Mandant :" + getName() + ") ";
msg += " :" + props.getProperty(propertyName);
logger.info(msg);
}
Logger aLogger = Logger.getLogger(loggerName);
aLogger.setLevel(dbPropsLevel != null ? dbPropsLevel : defaultLevel);
aLogger.setAdditivity(false);
logger.info("\nLoglevel " + logger + ": "+ Logger.getLogger(loggerName).getLevel());
}
public static String getLogDir() {
String targetDir = SuperXManager.getWEB_INFPfad() + File.separator + "logs";
File f = new File(targetDir);
if (!f.exists())
f.mkdir();
if (System.getProperty("SX_LOG_TO_TMP") != null && System.getProperty("SX_LOG_TO_TMP").equalsIgnoreCase("true"))
targetDir = System.getProperty("java.io.tmpdir");
return targetDir;
}
/**
* Liest auch aus, ob eine restrictedConnection aufgebaut werden soll oder nicht
*
* @throws Exception
*/
private void readPropertiesAndUrl() throws Exception {
props = PropsReader.prepareProps(new File(getDbPropertyFilePath()));
}
private String getDbPropertyFilePath() {
String propname = "db_" + getName() + ".properties";
if (getName().equals(DEFAULT_MANDANTEN_ID))
propname = "db.properties";
return SuperXManager.getWEB_INFPfad() + File.separator + propname;
}
private void checkRestrictedConnection() throws Exception {
if (props.getProperty("restrictedConnectionName") != null
&& !props.getProperty("restrictedConnectionName").trim().equals("")
&& props.getProperty("restrictedConnectionPassword") != null
&& !props.getProperty("restrictedConnectionPassword").trim().equals("")) {
props.put("user", props.getProperty("restrictedConnectionName"));
props.put("password", PropsReader.check(props.getProperty("restrictedConnectionPassword")));
isRestrictedConnection = true;
} else {
String user = props.getProperty("connectionName");
String passw = props.getProperty("connectionPassword");
if (user != null) {
props.put("user", user);
} else {
logger.warn("No property connectionName!");
}
if (passw != null) {
props.put("password", PropsReader.check(passw));
} else {
logger.warn("No property connectionPassword!");
}
}
}
public String getSqlDialect() {
if (("PG").equals(databaseAbbrevation)) {
return "Postgres";
}
return "Informix";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void close() throws SQLException {
if (this.eduetlDataSource == null) {
PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
driver.closePool(this.getName());
}
closeLoggers();
}
private void closeLogger(String loggername) {
Enumeration appenders = Logger.getLogger(loggername).getAllAppenders();
Iterator<Appender> it = appenders.asIterator();
while(it.hasNext()) {
it.next().close();
}
}
private void closeLoggers() {
String loggerSqlName = String.format("superx_%s", getName());
String loggerXmlName = String.format("superx_%s_xml", getName());
closeLogger(loggerSqlName);
closeLogger(loggerXmlName);
}
public Connection getConnection() throws SQLException {
if (eduetlDataSource != null) {
Connection con = eduetlDataSource.getConnection();
return con;
}
return DriverManager.getConnection("jdbc:apache:commons:dbcp:" + this.getName());
}
public DataSource getDataSource() {
return eduetlDataSource;
}
@Override
public Object borrowObject() throws Exception {
Object obj = super.borrowObject();
return obj;
}
@Override
public void returnObject(Object obj) throws Exception {
super.returnObject(obj);
}
// NON-DB FUNCTIONS
public boolean hasMaske(Integer tid) {
return maskenpool.containsItemWithId(tid);
}
public Maske getMaskenclone(Integer tid) throws CloneNotSupportedException {
return (Maske) ((Maske) maskenpool.getById(tid)).clone();
}
/**
* Initialize cache for sx_captions from db
*
* @return result of initialization (Optional.empty(): success, otherwise
* contains the Exception thrown)
*/
private Optional<Throwable> initTranslations() {
try {
translations = new IdObjectCollection();
SxResultSet rs = ServletUtils.execute("Einlesen von Übersetzungen",
"select id,locale,contents_short,contents_long from sx_captions where id is not null", getName());
for (Iterator it = rs.iterator(); it.hasNext();) {
SxResultRow row = (SxResultRow) it.next();
Object id = row.get(0);
String loc = (String) row.get(1);
String contentsShort = SqlStringUtils.getValueAsString(row.get(2));
String contentsLong = SqlStringUtils.getValueAsString(row.get(3));
if (!translations.containsItemWithId(id)) {
translations.add(new TranslationContainer(this.getName(), id, loc, contentsShort, contentsLong));
} else {
TranslationContainer tc = (TranslationContainer) translations.getById(id);
tc.addLocalizedItem(loc, contentsShort, contentsLong);
}
}
} catch (Exception e) {
return Optional.of(e);
}
return Optional.empty();
}
/**
* Initialize cache for db tables sx_repository, hochschulinfo and konstanten.
*
* Keys for hochschulinfo and konstanten are prefixed with "K_"
*
* @return result of initialization (Optional.empty(): success, otherwise
* contains the Exception thrown)
*/
public synchronized Optional<Throwable> initRepository() {
try {
repositoryMap = readRepository();
} catch (Exception e) {
return Optional.of(e);
}
return Optional.empty();
}
public HashMap readRepository() throws SQLException, DBServletException {
HashMap result = new HashMap<>();
SxResultSet rs = ServletUtils.execute("Einlesen von Sx_repository Einträgen",
TemplateProcessor.REPOSITORY_SELECT, getName());
TemplateProcessor.repositoryToMap(rs, result); // TODO: Sollte result zurückgeben, nicht darauf arbeiten!
// Kram
rs = ServletUtils.execute("Einlesen von hochschulinfo für repository",
"select name,adresse,hs_nr,kapitel from hochschulinfo", getName());
// sollte eigentlich nur eine Zeile geben aber rs.first() macht Ärger,
// wenn Tabelle wider Erwarten leer
for (Iterator it = rs.iterator(); it.hasNext();) {
SxResultRow zeile = (SxResultRow) it.next();
result.put("K_Name", zeile.get(0));
result.put("K_Adresse", zeile.get(1));
result.put("K_hs_nr", zeile.get(2));
result.put("K_Kapitel", zeile.get(3));
}
rs = ServletUtils.execute("Einlesen von konstanten für repository",
"select trim(beschreibung),apnr from konstanten", getName());
for (Iterator it = rs.iterator(); it.hasNext();) {
SxResultRow row = (SxResultRow) it.next();
String beschreibung = (String) row.get(0);
result.put("K_" + beschreibung, row.get(1));
}
return result;
}
public String localize(StringBuffer text, Locale l) {
return localize(text.toString(), l);
}
public String localize(String text, Locale l) {
String result = text;
// im angegebenen Text alle vorhandenen @@@tags und @@tags ersetzen
for (@SuppressWarnings("unchecked")
Iterator<TranslationContainer> it = this.translations.iterator(); it.hasNext();) {
TranslationContainer tc = it.next();
StringBuffer longVersion = new StringBuffer().append("@@@").append(tc.getId()).append("@@@");
StringBuffer shortVersion = new StringBuffer().append("@@").append(tc.getId()).append("@@");
result = StringUtils.replace(result, longVersion.toString(), tc.getContentsLong(l));
result = StringUtils.replace(result, shortVersion.toString(), tc.getContentsShort(l));
}
//spezielle Tags zur Doku zu einzelnen Masken entfernen, falls nichts explizit eingepflegt #295164
result=result.replaceAll("@@@doku_\\d*_mask@@@", "");
return result.replaceAll("_HISINONE_", SuperXManager.his1_refapp);
}
/**
*
* @param id
* @param l
* @return Leerstring falls nicht gefunden
*/
public String getTranslationShort(String id, Locale l) {
String result = "";
if (translations.containsItemWithId(id)) {
TranslationContainer tc = (TranslationContainer) translations.getById(id);
result = tc.getContentsShort(l);
}
return result;
}
/**
* Initialize cache for graphicsformats from table graphicformat in db. TODO: Is
* this still needed? DB table seems to be empty.
*
* @return result of initialization (Optional.empty(): success, otherwise
* contains the Exception thrown)
*/
private Optional<Throwable> initGraphicsFormats() {
try {
SxResultSet rs = ServletUtils.execute("Einlesen von Grafikformaten",
"select id,charttype,caption,width,height,captionx,captiony,linex,liney,showvalues,moreattribs from graphicformat",
getName());
graphicformats.clear();
for (Iterator it = rs.iterator(); it.hasNext();) {
SxResultRow row = (SxResultRow) it.next();
graphicformats.add(new GraphicFormat(row));
}
} catch (Exception e) {
return Optional.of(e);
}
return Optional.empty();
}
/**
* Initialize cache for macro_feld_wert from db.
*
* @return result of initialization (Optional.empty(): success, otherwise
* contains the Exception thrown)
*/
private Optional<Throwable> initMacroFieldSelections() {
try {
SxResultSet makroFieldRs = ServletUtils.execute(
"Einlesen von speziellen Auswahlwerten für makros aus macro_feld_wert",
"select macro,sortnr,feldname,value,feldsicht from macro_feld_wert where active=1", getName());
makroFieldSelections.clear();
for (Iterator it = makroFieldRs.iterator(); it.hasNext();) {
SxResultRow aRow = (SxResultRow) it.next();
MacroFieldSelection m = new MacroFieldSelection(aRow);
if (m.getWert() != null && m.getWert().startsWith("<<SQL>>")) {
SxResultSet result = ServletUtils.execute("Wert für hinterlegten makro_feld_wert " + m.getMakroid()
+ ", sortnr " + m.getSortnr() + " holen", m.getWert().substring(7), getName());
if (result.size() == 0)
throw new IllegalArgumentException("Kein Makro_feld_wert für makro " + m.getMakroid()
+ " sortnr " + m.getSortnr() + " per " + m.getWert() + " gefunden.");
SxResultRow row = (SxResultRow) result.first();
Object o = row.get(0);
if (o == null)
throw new IllegalArgumentException("Makro_feld_wert für makro " + m.getMakroid() + " sortnr "
+ m.getSortnr() + " darf nicht null sein.");
m.setWert(o.toString());
}
makroFieldSelections.add(m);
}
} catch (Exception e) {
return Optional.of(e);
}
return Optional.empty();
}
public boolean hasMakroFieldSelection(Object makroid, Integer sortNr) {
boolean result = false;
for (Iterator it = makroFieldSelections.iterator(); it.hasNext();) {
MacroFieldSelection makroFieldSelection = (MacroFieldSelection) it.next();
if (makroFieldSelection.getMakroid().toString().equals(makroid.toString())
&& makroFieldSelection.getSortnr().equals(sortNr)) {
result = true;
break;
}
}
return result;
}
public void applyMacroFieldSelectionTo(Object makroid, Maske maske, Hashtable formular, HashMap map,
FieldContainer fc, SxUser user) {
for (Iterator it = makroFieldSelections.iterator(); it.hasNext();) {
MacroFieldSelection makroFieldSelection = (MacroFieldSelection) it.next();
if (makroFieldSelection.getMakroid().toString().equals(makroid.toString())
&& makroFieldSelection.getSortnr().equals(maske.getSortNr())) {
SuperXManager.logActivity(Level.DEBUG,
"Setze speziellen Auswahlwert ein für Makro " + makroid + " Submaske: "
+ maske.getName() + " sortnr=" + makroFieldSelection.getSortnr()
+ " Feld:" + makroFieldSelection.getFeldername() + " Wert:"
+ makroFieldSelection.getWert() + " Sicht:" + makroFieldSelection.getFeldsicht());
try {
if (makroFieldSelection.getFeldsicht() != null && !makroFieldSelection.getFeldsicht().equals("")) {
Field f = maske.getField(makroFieldSelection.getFeldername());
SxResultSet rs = ServletUtils.execute(
"Suchen der Sicht mit name_intern=" + makroFieldSelection.getFeldsicht(),
"select tid from sichten where name_intern='" + makroFieldSelection.getFeldsicht()
+ "'",
getName());
Integer sichttid = Integer.valueOf(-1);
for (Iterator it2 = rs.iterator(); it2.hasNext();) {
SxResultRow row = (SxResultRow) it2.next();
sichttid = (Integer) row.get(0);
}
if (sichttid == null || sichttid.intValue() == -1)
throw new IllegalArgumentException("Für Makro " + makroid + " Feld:"
+ makroFieldSelection.getFeldername() + " Sortnr:" + makroFieldSelection.getSortnr()
+ " wurde eine Sicht mit name_intern=" + makroFieldSelection.getFeldsicht()
+ " angegeben, die nicht gefunden wurde");
f.setSicht(formular, map, fc, sichttid, user);
f.setMacroMaskenSichtSet(true);
}
} catch (Exception e) {
e.printStackTrace();
throw new IllegalArgumentException(
"Für Makro " + makroid + " Feld:" + makroFieldSelection.getFeldername() + " Sortnr:"
+ makroFieldSelection.getSortnr() + " konnte eine Sicht mit name_intern="
+ makroFieldSelection.getFeldsicht() + " nicht gesetzt werden");
}
try {
if (makroFieldSelection.getWert() != null && !makroFieldSelection.getWert().equals("")) {
Field f = maske.getField(makroFieldSelection.getFeldername());
f.initIfNeeded(formular, map, fc, user);
maske.setSpecialFieldSelection(makroFieldSelection.getFeldername(),
makroFieldSelection.getWert());
}
} catch (Exception e) {
e.printStackTrace();
throw new IllegalArgumentException("Konnte für Maske " + maske.getName() + " (" + maske.getId()
+ ") den gewünschten Wert :\"" + makroFieldSelection.getWert() + "\" für das Feld "
+ makroFieldSelection.getFeldername() + " nicht eintragen.\n" + e);
}
}
}
}
/**
* Init all subsystems and check for errors.
*
*/
public void init() {
try {
SuperXmlAnmeldung.waitForPoolInit = true;
InitStatus.setStatus(SubSystem.OrgunitMapping, initOrgUnitMapping());
InitStatus.setStatus(SubSystem.SichtartRechteDefinition, initSichtartRechteDefinition());
InitStatus.setStatus(SubSystem.FinRights, initFinRights());
InitStatus.setStatus(SubSystem.FMTemplates, initFMTemplates());
InitStatus.setStatus(SubSystem.Repository, initRepository());
InitStatus.setStatus(SubSystem.Translations, initTranslations());
InitStatus.setStatus(SubSystem.HeaderFooterDB, initHeaderFooterDB());
InitStatus.setStatus(SubSystem.MacroFieldSelections, initMacroFieldSelections());
InitStatus.setStatus(SubSystem.GraphicsFormats, initGraphicsFormats());
// TODO: This init function should be refactored!
// contains different logging outputs and swallows exceptions...
InitStatus.setStatus(SubSystem.FieldElementCache, initFieldElementCache());
InitStatus.setStatus(SubSystem.ExcelTemplate, initExcelTemplate());
// TODO: How to handle this with Hikari?
// TODO: Switch ExternalPool to using Hikari!
InitStatus.setStatus(SubSystem.ExternalPools, initExternalPools());
InitStatus.setStatus(SubSystem.HasKontierungsRechte, initHasKontierungsrechte());
InitStatus.setStatus(SubSystem.HasImplicitOrgunitsRightTable, inithasImplicitOrgUnitRightsTable());
InitStatus.setStatus(SubSystem.JasperReports, initJasper());
deleteMaskenProtokoll();
} finally {
SuperXmlAnmeldung.waitForPoolInit = false;
}
}
private void deleteMaskenProtokoll() {
if (this.getRepository().containsKey("K_Nutzungsstatistiken loeschen nach Tagen")&&Integer.parseInt(getRepository().get("K_Nutzungsstatistiken loeschen nach Tagen").toString())>0)
{
try {
Connection con=this.getConnection();
PreparedStatement pst=con.prepareStatement("delete from masken_protokoll where CURRENT_DATE - Zeitpunkt::date>=?");
pst.setInt(1, Integer.parseInt(getRepository().get("K_Nutzungsstatistiken loeschen nach Tagen").toString()));
pst.executeUpdate();
pst.close();
con.close();
} catch (SQLException e) {
Logger.getLogger("superx_" + getName()).log(Level.WARN,
"Fehler Nutzungsstatistiken loeschen nach Tagen");
e.printStackTrace();
}
}
}
private Optional<Throwable> initJasper() {
boolean useJaxen=true;
try (Connection dbConnection = SxPools.getConnection(getName());
Statement stm = dbConnection.createStatement();
ResultSet rs = stm.executeQuery("select count(*) from konstanten where beschreibung='KERN_JASPER_USE_JAXEN' and apnr=0")) {
while (rs.next()) {
if (rs.getInt(1)!=0) useJaxen=false;
}
Logger.getLogger("superx_" + getName()).log(Level.DEBUG,
"Inited " + orgUnitMappings.size() + " OrgUnitMappings for LiveMapping");
} catch (Exception e) {
Logger.getLogger("superx_" + getName()).log(Level.ERROR, e.toString());
return Optional.of(e);
}
Logger.getLogger("superx_" + getName()).info("JASPER Jaxen Nutzung steht auf "+useJaxen);
if (useJaxen)
{
DefaultJasperReportsContext context = DefaultJasperReportsContext.getInstance();
JRPropertiesUtil.getInstance(context).setProperty("net.sf.jasperreports.xpath.executer.factory",
"net.sf.jasperreports.engine.util.xml.JaxenXPathExecuterFactory");
}
return Optional.empty();
}
/**
* Set hasImplicitOrgUnitRightsTable table if implicit_orgunit_rights exists in
* db.
*
* @return result of initialization (Optional.empty(): success, otherwise
* contains the Exception thrown)
*/
private Optional<Throwable> inithasImplicitOrgUnitRightsTable() {
try (Connection dbConnection = SxPools.getConnection(getName())) {
DatabaseMetaData md = dbConnection.getMetaData();
String[] types = { "TABLE" };
// wenn fin_user_kam exisitert simple rights
try (ResultSet rs = md.getTables(null, null, "implicit_orgunit_rights", types)) {
if (rs.next()) {
hasImplicitOrgUnitRightsTable = true;
}
}
} catch (Exception e) {
return Optional.of(e);
}
return Optional.empty();
}
public boolean hasImplicitOrgUnitRightsTable() {
return hasImplicitOrgUnitRightsTable;
}
/**
* Init cache for orgunit mappings from db
*
* @return result of initialization (Optional.empty(): success, otherwise
* contains the Exception thrown)
*/
private Optional<Throwable> initOrgUnitMapping() {
try (Connection dbConnection = SxPools.getConnection(getName());
Statement stm = dbConnection.createStatement();
ResultSet rs = stm.executeQuery("select apnr,mapped_id,uniquename from orgunit_mapping")) {
orgUnitMappings.clear();
while (rs.next()) {
String id = rs.getString("apnr");
OrgUnitMapping oum = orgUnitMappings.get(id);
if (oum == null) {
oum = new OrgUnitMapping(id);
orgUnitMappings.put(id, oum);
}
oum.setUniquename(rs.getString("uniquename"));
oum.addMappedId(rs.getString("mapped_id"));
}
Logger.getLogger("superx_" + getName()).log(Level.DEBUG,
"Inited " + orgUnitMappings.size() + " OrgUnitMappings for LiveMapping");
} catch (Exception e) {
Logger.getLogger("superx_" + getName()).log(Level.ERROR, e.toString());
// TODO: Is this necessary?
// SxPools.invalidate(getName(), dbConnection);
return Optional.of(e);
}
return Optional.empty();
}
public Map<String, OrgUnitMapping> getOrgUnitMappings() {
return orgUnitMappings;
}
/**
*
* @throws SQLException
* @deprecated
*/
private void updateHisInOneConfig() throws SQLException {
int hisinone_active = SuperXManager.his1_refapp.equals("") ? 0 : 1;
Connection con = this.getConnection();
Statement st = con.createStatement();
updateHisIneOrganigrammQuelle(st, hisinone_active);
st.close();
con.close();
}
/**
* Feststellen ob HisinONe aktiv ist, könnte problematisch sein, wenn die HS zu
* Testzwecken zweiten Tomcat ohne hisinone laufen lässt daher doch durch
* Scripte gemacht (Konstante BI-Platform
*
* @param st
* @param hisinone_active
* @throws SQLException
* @deprecated
*
*/
private void updateHisInOneActive(Statement st, int hisinone_active) throws SQLException {
getKonstantenAPNR(st, "HisInOne_aktiv", true);// falls nicht existiert, wird Konstante angelegt
st.executeUpdate(
"update konstanten set apnr=" + hisinone_active + ",read_only=1 where beschreibung='HisInOne_aktiv'");
}
/**
* wird doch durch Scripte gemacht
*
* @param st
* @param hisinone_active
* @throws SQLException
* @deprecated
*/
private void updateHisIneOrganigrammQuelle(Statement st, int hisinone_active) throws SQLException {
getKonstantenAPNR(st, "Organigrammquelle", true);// falls nicht existiert, wird Konstante angelegt
// if (hisinone_active == 1)
// HisinOne ist aktiv, daher Datenquelle nur Hisinone (apnr=0), darf
// nicht geändert werden
// https://wiki.his.de/mediawiki/index.php/FD_BIA_Uebernahme_HISInOne-Organisationsstruktur
// {
// st.executeUpdate("update konstanten set apnr=0,read_only=1 where
// beschreibung='Organigrammquelle'");
// } else
// SuperX Standalone
// wird noch diskutiert
// https://hiszilla.his.de/hiszilla/show_bug.cgi?id=104131#c30
{
int quelle_cob = getKonstantenAPNR(st, "Organigramm_aus_COB", false);
if (quelle_cob == 1)
st.executeUpdate("udpate konstanten set apnr=10,read_only=0 where beschreibung='Organigrammquelle'");
int quelle_mbs = getKonstantenAPNR(st, "Organigramm_aus_MBS", false);
if (quelle_mbs == 1)
st.executeUpdate("update konstanten set apnr=3,read_only=0 where beschreibung='Organigrammquelle'");
// eine Kostante Organigramm_aus_SOS gibt es nicht, falls weder COB
// und MBS nur SOS installiert,
// reagiert Script sos/schluesseltabellen/organigramm_fuellen.sql
// darauf, indem es feststellt, dass keine Einträge orgstruktur
// 20/30 im Organigramm vorliegen
// Alte Konstanten löschen
st.executeUpdate("delete from konstanten where beschreibung='Organigramm_aus_COB'");
st.executeUpdate("delete from konstanten where beschreibung='Organigramm_aus_MBS'");
}
}
/**
* Liefert apnr einer Konstante, ggfs. -1 falls sie nicht existiert
*
* @param st
* @param konstante
* @param createIfNotFound Konstante anlegen, falls noch nicht vorhanden
* @return apnr der Konstante - -1 falls neu angelegt
* @throws SQLException
*/
private int getKonstantenAPNR(Statement st, String konstante, boolean createIfNotFound) throws SQLException {
ResultSet rs;
if (createIfNotFound) {
rs = st.executeQuery("select count(*) from konstanten where beschreibung='" + konstante + "'");
int konstante_gefunden = 0;
while (rs.next()) {
konstante_gefunden = rs.getInt(1);
}
rs.close();
if (konstante_gefunden == 0) {
rs = st.executeQuery("select max(tid) from konstanten");
int maxtid = 0;
while (rs.next()) {
maxtid = rs.getInt(1);
}
rs.close();
maxtid++;
st.executeUpdate("insert into konstanten (tid,beschreibung,apnr) values (" + maxtid + ",'" + konstante
+ "',-1)");
if (this.getDatabaseAbbr().equals("PG"))
st.executeQuery("select sp_update_sequence('konstanten')");
}
}
int apnr = -1;
rs = st.executeQuery("select apnr from konstanten where beschreibung='" + konstante + "'");
while (rs.next()) {
apnr = rs.getInt(1);
}
return apnr;
}
public boolean hasKontierungsrechte() {
return this.hasKontierungsrechte;
}
/**
* Set hasKontierungsrechte if db table gxstage_user_rights exists.
*
* @return result of initialization (Optional.empty(): success, otherwise
* contains the Exception thrown)
*/
private Optional<Throwable> initHasKontierungsrechte() {
try (Connection dbConnection = SxPools.getConnection(getName());) {
hasKontierungsrechte = false;
boolean isErweitert = false;
DatabaseMetaData md = dbConnection.getMetaData();
try (ResultSet rs = md.getColumns(null, null, "gxstage_user_rights", null)) {
while (rs.next()) {
hasKontierungsrechte = true;
if (rs.getString("COLUMN_NAME").equalsIgnoreCase("status")) {
isErweitert = true;
}
}
if (hasKontierungsrechte) {
Logger.getLogger("superx_" + getName())
.info("Spezielle SAP-Finanzkontierungsrechte (gxstage_user_rights) "
+ (isErweitert ? " inkl. Status" : "ohne Status") + "gefunden");
SxKontierungsrechte.initReadingSQL(isErweitert);
} else {
Logger.getLogger("superx_" + getName())
.info("Keine Spezielle SAP-Finanzkontierungsrechte (gxstage_user_rights) gefunden");
}
}
} catch (Exception e) {
return Optional.of(e);
}
return Optional.empty();
}
/**
* Initialize excelVorlage template from file superx/custom/vorlage.xlsx if it
* exists. Output contents of CUSTOM_PDF in repositoryMap to file
* superx/custom/custom_pdf.xsl if exists and is not empty.
*
* @return result of initialization (Optional.empty(): success, otherwise
* contains the Exception thrown)
*/
private Optional<Throwable> initExcelTemplate() {
try {
// getName() enthält MandantenID bzw. DEFAULT_MANDANTEN_ID bei Betrieb ohne
// Mandanten
String pfad = SuperXManager.getWEB_INFPfad() + File.separator + ".." + File.separator + getName()
+ File.separator + "custom";
// HTML
// Excel
// Korrektur 2/2015 FIle.separator fehlte dadurch wurde nach
// customvorlage.xls gesucht
File excelVorlageFile = new File(pfad + File.separator + "vorlage.xlsx");
if (excelVorlageFile.exists()) {
excelVorlage = excelVorlageFile.getAbsolutePath();
// Workbook Objekt erzeugen und per clone ausliefern wäre schön
// Workbookobjekt erlaubt aber kein clone
}
// PDF sx_repository Eintrag in Datei schreiben
File f = new File(pfad);
if (!f.exists())
f.mkdirs();
File customPdfFile = new File(pfad + File.separator + "custom_pdf.xsl");
if (customPdfFile.exists()) {
customPdfFile.delete();
}
if (repositoryMap.get("CUSTOM_PDF") != null
&& !((de.superx.common.RepositoryItemCollection) repositoryMap.get("CUSTOM_PDF")).getContent()
.equals("")) {
FileUtils.writeStringToFile(customPdfFile,
((de.superx.common.RepositoryItemCollection) repositoryMap.get("CUSTOM_PDF")).getContent());
}
hasCustomPdfFile = customPdfFile.exists();
} catch (Exception e) {
return Optional.of(e);
}
return Optional.empty();
}
public boolean hasCustomPDFFile() {
return hasCustomPdfFile;
}
/**
* Initialize fieldElementCache from db.
*
* Configurable (via servlet params in web.xml) caching of Sichten and Felder.
*
* @return result of initialization (Optional.empty(): success, otherwise
* contains the Exception thrown)
*/
private Optional<Throwable> initFieldElementCache() {
try {
fieldElementCache.init();
if (SuperXManager.isSichtenCachingWanted) {
logger.info(" Caching von Sichten mit statischem SQL (Mandant:" + getName() + ")...");
// Sichten
SxResultSet rs = null;
try {
rs = ServletUtils.execute("potentielle zu cachende Sichtenquellen lesen",
"select name_intern,art,quelle,cacheapplet,cachexml from sichten "
+ "where tid>10 and type!=20 and aktiv=1 "
+ "and (length(quelle) > 7 and substring(quelle from 7 for (length(quelle)-7)) not like '%<<%') "
+ " and quelle not like '%${%' and quelle not like '%--freemarker%' and quelle not like '%<@%'",
getName());
} catch (Exception e) {
// TODO: Do we really not want to propagate this exception here?
logger.error("Error beim Einlesen potentielle zu cachende Sichtenquellen " + e);
}
if (rs != null) {
for (Iterator it = rs.iterator(); it.hasNext();) {
SxResultRow row = (SxResultRow) it.next();
if (fieldElementCache.isSichtCachingWanted((String) row.get(2))) {
try {
String sqlQuery = (String) row.get(2);
// in Spalte cacheapplet und cachexml kann zusätzlicher SQL für die Quelle
// hinterlegt
// sein
if (row.get(3) != null)
sqlQuery += " " + row.get(3);
if (row.get(4) != null)
sqlQuery += " " + row.get(4);
Logger.getLogger("superx_" + getName()).log(Level.DEBUG,
" Cache Sicht: " + row.get(0));
SxResultSet items = ServletUtils.executeALL_el(null, null,
"Elemente für zu cachende Sicht " + row.get(0),
fieldElementCache.generateSQL(sqlQuery, getSqlDialect()), getName(), false)
.getResultSet();
boolean isOrganigramm = false;
if (row.get(1).toString().equals("Organigramm-Sicht")) {
isOrganigramm = true;
}
fieldElementCache.addSicht(this.getName(), (String) row.get(0), items, isOrganigramm);
} catch (Exception e) {
// TODO: Do we really not want to propagate this exception here?
Logger.getLogger("superx_" + getName()).log(Level.INFO,
"Problem bei Caching der Sicht " + row.get(0) + " " + e);
}
}
}
}
logger.info("OK");
} else {
logger.info("Caching von Sichten mit statischem SQL deaktiviert");
}
if (SuperXManager.field1Cache == null || SuperXManager.field1Cache.equals("")) {
logger.info(" kein Feldart 1-caching aktiviert");
} else {
logger.info(" Feldart 1-caching (" + SuperXManager.field1Cache + ")...");
SxResultSet rs = null;
try {
// UserID oder FreeMarker ${ kommt nicht in Frage
// Informix kann kein distinct relation weil blob
rs = ServletUtils
.execute("potentielle zu cachende Felderquellen lesen",
"select relation from felderinfo where " + SuperXManager.field1Cache
+ " and art=1 and substring(relation from 7 for (length(relation)-7)) not like '%<<%' and relation not like '%${%' and relation not like '%--freemarker%' and relation not like '%<@%' and relation not like '%#dbid:%' and tid!=23541",
getName());
} catch (Exception e) {
// TODO: Do we really not want to propagate this exception here?
logger.error("Error beim Einlesen potentielle zu cachende Felderquellen ", e);
}
if (rs != null) {
TreeSet sqls = new TreeSet();
String haushaltsjahr = DateUtils.getYear(new java.sql.Date(new java.util.Date().getTime()));
Hashtable formular = new Hashtable();
formular.put("Haushaltsjahr", haushaltsjahr);
for (Iterator it = rs.iterator(); it.hasNext();) {
SxResultRow row = (SxResultRow) it.next();
String sql = (String) row.get(0);
if (sql.trim().indexOf("<<SQL>>") == -1)
continue;
sql = SqlStringUtils.generateSQL("PG", formular, sql);// Database
// -
// Abbr
// für
// haushaltsjahr
// egal
sql = AbstractSicht.getStrippedSQL(sql);
if (sql.indexOf("<<") == -1)
sqls.add(sql);
}
for (Iterator it = sqls.iterator(); it.hasNext();) {
String sql = (String) it.next();
Logger.getLogger("superx_" + getName()).log(Level.DEBUG, " Cache Feld-SQL: " + sql);
try {
rs = ServletUtils.executeALL_el(null, null, "Felder-SQL cachen", sql, getName(), false)
.getResultSet();
fieldElementCache.add(sql, rs);
} catch (Exception e) {
// TODO: Do we really not want to propagate this exception here?
Logger.getLogger("superx_" + getName()).log(Level.INFO,
"Problem bei Caching des Feld-SQLs " + sql + " " + e);
}
}
}
logger.info("OK");
}
} catch (Exception e) {
return Optional.of(e);
}
return Optional.empty();
}
/**
* Initialize cache for sichtart_rechttabelle from db
*
* @return result of initialization (Optional.empty(): success, otherwise
* contains the Exception thrown)
*/
private Optional<Throwable> initSichtartRechteDefinition() {
sichtartRechteDefinitionen.clear();
try (Connection con = this.getConnection()) {
if (SqlStringUtils.tableExists(con, "sichtart_rechttabelle", getName())) {
SxResultSet rs = ServletUtils.execute("Einlesen von sichtartRechttable (ab 4.5)",
"select art,tabelle,feldname,additionalkeyssql,fallback_user_inst from sichtart_rechttabelle",
getName());
for (Iterator it = rs.iterator(); it.hasNext();) {
SxResultRow row = (SxResultRow) it.next();
String sichtart = (String) row.get(0);
String tabelle = (String) row.get(1);
String feldname = (String) row.get(2);
String additionalKeys = (String) row.get(3);
boolean fallback_user_inst = false;
if (row.get(4) != null && row.get(4).toString().equals("1"))
fallback_user_inst = true;
SichtartRechteDefinition sd = new SichtartRechteDefinition();
sd.setName(sichtart);
sd.setTabelle(tabelle);
sd.setFeld(feldname);
sd.setFallback_user_inst(fallback_user_inst);
if (additionalKeys != null && additionalKeys.startsWith("sp_")) {
if (getDatabaseAbbr().equals("PG"))
additionalKeys = "select " + additionalKeys;
else
additionalKeys = "execute procedure " + additionalKeys;
}
sd.setAdditionalKeys(additionalKeys);
sichtartRechteDefinitionen.add(sd);
}
}
} catch (Exception e) {
return Optional.of(e);
}
return Optional.empty();
}
public NamedObjectList getSichtartRechteDefinitionen() {
return sichtartRechteDefinitionen;
}
/**
* Initialize cache externalPools from db.
*
* This stores external db connection configurations.
*
* @return result of initialization (Optional.empty(): success, otherwise
* contains the Exception thrown)
*/
private Optional<Throwable> initExternalPools() {
try {
String sql = "SELECT id, \n" + " driver, \n" + " url, \n" + " username, \n"
+ " passwort, \n" + " minidle, \n" + " maxidle, \n" + " maxactive, \n"
+ " testsql \n" + "FROM dbconnections";
// falls reset läuft und vorher schon welche offen waren
closeExternalPools();
externalPools.clear();
try (Connection dbConnection = SxPools.getConnection(getName());
Statement stm = dbConnection.createStatement();
ResultSet rs = stm.executeQuery(sql)) {
while (rs.next()) {
String externalid = rs.getString(1);
String driver = rs.getString(2);
String url = rs.getString(3);
String username = rs.getString(4);
String password = rs.getString(5);
int minidle = rs.getInt(6);
int maxidle = rs.getInt(7);
int maxactive = rs.getInt(8);
String testsql = rs.getString(9);
// Es wird auf jeden Fall ein ExternalPool-Objekt erzeugt und
// hinzugefuegt,
// falls dabei ein Fehler auftritt ist der Status isOK=false und
// die exceptionMsg kann abgefragt werden
ExternalPool pool = new ExternalPool(this.name, this.name + "-" + externalid, driver, url, username,
password, minidle, maxidle, maxactive, testsql);
externalPools.add(pool);
}
}
} catch (Exception e) {
return Optional.of(e);
}
return Optional.empty();
}
private void closeExternalPools() throws SQLException {
Iterator it = externalPools.iterator();
if (it.hasNext()) {
PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
while (it.hasNext()) {
ExternalPool pool = (ExternalPool) it.next();
if (pool.isOK())
driver.closePool(pool.getName());
}
}
}
/**
* Initialize fin rights
*
* @return result of initialization (Optional.empty(): success, otherwise
* contains the Exception thrown)
*/
private Optional<Throwable> initFinRights() {
finRightVariant = SxFinRechte.NO_RIGHTS;
try (Connection dbConnection = SxPools.getConnection(getName());
Statement stm = dbConnection.createStatement()) {
boolean isFinFound = false;
DatabaseMetaData md = dbConnection.getMetaData();
String[] types = { "TABLE" };
// wenn fin_user_kam exisitert simple rights
try (ResultSet rs = md.getTables(null, null, "fin_user_kam", types)) {
if (rs.next()) {
isFinFound = true;
finRightVariant = SxFinRechte.SIMPLE_RIGHTS;
} else {
logger.info("Kein Fin-Modul gefunden (fin_user_kam)");
}
}
if (isFinFound) {
// wenn in fin_user_kam kapitel existiert erweiterte Rechte
try (ResultSet rs = md.getColumns(null, null, "fin_user_kam", null)) {
while (rs.next()) {
if (rs.getString(4).equals("kapitel")) {
finRightVariant = SxFinRechte.EXTENDED_RIGHTS;
logger.info("erweiterte FIN_user_kam gefunden - OK");
}
if (rs.getString(4).equals("restrict_konten")) {
hasFinUserKamRestrictionFields = true;
}
}
}
// wenn erweiterte Rechte aber keine %k3% in fin_buch oder
// fin_konto_aggr
int k3count = 1;
/*
* MB 8/2015 rausgenommen, nur für alte FIn-Modul relevant, sehr langsam bei
* Informix ResultSet rs2 = stm .executeQuery(
* "select 1 from xdummy where (select count(*) from fin_buch where kaminfo like '%k3%')>1 and (select count(*) from fin_konto_aggr where kaminfo like '%k3%')>1 union select 0 from xdummy where (select count(*) from fin_buch where kaminfo like '%k3%')=0 and (select count(*) from fin_konto_aggr where kaminfo like '%k3%')=0"
* ); int k3count = 0; while (rs2.next()) // wenn fin_buch_gefüllt, aber
* fin_konto_aggr // nicht (h1) kam kein satz zurück, // Postgresfehler {
* k3count = rs2.getInt(1); } rs2.close();
*/
if (finRightVariant == SxFinRechte.EXTENDED_RIGHTS && k3count > 0) {
finRightVariant = SxFinRechte.INS3_RIGHTS;
logger.info("erweiterte FIN_user_kam inkl. ins2/3 gefunden - OK");
}
}
SxResultSet rs2 = ServletUtils.execute("",
"select apnr from konstanten where beschreibung='FIN_RECHTE_0_JOKER'", getName());
for (Iterator iterator = rs2.iterator(); iterator.hasNext();) {
SxResultRow r = (SxResultRow) iterator.next();
logger.info(r.get(0) + " " + r.get(0).toString().equals("0"));
if (r.get(0) != null && r.get(0).toString().equals("0"))
is0FINJoker = false;
}
logger.info(DateUtils.getNowString() + " finrights fertig");
} catch (Exception e) {
Logger.getLogger("superx_" + getName()).log(Level.ERROR, e.toString());
// TODO: Is this necessary here?
// SxPools.invalidate(getName(), dbConnection);
return Optional.of(e);
}
return Optional.empty();
}
/*
* Ist 0 auch für SxFinRechte ein Joker , default true
*/
public boolean is0FINJoker() {
return is0FINJoker;
}
public int getFinRightVariant() {
return finRightVariant;
}
private void initMask(Integer tid) throws TransformerConfigurationException, TemplateException,
KeyParentEqualException, CloneNotSupportedException, SichtException, IOException, SQLException,
DBServletException, NoMainEntryException {
System.out.println("adding " + tid + " to Maskenpool");
maskenpool.add(new Maske(this.getName(), null, tid, TranslationContainer.defaultLocale));
}
/**
* Initialize Freemarker template processor with contents of fm_templates from
* db
*
* @return result of initialization (Optional.empty(): success, otherwise
* contains the Exception thrown)
*/
private Optional<Throwable> initFMTemplates() {
try {
SxResultSet rawFmTemplates = ServletUtils.execute("Hole allg. FreeMarker Templates aus der DB",
"select trim(id),content from fm_templates", getName());
templateProcessor.setTemplates(rawFmTemplates);
} catch (Exception e) {
return Optional.of(e);
}
return Optional.empty();
}
/**
* mit integer id klappt irgendwarum nicht daher zweite Variante angelegt
**/
public GraphicFormat getGraphicFormat(String graphicFormat) {
GraphicFormat result = null;
Optional<Throwable> error = initGraphicsFormats();
if (error.isPresent()) {
logger.error(error.get().getMessage(), error.get());
}
try {
Integer graphicFormatNr = Integer.valueOf(graphicFormat);
result = (GraphicFormat) graphicformats.getById(graphicFormatNr);
} catch (RuntimeException e) {
throw new IllegalArgumentException(
"Kein GraphicFormat mit id " + graphicFormat + " in der Datenbank gefunden.");
}
return result;
}
public GraphicFormat getGraphicFormat2(String graphicFormat) {
GraphicFormat result = null;
Optional<Throwable> error = initGraphicsFormats();
if (error.isPresent()) {
logger.error(error.get().getMessage(), error.get());
}
try {
result = (GraphicFormat) graphicformats.getById(graphicFormat);
} catch (RuntimeException e) {
throw new IllegalArgumentException(
"Kein GraphicFormat mit id " + graphicFormat + " in der Datenbank gefunden.");
}
return result;
}
public ServletTemplateProcessor getTemplateProcessor() {
return templateProcessor;
}
public static void main(String args[]) {
}
public String getDatabaseAbbr() {
return databaseAbbrevation;
}
public HashMap getRepository() {
return repositoryMap;
}
public void clearLogFiles() throws IOException {
closeLoggers();
initLogging(false, Level.ERROR);
}
private void initDSAHandler() throws DBServletException {
// privateKey wird ggfs. im Konstruktur bei Connection-Test, public key
// aus properties eingelesen
if (privateKeyEncoded == null)
throw new IllegalStateException("privatekey war null - sx_repository auf Eintrag überprüfen");
if (publicKeyEncoded == null)
throw new IllegalStateException("publickey war null - sx_repository auf Eintrag prüfen");
try {
dsaHandler = new DSAHandler(privateKeyEncoded, publicKeyEncoded);
} catch (Exception e) {
throw new DBServletException(e.toString());
}
}
public boolean hasDSAHandler() {
return dsaHandler != null;
}
public boolean verifiy(String data, String signature)
throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, SignatureException {
if (dsaHandler == null)
throw new IllegalStateException("DSAHandler ist null, public und private key definition prüfen");
return dsaHandler.verify(data, signature);
}
public String getPrivateKey() {
return privateKeyEncoded;
}
public boolean isRestrictedConnection() {
return isRestrictedConnection;
}
public NewPasswordChecker getNewPWChecker() {
return newPasswordChecker;
}
public FieldElementCache getFieldElementCache() {
return fieldElementCache;
}
public String getFinRightVariantName() {
String result = "einfach";
if (finRightVariant == SxFinRechte.EXTENDED_RIGHTS)
result = "erweitert ohne ins2/ins3";
if (finRightVariant == SxFinRechte.INS3_RIGHTS)
result = "erweitert inkl. ins2/3";
return result;
}
public String customHTMLHeaderFooter(String result) {
if (repositoryMap.get("HTML_HEADER") != null
&& !((de.superx.common.RepositoryItemCollection) repositoryMap.get("HTML_HEADER")).getContent()
.equals("")) {
Pattern customheadertablePattern = Pattern.compile("<table .* id=\"customheader\".*?</table>",
Pattern.DOTALL);
Matcher action = customheadertablePattern.matcher(result);
String newstuff = ((de.superx.common.RepositoryItemCollection) repositoryMap.get("HTML_HEADER"))
.getContent();
result = action.replaceAll(newstuff);
}
if (repositoryMap.get("HTML_FOOTER") != null
&& !((de.superx.common.RepositoryItemCollection) repositoryMap.get("HTML_FOOTER")).getContent()
.equals(""))
result = StringUtils.replace(result, "<!--customfooter-->",
((de.superx.common.RepositoryItemCollection) repositoryMap.get("HTML_FOOTER")).getContent());
return result;
}
public String getExcelVorlage() {
return excelVorlage;
}
public int getDatabaseMinorVersion() throws SQLException {
int version = 0;
try (Connection con = getConnection()) {
version = con.getMetaData().getDatabaseMinorVersion();
}
return version;
}
public int getDatabaseMajorVersion() throws SQLException {
int version = 0;
try (Connection con = getConnection()) {
version = con.getMetaData().getDatabaseMajorVersion();
}
return version;
}
public boolean hasExternalPool(String epName) {
return externalPools.containsItemWithName(epName);
}
public ExternalPool getExternalPool(String epName) {
return (ExternalPool) externalPools.getByName(epName);
}
public String checkImports(String input) throws SQLException {
String result = null;
if (input != null) {
StringBuffer work = new StringBuffer(input);
boolean importsFounds = input.indexOf("<sximport>") > -1;
if (importsFounds) {
try (Connection dbConnection = SxPools.getConnection(getName());
Statement stm = dbConnection.createStatement()) {
while (work.indexOf("<sximport") > -1) {
int posstart = work.indexOf("<sximport>");
int posende = work.indexOf("</sximport>", posstart);
if (posende == -1)
throw new IllegalArgumentException("Tag sximport nicht ordentlich beendet");
String importInstruction = work.substring(posstart + 10, posende);
try (ResultSet rs = stm.executeQuery(importInstruction)) {
boolean validReplaceText=false;
while (rs.next()) {
validReplaceText=true;
de.memtext.util.StringUtils.replace(work,
"<sximport>" + importInstruction + "</sximport>",
SqlStringUtils.getValueAsString(rs.getObject(1)));
}
rs.close();
if(!validReplaceText)
break;
}
}
stm.close();
dbConnection.close();
}
}
result = work.toString();
}
return result;
}
private void initProperties(Properties dbProperties) throws DBServletException, SQLException {
try {
if (dbProperties == null || dbProperties.isEmpty()) {
if (new File(getDbPropertyFilePath()).exists()) {
readPropertiesAndUrl();
logger.info(" (" + this.props.getProperty("connectionURL") + ") ..");
} else {
logger.warn("No dbproperties found and no explicit properties set - setting emtpy properties!");
this.props = new Properties();
}
} else {
// this is for unit testing to "inject" db properties
logger.info("Setting explicit properties");
this.props = dbProperties;
}
checkRestrictedConnection();
} catch (Exception e) {
logger.error("Konnte db.properties nicht verarbeiten ", e);
throw new DBServletException("Konnte properties / Passwort nicht lesen. " + e.getMessage());
}
}
private void configureDbcp() throws DBServletException {
try {
Class.forName(this.props.getProperty("driverName"));
} catch (ClassNotFoundException e1) {
throw new DBServletException("Treiber " + this.props.getProperty("driverName")
+ " nicht gefunden. Ggfs. nach tomcat/common/lib kopieren.");
}
setTestOnBorrow(true);
String devMode = this.props.getProperty("developmentMode");
SuperXManager.isDevelopmentMode = (devMode == null || devMode.equals("true")) ? true : false;
setMinIdle(NumberUtils.toInt(this.props.getProperty("minIdle"), 5));
setMaxIdle(NumberUtils.toInt(this.props.getProperty("maxIdle"), -1));
setMaxActive(NumberUtils.toInt(this.props.getProperty("maxActive"), -1));
setMaxWait(NumberUtils.toLong(this.props.getProperty("maxWait"), -1));
setTimeBetweenEvictionRunsMillis(
NumberUtils.toInt(this.props.getProperty("timeBetweenEvictionRunsMillis"), -1));
ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
this.props.getProperty("connectionURL"), this.props);
PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, this,
null, "select count(*) from xdummy;", false, true);
this.setFactory(poolableConnectionFactory);
}
private void initHikariPool() {
His1DataSources dataSources = ApplicationContextHolder.getBean("dataSources", His1DataSources.class);
if (dataSources == null) {
logger.warn("No Spring bean dataSources available. Will init Hikari pool standalone!");
AppConfig batchConfig = new AppConfig();
dataSources = batchConfig.dataSources();
}
this.eduetlDataSource = dataSources.get("eduetl");
}
private void initDbcpPoolingDriver() throws DBServletException, SQLException {
try {
// PoolingDriver driver = new PoolingDriver();
Class.forName("org.apache.commons.dbcp.PoolingDriver");
} catch (ClassNotFoundException e2) {
throw new DBServletException(
"ConnectionPool Klasse org.apache.commons.dbcp.PoolingDriver nicht gefunden.\ncommons-dbcp nach tomcat/common/lib stellen.");
}
PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
driver.registerPool(this.getName(), this);
}
private void setDatabaseAbbreviation() throws SQLException {
try (Connection con = getConnection()) {
String product = con.getMetaData().getDatabaseProductName();
if (product.toLowerCase().contains("postgres") || product.toLowerCase().contains("h2")) {
this.databaseAbbrevation = "PG";
} else {
this.databaseAbbrevation = "IDS";
}
}
}
public void evictConnection(Connection con) {
if (!DEFAULT_MANDANTEN_ID.equals(this.name)) {
return;
}
HikariDataSource hikariDs = (HikariDataSource) this.eduetlDataSource;
hikariDs.evictConnection(con);
}
}
// Created on 04.11.2004 at 20:18:11