<commit_before>/*******************************************************************************
 * Copyright (c) 2006-2011, <NAME> and Elexis
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    <NAME> - initial implementation
 *    <NAME> - better support for IDataAccess
 *    <NAME> - introduced SQL Fields
 * 
 *******************************************************************************/

package ch.elexis.core.ui.text;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipInputStream;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormText;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.elexis.core.constants.Preferences;
import ch.elexis.core.constants.StringConstants;
import ch.elexis.core.data.activator.CoreHub;
import ch.elexis.core.data.constants.ExtensionPointConstantsData;
import ch.elexis.core.data.events.ElexisEventDispatcher;
import ch.elexis.core.data.interfaces.text.ITextResolver;
import ch.elexis.core.data.interfaces.text.ReplaceCallback;
import ch.elexis.core.data.util.Extensions;
import ch.elexis.core.data.util.ScriptUtil;
import ch.elexis.core.exceptions.ElexisException;
import ch.elexis.core.model.IPersistentObject;
import ch.elexis.core.text.XRefExtensionConstants;
import ch.elexis.core.text.model.Samdas;
import ch.elexis.core.ui.UiDesk;
import ch.elexis.core.ui.constants.ExtensionPointConstantsUi;
import ch.elexis.core.ui.dialogs.DocumentSelectDialog;
import ch.elexis.core.ui.dialogs.KontaktSelektor;
import ch.elexis.core.ui.preferences.TextTemplatePreferences;
import ch.elexis.core.ui.util.SWTHelper;
import ch.elexis.data.Brief;
import ch.elexis.data.Fall;
import ch.elexis.data.Konsultation;
import ch.elexis.data.Kontakt;
import ch.elexis.data.Mandant;
import ch.elexis.data.PersistentObject;
import ch.elexis.data.Person;
import ch.elexis.data.Query;
import ch.elexis.data.Script;
import ch.rgw.tools.ExHandler;
import ch.rgw.tools.JdbcLink;
import ch.rgw.tools.JdbcLink.Stm;
import ch.rgw.tools.StringTool;
import ch.rgw.tools.TimeTool;

public class TextContainer {
	private static final String WARNING_SIGN = "??"; //$NON-NLS-1$
	public static final String MATCH_SQUARE_BRACKET = "[\\[\\]]"; //$NON-NLS-1$
	private static final String TEMPLATE_NOT_FOUND_HEADER =
		Messages.TextContainer_TemplateNotFoundHeader;
	private static final String TEMPLATE_NOT_FOUND_BODY =
		Messages.TextContainer_TemplateNotFoundBody;
	
	private ITextPlugin plugin = null;
	private static Logger log = LoggerFactory.getLogger(TextContainer.class); //$NON-NLS-1$
	private Shell shell;
	private static final String DONT_SHOW_REPLACEMENT_ERRORS = "*";
	public static final String MATCH_TEMPLATE = "\\[[" + DONT_SHOW_REPLACEMENT_ERRORS //$NON-NLS-1$
		+ "]?[-a-zA-ZäöüÄÖÜéàè_ ]+\\.[-a-zA-Z0-9äöüÄÖÜéàè_ ]+\\]";
	public static final String MATCH_INDIRECT_TEMPLATE = "\\[[" + DONT_SHOW_REPLACEMENT_ERRORS //$NON-NLS-1$
		+ "]?[-a-zA-ZäöüÄÖÜéàè_ ]+(\\.[-a-zA-Z0-9äöüÄÖÜéàè_ ]+)+\\]";
	public static final String MATCH_GENDERIZE =
		"\\[[" + DONT_SHOW_REPLACEMENT_ERRORS + "]?[a-zA-Z]+:mwn?:[^\\[]+\\]"; //$NON-NLS-1$
	//public static final String MATCH_IDATACCESS = "\\[[-_a-zA-Z0-9]+:[-a-zA-Z0-9]+:[-a-zA-Z0-9\\.]+:[-a-zA-Z0-9\\.]:?.*\\]"; //$NON-NLS-1$
	public static final String MATCH_IDATACCESS = "\\[[" + DONT_SHOW_REPLACEMENT_ERRORS //$NON-NLS-1$
		+ "]?[-_a-zA-Z0-9]+:[-a-zA-Z0-9]+:[-a-zA-Z0-9\\.]+:[-a-zA-Z0-9\\.]:?[^\\]]*\\]";
	public static final String MATCH_SQLCLAUSE =
		"\\[[" + DONT_SHOW_REPLACEMENT_ERRORS + "]?SQL[^:]*:[^\\[]+\\]"; //$NON-NLS-1$
	public static final String DISALLOWED_SQLEXPRESSIONS = "DROP,UPDATE,CREATE,INSERT"; //$NON-NLS-1$
	//public static final String MATCH_SCRIPT = "\\["+Script.SCRIPT_MARKER+".+\\]"; //$NON-NLS-1$
	public static final String MATCH_SCRIPT = "\\[" + Script.SCRIPT_MARKER + "[^\\[]+\\]"; //$NON-NLS-1$
	
