java/sql-dk/src/info/globalcode/sql/dk/configuration/FormatterDefinition.java
author František Kučera <franta-hg@frantovo.cz>
Tue, 26 Feb 2019 18:19:49 +0100
branchv_0
changeset 236 a3ec71fa8e17
parent 188 54bacc7ed42b
permissions -rw-r--r--
Avoid reusing/rewriting the DB connection properties. There was weird random errors while testing connection to multiple DB in parallel when one of them was meta connection to same DB connection. Two kinds of exception: 1) missing password 2) „Passing DB password as CLI parameter is insecure!“

/**
 * SQL-DK
 * Copyright © 2013 František Kučera (frantovo.cz)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package info.globalcode.sql.dk.configuration;

import static info.globalcode.sql.dk.Xmlns.CONFIGURATION;
import info.globalcode.sql.dk.formatting.Formatter;
import info.globalcode.sql.dk.formatting.FormatterContext;
import info.globalcode.sql.dk.formatting.FormatterException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import javax.xml.bind.annotation.XmlElement;

/**
 * Configured (but not yet instantiated) formatter.
 *
 * @author Ing. František Kučera (frantovo.cz)
 */
public class FormatterDefinition implements NameIdentified {

	private String name;
	private String className;
	private Properties properties = new Properties();

	public FormatterDefinition() {
	}

	public FormatterDefinition(String name, String className) {
		this.name = name;
		this.className = className;
	}

	public FormatterDefinition(String name, String className, Properties properties) {
		this(name, className);
		this.properties = properties;
	}

	@XmlElement(name = "name", namespace = CONFIGURATION)
	@Override
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Filter's class. Must implement the
	 * <code>info.globalcode.sql.dk.formatting.Formatter</code> interface.
	 * Subclassing the
	 * <code>info.globalcode.sql.dk.formatting.AbstractFormatter</code> is strongly recommended.
	 * The constructor must accept one parameter:
	 * <code>info.globalcode.sql.dk.formatting.FormatterContext</code>
	 *
	 * @return fully qualified class name
	 */
	@XmlElement(name = "class", namespace = CONFIGURATION)
	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	@XmlElement(name = "property", namespace = CONFIGURATION)
	public Properties getProperties() {
		return properties;
	}

	public void setProperties(Properties properties) {
		this.properties = properties;
	}

	/**
	 * @param context
	 * @return
	 * @throws FormatterException
	 */
	public Formatter getInstance(FormatterContext context) throws FormatterException {
		context.getProperties().setDefaults(properties);
		try {
			Constructor constructor = Class.forName(className).getConstructor(context.getClass());

			Object instance = constructor.newInstance(context);
			if (instance instanceof Formatter) {
				return (Formatter) instance;
			} else {
				throw new FormatterException("Formatter " + instance + " does not implement the " + Formatter.class.getName() + " interface");
			}
		} catch (ClassNotFoundException e) {
			throw new FormatterException("Formatter class does not exist: " + className, e);
		} catch (NoSuchMethodException e) {
			throw new FormatterException("Formatter class with no valid constructor: " + className, e);
		} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
			throw new FormatterException("Formatter's constructor caused an error: " + className, e);
		}
	}
}