/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */

package org.apache.openaz.xacml.admin.view.components;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Set;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.openaz.xacml.admin.jpa.PIPConfigParam;
import org.apache.openaz.xacml.admin.jpa.PIPConfiguration;
import org.apache.openaz.xacml.admin.view.events.FormChangedEventListener;
import org.apache.openaz.xacml.admin.view.events.FormChangedEventNotifier;
import com.vaadin.addon.jpacontainer.EntityItem;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Buffered.SourceException;
import com.vaadin.data.Item;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.server.Page;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;
import com.vaadin.ui.PasswordField;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

public class SQLPIPConfigurationComponent extends CustomComponent implements FormChangedEventNotifier {
	
	@AutoGenerated
	private VerticalLayout mainLayout;

	@AutoGenerated
	private Button buttonTest;

	@AutoGenerated
	private PasswordField textFieldPassword;

	@AutoGenerated
	private TextField textFieldUser;

	@AutoGenerated
	private TextField textFieldConnectionURL;

	@AutoGenerated
	private ComboBox comboBoxSQLDriver;

	@AutoGenerated
	private TextField textFieldDataSource;

	@AutoGenerated
	private ComboBox comboBoxConnectionType;

	public static final String	CLASSNAME = "org.apache.openaz.xacml.std.pip.engines.jdbc.JDBCEngine";
	
	public static final String	SQL_TYPE = "type";
	public static final String	SQL_TYPE_JDBC = "jdbc";
	public static final String	SQL_TYPE_JNDI = "jndi";
	public static final String	SQL_DATASOURCE = "datasource";
	public static final String	SQL_DRIVER = "jdbc.driver";
	public static final String	SQL_URL = "jdbc.url";
	public static final String	SQL_USER = "jdbc.conn.user";
	public static final String	SQL_PASSWORD = "jdbc.conn.password";
	
	//
	// These are the drivers that we are initially supporting and testing.
	// Other JDBC drivers may work fine, but we will wait until we test
	// with those drivers before adding them to this list.
	//
	public static final String	SQL_DRIVER_MYSQL = "com.mysql.jdbc.Driver";
	public static final String	SQL_DRIVER_POSTGRESQL = "org.postgresql.Driver";
	public static final String	SQL_DRIVER_H2 = "org.h2.Driver";
	public static final String	SQL_DRIVER_HYPER = "org.hsqldb.jdbc.JDBCDriver";
	public static final String	SQL_DRIVER_SQL_SERVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
	public static String[]	SQL_DRIVERS = new String[] {SQL_DRIVER_MYSQL, SQL_DRIVER_POSTGRESQL, SQL_DRIVER_H2, SQL_DRIVER_HYPER, SQL_DRIVER_SQL_SERVER};

	public static final String	SQL_DRIVER_MYSQL_URL = "jdbc:mysql://localhost:3306/";
	public static final String	SQL_DRIVER_POSTGRESQL_URL = "jdbc:postgresql://localhost:5432/";
	public static final String	SQL_DRIVER_H2_URL = "jdbc:h2:file:/";
	public static final String	SQL_DRIVER_HYPER_URL = "jdbc:hsqldb:file:/";
	public static final String	SQL_DRIVER_SQL_SERVER_URL = "jdbc:sqlserver://localhost:1433/";

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final Log logger	= LogFactory.getLog(SQLPIPConfigurationComponent.class);

	private final SQLPIPConfigurationComponent self = this;
	private final BasicNotifier notifier = new BasicNotifier();
	private final EntityItem<PIPConfiguration> entity;
	/**
	 * The constructor should first build the main layout, set the
	 * composition root and then do any custom initialization.
	 *
	 * The constructor will not be automatically regenerated by the
	 * visual editor.
	 * @param configParamField 
	 */
	public SQLPIPConfigurationComponent(EntityItem<PIPConfiguration> entity) {
		buildMainLayout();
		setCompositionRoot(mainLayout);
		//
		// Save
		//
		this.entity = entity;
		//
		// Initialize
		//
		this.initialize();
		//
		// Finish 
		//
		this.reset();
	}
	