	public static Connection queryConn = null;
	
	/**
	 * Der Konstruktor sucht nach dem in den Settings definierten Textplugin Wenn er kein Textplugin
	 * findet, wählt er ein rudimentäres Standardplugin aus (das in der aktuellen Version nur eine
	 * Fehlermeldung ausgibt)
	 */
	public TextContainer(){
		if (plugin == null) {
			String ExtensionToUse = CoreHub.localCfg.get(Preferences.P_TEXTMODUL, null);
			IExtensionRegistry exr = Platform.getExtensionRegistry();
			IExtensionPoint exp =
				exr.getExtensionPoint(ExtensionPointConstantsUi.TEXTPROCESSINGPLUGIN);
			if (exp != null) {
				IExtension[] extensions = exp.getExtensions();
				for (IExtension ex : extensions) {
					IConfigurationElement[] elems = ex.getConfigurationElements();
					for (IConfigurationElement el : elems) {
						if ((ExtensionToUse == null) || el.getAttribute("name").equals( //$NON-NLS-1$
							ExtensionToUse)) {
							try {
								plugin = (ITextPlugin) el.createExecutableExtension("Klasse"); //$NON-NLS-1$
							} catch (/* Core */Exception e) {
								ExHandler.handle(e);
							}
						}
						
					}
				}
			}
		}
		if (plugin == null) {
			plugin = new DefaultTextPlugin();
		}
	}
	
	public TextContainer(final IViewSite s){
		this();
		shell = s.getShell();
	}
	
	public TextContainer(final Shell s){
		this();
		shell = s;
	}
	
	public void setFocus(){
		plugin.setFocus();
	}
	
	public ITextPlugin getPlugin(){
		return plugin;
	}
	
	public void dispose(){
		plugin.dispose();
	}
	
	private Brief loadTemplate(String name){
		Query<Brief> qbe = new Query<Brief>(Brief.class);
		qbe.add(Brief.FLD_TYPE, Query.EQUALS, Brief.TEMPLATE);
		qbe.and();
		qbe.add(Brief.FLD_SUBJECT, Query.EQUALS, name);
		qbe.startGroup();
		qbe.add(Brief.FLD_DESTINATION_ID, Query.EQUALS, CoreHub.actMandant.getId());
		qbe.or();
		qbe.add(Brief.FLD_DESTINATION_ID, Query.EQUALS, StringTool.leer);
		qbe.endGroup();
		List<Brief> list = qbe.execute();
		if ((list == null) || (list.size() == 0)) {
			return null;
		}
		Brief template = list.get(0);
		return template;
	}
	
