public class Database implements Validable {
	
	DBType	type;
	private String	nameFC;
	String	url;
	String	user;
	String	password;
	String	instance;
	private Integer maxactive = new Integer(15);
	private Integer maxidle = new Integer(2);
	private Integer maxwaitmillis = new Integer (10000);
	private Boolean persistent = false;
	private Integer	queryTimeout = new Integer(15);
	private Set<String>  configurationUIDs=new HashSet<String>();
	
	public DBType getType() {
		return type;
	}
	
	public String getDBNameFC() {
		return nameFC;
	}
	
	public void setDBNameFC(String nameFC) {
		this.nameFC=nameFC;
	}
	
	public String getURL() {
		return url;
	}
	
	
	public String getUser() {
		return user;
	}
	
	public String getPassword() {
		return password;
	}
	
	public String getInstance() {
		return instance;
	}
	
	@Override
	public boolean isValid() {
		return (nameFC != null) && (url != null) && (user != null) && (password != null);
	}
	
	@Override
	public String toString() {
		return "DSN:"+this.getDBNameFC()+",\ttype:"+getType() + ",\tURL:" + getURL() + ",\tInstance:" + getInstance();
	}

	public Integer getMaxWaitMillis() {
		return maxwaitmillis;
	}

	public void setMaxWaitMillis(Integer maxwaitmillis) {
		this.maxwaitmillis = maxwaitmillis;
	}

	public Integer getMaxIdle() {
		return maxidle;
	}

	public void setMaxIdle(Integer maxidle) {
		this.maxidle = maxidle;
	}


	public void setPersistence(String pers) {
		if (pers.equalsIgnoreCase("true")) {
			this.persistent = true;
		}
	}
	public Boolean getPersistence(){
		return this.persistent;
	}

	public void setMaxActive(Integer maxactive) {
		this.maxactive= maxactive;
	}

	public Integer getMaxActive() {
		return maxactive;
	}
	public int getQueryTimeout() {
		return queryTimeout;
	}
	
	public void setQueryTimeout(int queryTimeout) {
		this.queryTimeout = queryTimeout;
	}

	public Set<String> getConfigurationUIDs() {
		return configurationUIDs;
	}

	public void addConfigurationUID(String configurationUID) {
		configurationUIDs.add(configurationUID);
	}
	