	protected void initialize() {
		if (logger.isDebugEnabled()) {
			logger.debug("initializing " + this.entity.getEntity().toString());
		}
		//
		// Iterate any existing values, save them in the data field for each
		// GUI object.
		//
		Set<PIPConfigParam> unneeded = new HashSet<PIPConfigParam>();
		for (PIPConfigParam param : this.entity.getEntity().getPipconfigParams()) {
			//
			// Sanity check
			//
			if (param.getParamName() == null) {
				logger.warn("Null parameter name found.");
				unneeded.add(param);
				continue;
			}
			if (param.getParamName().equals(SQL_TYPE)) {
				this.comboBoxConnectionType.setData(param);
			} else if (param.getParamName().equals(SQL_DATASOURCE)) {
				this.textFieldDataSource.setData(param);
			} else if (param.getParamName().equals(SQL_DRIVER)) {
				this.comboBoxSQLDriver.setData(param);
			} else if (param.getParamName().equals(SQL_URL)) {
				this.textFieldConnectionURL.setData(param);
			} else if (param.getParamName().equals(SQL_USER)) {
				this.textFieldUser.setData(param);
			} else if (param.getParamName().equals(SQL_PASSWORD)) {
				this.textFieldPassword.setData(param);
			} else {
				unneeded.add(param);
			}
		}
		//
		// Get rid of parameters that are not needed
		//
		if (unneeded.isEmpty() == false) {
			this.entity.getEntity().getPipconfigParams().removeAll(unneeded);
		}
		//
		// Now finish initializing the GUI objects
		//
		this.initializeEntity();
		this.initializeTypeCombo();
		this.initializeSQLDriverCombo();
		this.initializeText();
		this.initializeButtons();
	}
	
	protected void initializeEntity() {
		//
		// Initialize the entity
		//
		this.entity.getEntity().setClassname(CLASSNAME);
		this.entity.getEntity().setRequiresResolvers(true);
	}
	