	/**
	 * Ein Dokument aus einer namentlich genannten Vorlage erstellen. Die Vorlage muss entweder dem
	 * aktuellen Mandanten oder allen Mandanten zugeordet sein.
	 * 
	 * @param templatename
	 *            Name der Vorlage. Wenn in der lokalen Konfiguration
	 *            (Datei-Einstellungen-Textvorlagen) eine Alternative zu diesem Vorlagennamen
	 *            hinterlegt ist, wird diese genommen
	 * @param typ
	 *            Typ des zu erstellenden Dokuments
	 * @param adressat<commit_msg>[16427] updated loadTemplate to select mandantor specific if present<commit_after>/*******************************************************************************
 * Copyright (c) 2006-2011, <NAME> and Elexis
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    <NAME> - initial implementation
 *    <NAME> - better support for IDataAccess
 *    <NAME> - introduced SQL Fields
 * 
 *******************************************************************************/

package ch.elexis.core.ui.text;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipInputStream;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormText;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.elexis.core.constants.Preferences;
import ch.elexis.core.constants.StringConstants;
import ch.elexis.core.data.activator.CoreHub;
import ch.elexis.core.data.constants.ExtensionPointConstantsData;
import ch.elexis.core.data.events.ElexisEventDispatcher;
import ch.elexis.core.data.interfaces.text.ITextResolver;
import ch.elexis.core.data.interfaces.text.ReplaceCallback;
import ch.elexis.core.data.util.Extensions;
import ch.elexis.core.data.util.ScriptUtil;
import ch.elexis.core.exceptions.ElexisException;
import ch.elexis.core.model.IPersistentObject;
import ch.elexis.core.text.XRefExtensionConstants;
import ch.elexis.core.text.model.Samdas;
import ch.elexis.core.ui.UiDesk;
import ch.elexis.core.ui.constants.ExtensionPointConstantsUi;
import ch.elexis.core.ui.dialogs.DocumentSelectDialog;
import ch.elexis.core.ui.dialogs.KontaktSelektor;
import ch.elexis.core.ui.preferences.TextTemplatePreferences;
import ch.elexis.core.ui.util.SWTHelper;
import ch.elexis.data.Brief;
import ch.elexis.data.Fall;
import ch.elexis.data.Konsultation;
import ch.elexis.data.Kontakt;
import ch.elexis.data.Mandant;
import ch.elexis.data.PersistentObject;
import ch.elexis.data.Person;
import ch.elexis.data.Query;
import ch.elexis.data.Script;
import ch.rgw.tools.ExHandler;
import ch.rgw.tools.JdbcLink;
import ch.rgw.tools.JdbcLink.Stm;
import ch.rgw.tools.StringTool;
import ch.rgw.tools.TimeTool;

public class TextContainer {
	private static final String WARNING_SIGN = "??"; //$NON-NLS-1$
	public static final String MATCH_SQUARE_BRACKET = "[\\[\\]]"; //$NON-NLS-1$
	private static final String TEMPLATE_NOT_FOUND_HEADER =
		Messages.TextContainer_TemplateNotFoundHeader;
	private static final String TEMPLATE_NOT_FOUND_BODY =
		Messages.TextContainer_TemplateNotFoundBody;
	
	private ITextPlugin plugin = null;
	private static Logger log = LoggerFactory.getLogger(TextContainer.class); //$NON-NLS-1$
	private Shell shell;
	private static final String DONT_SHOW_REPLACEMENT_ERRORS = "*";
	public static final String MATCH_TEMPLATE = "\\[[" + DONT_SHOW_REPLACEMENT_ERRORS //$NON-NLS-1$
		+ "]?[-a-zA-ZäöüÄÖÜéàè_ ]+\\.[-a-zA-Z0-9äöüÄÖÜéàè_ ]+\\]";
	public static final String MATCH_INDIRECT_TEMPLATE = "\\[[" + DONT_SHOW_REPLACEMENT_ERRORS //$NON-NLS-1$
		+ "]?[-a-zA-ZäöüÄÖÜéàè_ ]+(\\.[-a-zA-Z0-9äöüÄÖÜéàè_ ]+)+\\]";
	public static final String MATCH_GENDERIZE =
		"\\[[" + DONT_SHOW_REPLACEMENT_ERRORS + "]?[a-zA-Z]+:mwn?:[^\\[]+\\]"; //$NON-NLS-1$
	//public static final String MATCH_IDATACCESS = "\\[[-_a-zA-Z0-9]+:[-a-zA-Z0-9]+:[-a-zA-Z0-9\\.]+:[-a-zA-Z0-9\\.]:?.*\\]"; //$NON-NLS-1$
	public static final String MATCH_IDATACCESS = "\\[[" + DONT_SHOW_REPLACEMENT_ERRORS //$NON-NLS-1$
		+ "]?[-_a-zA-Z0-9]+:[-a-zA-Z0-9]+:[-a-zA-Z0-9\\.]+:[-a-zA-Z0-9\\.]:?[^\\]]*\\]";
	public static final String MATCH_SQLCLAUSE =
		"\\[[" + DONT_SHOW_REPLACEMENT_ERRORS + "]?SQL[^:]*:[^\\[]+\\]"; //$NON-NLS-1$
	public static final String DISALLOWED_SQLEXPRESSIONS = "DROP,UPDATE,CREATE,INSERT"; //$NON-NLS-1$
	//public static final String MATCH_SCRIPT = "\\["+Script.SCRIPT_MARKER+".+\\]"; //$NON-NLS-1$
	public static final String MATCH_SCRIPT = "\\[" + Script.SCRIPT_MARKER + "[^\\[]+\\]"; //$NON-NLS-1$
	