	public void removeConfigurationUID(String configurationUID) {
		configurationUIDs.remove(configurationUID);
	}

} public class ALLBASE extends AbstractDBAdapter {

	public ALLBASE(String name, String url, String user, String passwd, Integer maxactive, Integer maxidle,Integer maxwaitmillis,Integer queryTimeout, Set<String> set, Boolean pers) {
		this.name = name;
		this.url = url;
		this.user = user;
		this.passwd = passwd;
		this.maxactive = maxactive.intValue();
		this.maxidle = maxidle.intValue();
		this.maxwaitmillis=maxwaitmillis.intValue();
		this.queryTimeout = queryTimeout.intValue();
		this.persistence = pers;
		this.configurationUIDs=set;
	}
	
	@Override
	public DBType getType() {
		return DBType.ALLBASE;
	}

	
}
 public interface DBAdapter {

	public DBType getType();
	public String getName();
	public String getURL();
	public String getUser();
	public String  getPassword();
	public Integer getMaxActive();
	public Integer getMaxIdle();
	public Integer getMaxWaitMillis();
	public Integer getQueryTimeout();
	//public String getItemFile();
	public Set<String> getConfigurationUIDs();
	
	public String[] getDiscoveryItems();
	public Object getDiscovery(String key);
	
	public boolean hasServerItems();
	public boolean hasUserItems();
	public boolean hasDatabaseItems();
	public boolean hasSchemaItems();
	public boolean hasTablespaceItems();
	public boolean getPersistence();
	
	
    /**
	 * Exception if database that came from Zabbix Web has not been defined in local file config yet.
	 */
	public class DBNotDefinedException extends RuntimeException
	{
		private static final long serialVersionUID = -106570768147815384L;
		//Parameterless Constructor
	      public DBNotDefinedException() {super("Database hasn't been defined in DBforBix local file config yet!");}
	      //Constructors that accept parameters
	      public DBNotDefinedException(String msg) { super(msg); }  
	      public DBNotDefinedException(Throwable cause) { super(cause); }  
	      public DBNotDefinedException(String msg, Throwable cause) { super(msg, cause); } 
	 }
	public Connection getConnection() throws SQLException, ClassNotFoundException, DBNotDefinedException;
	public void abort();
	public void reconnect();
	
	
}
 public class DB2 extends AbstractDBAdapter {

	public DB2(String name, String url, String user, String passwd, Integer maxactive, Integer maxidle,Integer maxwaitmillis, Integer queryTimeout, Set<String> set, Boolean pers) {
		this.name = name;
		this.url = url;
		this.user = user;
		this.passwd = passwd;
		this.maxactive = maxactive.intValue();
		this.maxidle = maxidle.intValue();
		this.maxwaitmillis = maxwaitmillis.intValue();
		this.queryTimeout = queryTimeout.intValue();
		this.persistence = pers;
		this.configurationUIDs=set;
				
	}
	
	@Override
	public DBType getType() {
		return DBType.DB2;
	}

	

}
 public class DB_NOT_DEFINED extends AbstractDBAdapter {

	public DB_NOT_DEFINED(String name, String url, String user, String passwd,Integer maxactive, Integer maxidle,Integer maxwaitmillis, Integer queryTimeout, Set<String> set, Boolean pers) {
		this.name = name;
		this.url = url;
		this.user = user;
		this.passwd = passwd;
		this.maxactive = maxactive.intValue();
		this.maxidle = maxidle.intValue();
		this.maxwaitmillis=maxwaitmillis.intValue();
		this.queryTimeout = queryTimeout.intValue();
		this.persistence = pers;
		this.configurationUIDs=set;
	}
	


	@Override
	public DBType getType() {
		return DBType.DB_NOT_DEFINED;
	}

	

}
 public class MSSQL extends AbstractDBAdapter {
	public MSSQL(String name, String url, String user, String passwd, Integer maxactive, Integer maxidle, Integer maxwaitmillis, Integer queryTimeout, Set<String> set, Boolean pers) {
		this.name = name;
		this.url = url;
		this.user = user;
		this.passwd = passwd;
		this.maxactive = maxactive.intValue();
		this.maxidle = maxidle.intValue();
		this.maxwaitmillis=maxwaitmillis.intValue();
		this.queryTimeout = queryTimeout.intValue();
		this.configurationUIDs = set;
		this.persistence = pers;
				
	}
	
	@Override
	public DBType getType() {
		return DBType.MSSQL;
	}
}
 public class MySQL extends AbstractDBAdapter {

	public MySQL(String name, String url, String user, String passwd, Integer maxactive, Integer maxidle, Integer maxwaitmillis, Integer queryTimeout, Set<String> set,Boolean pers) {
		this.name = name;
		this.url = url;
		this.user = user;
		this.passwd = passwd;
		this.maxactive = maxactive.intValue();
		this.maxidle = maxidle.intValue();
		this.maxwaitmillis=maxwaitmillis.intValue();
		this.queryTimeout = queryTimeout.intValue();
		this.configurationUIDs = set;
		this.persistence = pers;
				
	}

	@Override
	public DBType getType() {
		return DBType.MYSQL;
	}
}
 public class Oracle extends AbstractDBAdapter {
	
	//Error codes
	//ORA-12537 - connection closed
	public static final int ConnectionClosed=12537;

	public Oracle(String name, String url, String user, String passwd, Integer maxactive,Integer maxidle,Integer maxwaitmillis, Integer queryTimeout, Set<String> set, Boolean pers) {
		this.name = name;
		this.url = url;
		this.user = user;
		this.passwd = passwd;
		this.maxactive = maxactive;
		this.maxwaitmillis = maxwaitmillis;
		this.queryTimeout = queryTimeout.intValue();
		this.maxidle = maxidle;
		this.configurationUIDs = set;
		this.persistence = pers;
	}
	


	@Override
	public DBType getType() {
		return DBType.ORACLE;
	}


}
 public class PGSQL extends AbstractDBAdapter {

	public PGSQL(String name, String url, String user, String passwd, Integer maxactive, Integer maxidle, Integer maxwaitmillis, Integer queryTimeout, Set<String> set,Boolean pers) {
		this.name = name;
		this.url = url;
		this.user = user;
		this.passwd = passwd;
		this.maxactive = maxactive.intValue();
		this.maxidle = maxidle.intValue();
		this.maxwaitmillis=maxwaitmillis.intValue();
		this.queryTimeout = queryTimeout.intValue();
		this.configurationUIDs = set;
		this.persistence = pers;
	}
	
	@Override
	public DBType getType() {
		return DBType.PGSQL;
	}

}
 public class SQLANY extends AbstractDBAdapter {

	public SQLANY(String name, String url, String user, String passwd,Integer maxactive, Integer maxidle,Integer maxwaitmillis, Integer queryTimeout, Set<String> set, Boolean pers) {
		this.name = name;
		this.url = url;
		this.user = user;
		this.passwd = passwd;
		this.maxactive = maxactive.intValue();
		this.maxidle = maxidle.intValue();
		this.maxwaitmillis=maxwaitmillis.intValue();
		this.queryTimeout = queryTimeout.intValue();
		this.persistence = pers;
		this.configurationUIDs=set;
	}
	
	@Override
	public DBType getType() {
		return DBType.SQLANY;
	}

	

}
 public class SYBASE extends AbstractDBAdapter {

	public SYBASE(String name, String url, String user, String passwd,Integer maxactive, Integer maxidle,Integer maxwaitmillis, Integer queryTimeout, Set<String> set,Boolean pers) {
		this.name = name;
		this.url = url;
		this.user = user;
		this.passwd = passwd;
		this.maxactive = maxactive.intValue();
		this.maxidle = maxidle.intValue();
		this.maxwaitmillis=maxwaitmillis.intValue();
		this.queryTimeout = queryTimeout.intValue();
		this.configurationUIDs=set;
		this.persistence = pers;
	}
	
	@Override
	public DBType getType() {
		return DBType.SYBASE;
	}

}