	protected void initializeTypeCombo() {
		//
		// Setup GUI properties
		//
		this.comboBoxConnectionType.setImmediate(true);
		this.comboBoxConnectionType.setNullSelectionAllowed(false);
		this.comboBoxConnectionType.setRequired(true);
		this.comboBoxConnectionType.setRequiredError("You must select a connection type.");
		//
		// Add the possible items
		//
		this.comboBoxConnectionType.addItem(SQL_TYPE_JDBC);
		this.comboBoxConnectionType.addItem(SQL_TYPE_JNDI);
		//
		// Respond to events
		//
		this.comboBoxConnectionType.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				PIPConfigParam param = (PIPConfigParam) self.comboBoxConnectionType.getData();
				if (param == null) {
					param = new PIPConfigParam(SQL_TYPE);
					self.entity.getEntity().addPipconfigParam(param);
					self.comboBoxConnectionType.setData(param);
				}
				param.setParamValue(self.comboBoxConnectionType.getValue().toString());
				self.reset();
				self.fireFormChangedEvent();
			}
		});
		//
		// Set its default selection. If there isn't one, then we default to JDBC.
		//
		PIPConfigParam param = (PIPConfigParam) this.comboBoxConnectionType.getData();
		if (param == null) {
			param = new PIPConfigParam(SQL_TYPE, SQL_TYPE_JDBC);
			this.entity.getEntity().addPipconfigParam(param);
			this.comboBoxConnectionType.setData(param);
		}
		this.comboBoxConnectionType.select(param.getParamValue());
	}
	
	protected void initializeSQLDriverCombo() {
		//
		// GUI properties
		//
		this.comboBoxSQLDriver.setImmediate(true);
		this.comboBoxSQLDriver.setRequired(true);
		this.comboBoxConnectionType.setRequiredError("You must select a JDBC Driver");
		this.comboBoxSQLDriver.setInputPrompt("Eg. com.mysql.jdbc.Driver");
		//
		// Add some common driver values. These are the drivers we have tested with so far.
		//
		for (String driver : SQL_DRIVERS) {
			this.comboBoxSQLDriver.addItem(driver);
		}
		//
		// Setup the default selection
		//
		PIPConfigParam param = (PIPConfigParam) this.comboBoxSQLDriver.getData();
		if (param != null) {
			this.comboBoxSQLDriver.setValue(param.getParamValue());
			//
			// Check if its there (the value could be something other than what we
			// have setup in our list of defaults.)
			//
			boolean bFound = false;
			for (Object id : this.comboBoxSQLDriver.getItemIds()) {
				Item item = this.comboBoxSQLDriver.getItem(id);
				if (item.toString().equals(param.getParamValue())) {
					bFound = true;
					break;
				}
			}
			if (! bFound) {
				//
				// It's not one of our defaults, no problem. Add it in.
				//
				this.comboBoxSQLDriver.addItem(param.getParamValue());
				this.comboBoxSQLDriver.setValue(param.getParamValue());
			}
		}
		//
		// Allow new items
		//
		this.comboBoxSQLDriver.setNewItemsAllowed(true);
		//
		// Respond to selection changes
		//
		this.comboBoxSQLDriver.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				PIPConfigParam param = (PIPConfigParam) self.comboBoxSQLDriver.getData();
				if (param == null) {
					param = new PIPConfigParam(SQL_DRIVER, self.comboBoxSQLDriver.getValue().toString());
					self.entity.getEntity().addPipconfigParam(param);
					self.comboBoxSQLDriver.setData(param);
				}
				//
				// Was something unselected?
				//
				if (self.comboBoxSQLDriver.getValue() == null) {
					param.setParamValue(null);
				} else {
					param.setParamValue(self.comboBoxSQLDriver.getValue().toString());
					//
					// See if we should pre-populate the driver URL
					//
					self.setupDriverURL(self.comboBoxSQLDriver.getValue().toString());
				}
				//
				// Fire
				//
				self.fireFormChangedEvent();
			}
		});
	}
	
	protected void initializeText() {
		//
		// GUI properties
		//
		this.textFieldDataSource.setImmediate(true);
		this.textFieldDataSource.setNullRepresentation("");
		this.textFieldDataSource.setRequired(true);
		this.textFieldDataSource.setRequiredError("The name of the JNDI Resource is needed.");
		//
		// Get its initial value
		//
		PIPConfigParam param = (PIPConfigParam) this.textFieldDataSource.getData();
		if (param != null) {
			this.textFieldDataSource.setValue(param.getParamValue());
		}
		//
		// Respond to value changes
		//
		this.textFieldDataSource.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				PIPConfigParam param = (PIPConfigParam) self.textFieldDataSource.getData();
				if (param == null) {
					param = new PIPConfigParam(SQL_DATASOURCE, self.textFieldDataSource.getValue());
					self.entity.getEntity().addPipconfigParam(param);
					self.textFieldDataSource.setData(param);
				}
				param.setParamValue(self.textFieldDataSource.getValue());
				self.fireFormChangedEvent();
			}
		});
		//
		// Setup GUI properties
		//
		this.textFieldConnectionURL.setImmediate(true);
		this.textFieldConnectionURL.setNullRepresentation("");
		this.textFieldConnectionURL.setRequired(true);
		this.textFieldConnectionURL.setRequiredError("A URL is needed to connect to the database.");
		//
		// Set its default value
		//
		param = (PIPConfigParam) this.textFieldConnectionURL.getData();
		if (param != null) {
			this.textFieldConnectionURL.setValue(param.getParamValue());
		}
		//
		// Respond to value changes
		//
		this.textFieldConnectionURL.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				PIPConfigParam param = (PIPConfigParam) self.textFieldConnectionURL.getData();
				if (param == null) {
					param = new PIPConfigParam(SQL_URL);
					self.entity.getEntity().addPipconfigParam(param);
					self.textFieldConnectionURL.setData(param);
				}
				param.setParamValue(self.textFieldConnectionURL.getValue());
				self.fireFormChangedEvent();
			}
		});
		//
		// Set GUI properties
		//
		this.textFieldUser.setImmediate(true);
		this.textFieldUser.setNullRepresentation("");
		this.textFieldUser.setRequired(true);
		this.textFieldUser.setRequiredError("User name is required.");
		//
		// Setup its default value
		//
		param = (PIPConfigParam) self.textFieldUser.getData();
		if (param != null) {
			this.textFieldUser.setValue(param.getParamValue());
		}
		//
		// Respond to value changes
		//
		this.textFieldUser.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				PIPConfigParam param = (PIPConfigParam) self.textFieldUser.getData();
				if (param == null) {
					param = new PIPConfigParam(SQL_USER);
					self.entity.getEntity().addPipconfigParam(param);
					self.textFieldUser.setData(param);
				}
				param.setParamValue(self.textFieldUser.getValue());
				self.fireFormChangedEvent();
			}
		});
		//
		// Initialize GUI properties
		//
		this.textFieldPassword.setImmediate(true);
		this.textFieldPassword.setNullRepresentation("");
		//
		// Set its default value
		//
		param = (PIPConfigParam) self.textFieldPassword.getData();
		if (param != null) {
			this.textFieldPassword.setValue(param.getParamValue());
		}
		//
		// Respond to value change events
		//
		this.textFieldPassword.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				PIPConfigParam param = (PIPConfigParam) self.textFieldPassword.getData();
				if (param == null) {
					param = new PIPConfigParam(SQL_PASSWORD);
					self.entity.getEntity().addPipconfigParam(param);
					self.textFieldPassword.setData(param);
				}
				param.setParamValue(self.textFieldPassword.getValue());
				self.fireFormChangedEvent();
			}			
		});
	}
	
	protected void initializeButtons() {
		this.buttonTest.setImmediate(true);
		this.buttonTest.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				Object id = self.comboBoxConnectionType.getValue();
				if (id == null) {
					logger.warn("No combo box selection");
					return;
				}				
				if (id.toString().equals(SQL_TYPE_JDBC)) {
					self.testJDBCConnection();
				} else if (id.toString().equals(SQL_TYPE_JNDI)) {
					self.testJNDIConnection();
				}
			}			
		});
	}
	
	protected void setupDriverURL(String value) {
		if (value.equals(SQL_DRIVER_MYSQL)) {
			this.textFieldConnectionURL.setValue(SQL_DRIVER_MYSQL_URL);
		} else if (value.equals(SQL_DRIVER_POSTGRESQL)) {
			this.textFieldConnectionURL.setValue(SQL_DRIVER_POSTGRESQL_URL);
		} else if (value.equals(SQL_DRIVER_H2)) {
			this.textFieldConnectionURL.setValue(SQL_DRIVER_H2_URL);
		} else if (value.equals(SQL_DRIVER_HYPER)) {
			this.textFieldConnectionURL.setValue(SQL_DRIVER_HYPER_URL);
		} else if (value.equals(SQL_DRIVER_SQL_SERVER)) {
			this.textFieldConnectionURL.setValue(SQL_DRIVER_SQL_SERVER_URL);
		}
	}
	
	protected void testJNDIConnection() {
		try {
			Context initialContext = new InitialContext();
			DataSource dataSource = (DataSource) initialContext.lookup(this.textFieldDataSource.getValue());
			try (Connection connection = dataSource.getConnection()) {
				new Notification("Success!",
					    "Connection Established!",
					    Type.HUMANIZED_MESSAGE, true)
					    .show(Page.getCurrent());			
			}
		} catch (NamingException e) {
			logger.error(e);
			new Notification("JNDI Naming Exception",
				    "<br/>" + e.getLocalizedMessage() + "<br/>Is the context defined in this J2EE Container instance?",
				    Type.ERROR_MESSAGE, true)
				    .show(Page.getCurrent());
		} catch (SQLException e) {
			logger.error(e);
			new Notification("SQL Exception",
				    "<br/>" + e.getLocalizedMessage() + "<br/>Are the configuration parameters correct?",
				    Type.ERROR_MESSAGE, true)
				    .show(Page.getCurrent());
		}
	}

	protected void testJDBCConnection() {
		try {
			if (this.comboBoxSQLDriver.getValue() != null) {
				Class.forName(this.comboBoxSQLDriver.getValue().toString());
			} else {
				throw new ClassNotFoundException("Please select a JDBC driver to load.");
			}
		} catch (ClassNotFoundException e) {
			logger.error(e);
			new Notification("Driver Exception",
				    "<br/>" + e.getLocalizedMessage() + "<br/>Is the JDBC driver's jar in the J2EE container path?",
				    Type.ERROR_MESSAGE, true)
				    .show(Page.getCurrent());
			return;
		}
		Connection connection = null;
		try {
			connection = DriverManager.getConnection(this.textFieldConnectionURL.getValue(), this.textFieldUser.getValue(), this.textFieldPassword.getValue());
			new Notification("Success!",
				    "Connection Established!",
				    Type.HUMANIZED_MESSAGE, true)
				    .show(Page.getCurrent());
		} catch (SQLException e) {
			logger.error(e);
			new Notification("SQL Exception",
				    "<br/>" + e.getLocalizedMessage() + "<br/>Are the configuration parameters correct?",
				    Type.ERROR_MESSAGE, true)
				    .show(Page.getCurrent());
		} finally {
			if (connection != null) {
				try {
					connection.close();
				} catch (SQLException idontcare) { //NOPMD
				}
			}
		}
	}

	protected void reset() {
		Object id = this.comboBoxConnectionType.getValue();
		if (id == null) {
			logger.warn("Can't reset combo hasn't selected anything.");
			return;
		}
		if (id.toString().equals(SQL_TYPE_JDBC)) {
			//
			//
			//
			this.textFieldDataSource.setVisible(false);
			this.textFieldDataSource.setRequired(false);
			//
			//
			//
			this.textFieldConnectionURL.setVisible(true);
			this.textFieldConnectionURL.setRequired(true);
			this.comboBoxSQLDriver.setVisible(true);
			this.comboBoxSQLDriver.setRequired(true);
			this.textFieldUser.setVisible(true);
			this.textFieldUser.setRequired(true);
			this.textFieldPassword.setVisible(true);
		} else if (id.toString().equals(SQL_TYPE_JNDI)) {
			//
			//
			//
			this.textFieldDataSource.setVisible(true);
			this.textFieldDataSource.setRequired(true);
			//
			//
			//
			this.textFieldConnectionURL.setVisible(false);
			this.textFieldConnectionURL.setRequired(false);
			this.comboBoxSQLDriver.setVisible(false);
			this.comboBoxSQLDriver.setRequired(false);
			this.textFieldUser.setVisible(false);
			this.textFieldUser.setRequired(false);
			this.textFieldPassword.setVisible(false);
		} else {
			logger.warn("Unknown SQL type selection: " + id);
		}
	}
	
	public void validate() throws InvalidValueException {
		if (logger.isDebugEnabled()) {
			logger.debug("validate");
		}
		this.comboBoxConnectionType.validate();
		this.textFieldDataSource.validate();
		this.textFieldConnectionURL.validate();
		this.comboBoxSQLDriver.validate();
		this.textFieldPassword.validate();
		this.textFieldUser.validate();
	}
	
	public void commit()  throws SourceException, InvalidValueException {
		if (logger.isDebugEnabled()) {
			logger.debug("commit");
		}
		this.comboBoxConnectionType.commit();
		
		Object id = this.comboBoxConnectionType.getValue();
		if (id == null) {
			logger.warn("Can't reset combo hasn't selected anything.");
			return;
		}
		if (id.toString().equals(SQL_TYPE_JDBC)) {
			this.textFieldConnectionURL.commit();
			this.comboBoxSQLDriver.commit();
			this.textFieldPassword.commit();
			this.textFieldUser.commit();
			
			this.textFieldDataSource.setData(null);
			this.entity.getEntity().getPipconfigParams().remove(SQL_DATASOURCE);

		} else if (id.toString().equals(SQL_TYPE_JNDI)) {

			this.textFieldDataSource.commit();

			this.textFieldConnectionURL.setData(null);
			this.comboBoxSQLDriver.setData(null);
			this.textFieldPassword.setData(null);
			this.textFieldUser.setData(null);
			/* ???
			this.entity.getEntity().getPipconfigParams().remove(SQL_TYPE);
			this.entity.getEntity().getPipconfigParams().remove(SQL_DRIVER);
			this.entity.getEntity().getPipconfigParams().remove(SQL_URL);
			this.entity.getEntity().getPipconfigParams().remove(SQL_USER);
			this.entity.getEntity().getPipconfigParams().remove(SQL_PASSWORD);
			*/
		}
	}
	
	public void discard() throws SourceException {
		if (logger.isDebugEnabled()) {
			logger.debug("discard");
		}
		this.textFieldDataSource.setData(null);
		this.textFieldConnectionURL.setData(null);
		this.comboBoxSQLDriver.setData(null);
		this.textFieldPassword.setData(null);
		this.textFieldUser.setData(null);

		this.entity.getEntity().getPipconfigParams().remove(SQL_TYPE);
		this.entity.getEntity().getPipconfigParams().remove(SQL_DATASOURCE);
		this.entity.getEntity().getPipconfigParams().remove(SQL_DRIVER);
		this.entity.getEntity().getPipconfigParams().remove(SQL_URL);
		this.entity.getEntity().getPipconfigParams().remove(SQL_USER);
		this.entity.getEntity().getPipconfigParams().remove(SQL_PASSWORD);
	}

	@Override
	public boolean addListener(FormChangedEventListener listener) {
		return this.notifier.addListener(listener);
	}

	@Override
	public boolean removeListener(FormChangedEventListener listener) {
		return this.notifier.removeListener(listener);
	}

	@Override
	public void fireFormChangedEvent() {
		this.notifier.fireFormChangedEvent();
	}
	
	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("-1px");
		mainLayout.setHeight("-1px");
		mainLayout.setMargin(false);
		mainLayout.setSpacing(true);
		
		// top-level component properties
		setWidth("-1px");
		setHeight("-1px");
		
		// comboBoxConnectionType
		comboBoxConnectionType = new ComboBox();
		comboBoxConnectionType.setCaption("Type of SQL Connection");
		comboBoxConnectionType.setImmediate(false);
		comboBoxConnectionType.setWidth("-1px");
		comboBoxConnectionType.setHeight("-1px");
		mainLayout.addComponent(comboBoxConnectionType);
		
		// textFieldDataSource
		textFieldDataSource = new TextField();
		textFieldDataSource.setCaption("Data Source");
		textFieldDataSource.setImmediate(false);
		textFieldDataSource.setWidth("-1px");
		textFieldDataSource.setHeight("-1px");
		mainLayout.addComponent(textFieldDataSource);
		mainLayout.setExpandRatio(textFieldDataSource, 1.0f);
		
		// comboBoxSQLDriver
		comboBoxSQLDriver = new ComboBox();
		comboBoxSQLDriver.setCaption("JDBC Driver");
		comboBoxSQLDriver.setImmediate(false);
		comboBoxSQLDriver.setWidth("-1px");
		comboBoxSQLDriver.setHeight("-1px");
		mainLayout.addComponent(comboBoxSQLDriver);
		mainLayout.setExpandRatio(comboBoxSQLDriver, 1.0f);
		
		// textFieldConnectionURL
		textFieldConnectionURL = new TextField();
		textFieldConnectionURL.setCaption("Connection URL");
		textFieldConnectionURL.setImmediate(false);
		textFieldConnectionURL.setWidth("-1px");
		textFieldConnectionURL.setHeight("-1px");
		mainLayout.addComponent(textFieldConnectionURL);
		mainLayout.setExpandRatio(textFieldConnectionURL, 1.0f);
		
		// textFieldUser
		textFieldUser = new TextField();
		textFieldUser.setCaption("User");
		textFieldUser.setImmediate(false);
		textFieldUser.setWidth("-1px");
		textFieldUser.setHeight("-1px");
		mainLayout.addComponent(textFieldUser);
		mainLayout.setExpandRatio(textFieldUser, 1.0f);
		
		// textFieldPassword
		textFieldPassword = new PasswordField();
		textFieldPassword.setCaption("Password");
		textFieldPassword.setImmediate(false);
		textFieldPassword.setWidth("-1px");
		textFieldPassword.setHeight("-1px");
		mainLayout.addComponent(textFieldPassword);
		mainLayout.setExpandRatio(textFieldPassword, 1.0f);
		
		// buttonTest
		buttonTest = new Button();
		buttonTest.setCaption("Test Connection");
		buttonTest.setImmediate(true);
		buttonTest.setWidth("-1px");
		buttonTest.setHeight("-1px");
		mainLayout.addComponent(buttonTest);
		mainLayout.setComponentAlignment(buttonTest, new Alignment(48));
		
		return mainLayout;
	}
}