	public static Connection queryConn = null;
	
	/**
	 * Der Konstruktor sucht nach dem in den Settings definierten Textplugin Wenn er kein Textplugin
	 * findet, wählt er ein rudimentäres Standardplugin aus (das in der aktuellen Version nur eine
	 * Fehlermeldung ausgibt)
	 */
	public TextContainer(){
		if (plugin == null) {
			String ExtensionToUse = CoreHub.localCfg.get(Preferences.P_TEXTMODUL, null);
			IExtensionRegistry exr = Platform.getExtensionRegistry();
			IExtensionPoint exp =
				exr.getExtensionPoint(ExtensionPointConstantsUi.TEXTPROCESSINGPLUGIN);
			if (exp != null) {
				IExtension[] extensions = exp.getExtensions();
				for (IExtension ex : extensions) {
					IConfigurationElement[] elems = ex.getConfigurationElements();
					for (IConfigurationElement el : elems) {
						if ((ExtensionToUse == null) || el.getAttribute("name").equals( //$NON-NLS-1$
							ExtensionToUse)) {
							try {
								plugin = (ITextPlugin) el.createExecutableExtension("Klasse"); //$NON-NLS-1$
							} catch (/* Core */Exception e) {
								ExHandler.handle(e);
							}
						}
						
					}
				}
			}
		}
		if (plugin == null) {
			plugin = new DefaultTextPlugin();
		}
	}
	
	public TextContainer(final IViewSite s){
		this();
		shell = s.getShell();
	}
	
	public TextContainer(final Shell s){
		this();
		shell = s;
	}
	
	public void setFocus(){
		plugin.setFocus();
	}
	
	public ITextPlugin getPlugin(){
		return plugin;
	}
	
	public void dispose(){
		plugin.dispose();
	}
	
	private Brief loadTemplate(String name){
		Mandant mandantor = ElexisEventDispatcher.getSelectedMandator();
		Query<Brief> qbe = new Query<Brief>(Brief.class);
		qbe.add(Brief.FLD_TYPE, Query.EQUALS, Brief.TEMPLATE);
		qbe.and();
		qbe.add(Brief.FLD_SUBJECT, Query.EQUALS, name);
		qbe.startGroup();
		if(mandantor != null) {
			qbe.add(Brief.FLD_DESTINATION_ID, Query.EQUALS, mandantor.getId());
			qbe.or();			
		}
		qbe.add(Brief.FLD_DESTINATION_ID, Query.EQUALS, StringTool.leer);
		qbe.endGroup();
		List<Brief> list = qbe.execute();
		Brief ret = null;
		if (list != null && !list.isEmpty()) {
			ret = list.get(0);
			if (list.size() > 1) {
				if(mandantor != null) {
					for (Brief brief : list) {
						if (mandantor.getId().equals(brief.get(Brief.FLD_DESTINATION_ID))) {
							ret = brief;
							break;
						}
					}					
				}
			}
		}
		return ret;
	}
	
	/**
	 * Ein Dokument aus einer namentlich genannten Vorlage erstellen. Die Vorlage muss entweder dem
	 * aktuellen Mandanten oder allen Mandanten zugeordet sein.
	 * 
	 * @param templatename
	 *            Name der Vorlage. Wenn in der lokalen Konfiguration
	 *            (Datei-Einstellungen-Textvorlagen) eine Alternative zu diesem Vorlagennamen
	 *            hinterlegt ist, wird diese genommen
	 * @param typ
	 *            Typ des zu erstellenden Dokuments
	 * @param adressat
{'fraction_non_alphanumeric': 0.1563831081903371, 'fraction_numerical': 0.006389193136181088, 'mean_word_length': 4.274390243902439, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5630172', 'n_tokens_mistral': 6194, 'n_tokens_neox': 5783, 'n_words': 1073}