import com.smartmarmot.dbforbix.db.adapter.PGSQL;
import com.smartmarmot.dbforbix.db.adapter.SQLANY;
import com.smartmarmot.dbforbix.db.adapter.SYBASE;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import com.smartmarmot.dbforbix.config.Database;
import com.smartmarmot.dbforbix.db.adapter.ALLBASE;
import com.smartmarmot.dbforbix.db.adapter.DBAdapter;
import com.smartmarmot.dbforbix.db.adapter.DB2;
import com.smartmarmot.dbforbix.db.adapter.DB_NOT_DEFINED;
import com.smartmarmot.dbforbix.db.adapter.MSSQL;
import com.smartmarmot.dbforbix.db.adapter.MySQL;
import com.smartmarmot.dbforbix.db.adapter.Oracle;

/*
 * This file is part of DBforBix.
 *
 * DBforBix 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.
 * 
 * DBforBix 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
 * DBforBix. If not, see <http://www.gnu.org/licenses/>.
 */

package com.smartmarmot.dbforbix.db;



public class DBManager {

	private static DBManager	instance;

	protected DBManager() {}

	private Set<DBAdapter>	databases	= new HashSet<>();

	public static DBManager getInstance() {
		if (instance == null)
			instance = new DBManager();
		return instance;
	}
	
//DB2, ORACLE, MSSQL, MYSQL, PGSQL, ALLBASE, SYBASE, SQLANY;
	public void addDatabase(Database cfg) {
		if(databases.contains(cfg.getDBNameFC()))
			return;
		switch (cfg.getType()) {
			case DB2:
				databases.add(new DB2(cfg.getDBNameFC(), cfg.getURL(), cfg.getUser(), cfg.getPassword(), cfg.getMaxActive(),cfg.getMaxIdle()
						,cfg.getMaxWaitMillis(),cfg.getQueryTimeout(),cfg.getConfigurationUIDs(),cfg.getPersistence()));
			break;
			case ORACLE:
				databases.add(new Oracle(cfg.getDBNameFC(), cfg.getURL(), cfg.getUser(), cfg.getPassword(),cfg.getMaxActive(),cfg.getMaxIdle()
						,cfg.getMaxWaitMillis(),cfg.getQueryTimeout(),cfg.getConfigurationUIDs(),cfg.getPersistence()));
			break;

			case MSSQL:
