package com.revolsys.swing.map.form; import java.awt.event.ItemEvent; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import javax.swing.BorderFactory; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import org.jdesktop.swingx.VerticalLayout; import com.revolsys.awt.WebColors; import com.revolsys.collection.list.Lists; import com.revolsys.collection.map.LinkedHashMapEx; import com.revolsys.collection.map.MapEx; import com.revolsys.collection.map.Maps; import com.revolsys.datatype.DataTypes; import com.revolsys.io.IoFactory; import com.revolsys.jdbc.exception.DatabaseNotFoundException; import com.revolsys.jdbc.io.JdbcDatabaseFactory; import com.revolsys.record.io.AbstractRecordIoFactory; import com.revolsys.record.io.FileRecordStoreFactory; import com.revolsys.record.io.RecordStoreConnection; import com.revolsys.record.io.RecordStoreConnectionRegistry; import com.revolsys.record.io.RecordStoreFactory; import com.revolsys.swing.component.Form; import com.revolsys.swing.field.CheckBox; import com.revolsys.swing.field.ComboBox; import com.revolsys.swing.field.FileField; import com.revolsys.swing.field.NumberTextField; import com.revolsys.swing.field.PasswordField; import com.revolsys.swing.field.TextField; import com.revolsys.util.PasswordUtil; import com.revolsys.util.Property; import com.revolsys.util.Strings; public final class RecordStoreConnectionForm extends Form { private static final List<String> CONNECTION_FIELD_NAMES = Arrays.asList("url", "user", "password"); private static final long serialVersionUID = 2750736040832727823L; private final List<String> recordStoreTypes; private final Map<String, RecordStoreFactory> recordStoreFactoryByName = new TreeMap<>(); private final RecordStoreConnection connection; private final RecordStoreConnectionRegistry registry; private MapEx config; public RecordStoreConnectionForm(final RecordStoreConnectionRegistry registry) { this(registry, (RecordStoreConnection)null); } public RecordStoreConnectionForm(final RecordStoreConnectionRegistry registry, final RecordStoreConnection connection) { this(registry, connection, null); } @SuppressWarnings("unchecked") public RecordStoreConnectionForm(final RecordStoreConnectionRegistry registry, final RecordStoreConnection connection, Throwable exception) { super(new VerticalLayout()); this.registry = registry; this.connection = connection; final Map<String, String> allConnectionUrlMap = new TreeMap<>(); for (final RecordStoreFactory recordStoreFactory : IoFactory .factories(RecordStoreFactory.class)) { if (recordStoreFactory instanceof AbstractRecordIoFactory) { // Ignore these for now } else { final String name = recordStoreFactory.getName(); this.recordStoreFactoryByName.put(name, recordStoreFactory); if (recordStoreFactory instanceof JdbcDatabaseFactory) { final JdbcDatabaseFactory databaseFactory = (JdbcDatabaseFactory)recordStoreFactory; final Map<String, String> connectionUrlMap = databaseFactory.getConnectionUrlMap(); allConnectionUrlMap.putAll(connectionUrlMap); } } } this.recordStoreTypes = Lists.toArray(this.recordStoreFactoryByName.keySet()); if (exception != null) { if (exception instanceof DatabaseNotFoundException) { final DatabaseNotFoundException databaseException = (DatabaseNotFoundException)exception; exception = databaseException.getCause(); } final JOptionPane errorPane = new JOptionPane(exception.getMessage(), JOptionPane.ERROR_MESSAGE, JOptionPane.DEFAULT_OPTION, null, new Object[] {}, null); errorPane.setBorder(BorderFactory.createLineBorder(WebColors.LightCoral, 2)); add(errorPane); } addNewPanelTitledLabelledFields( // "General", // new TextField("name", 50), // new TextField("url", 50), // ComboBox.newComboBox("recordStoreType", this.recordStoreTypes) // ); if (Property.hasValue(allConnectionUrlMap)) { final List<String> connectionNames = new ArrayList<>(); connectionNames.add(null); connectionNames.addAll(allConnectionUrlMap.keySet()); final ComboBox<String> connectionNamesField = ComboBox.newComboBox("namedConnection", connectionNames); connectionNamesField.addItemListener((e) -> { if (e.getStateChange() == ItemEvent.SELECTED) { final String connectionName = (String)e.getItem(); if (connectionName != null) { final String url = allConnectionUrlMap.get(connectionName); setFieldValue("url", url); } } }); addNewPanelTitledLabelledFields( // "Named Connections", // connectionNamesField // ); } addNewPanelTitledLabelledFields( // "File Connection", // new FileField("file", JFileChooser.FILES_AND_DIRECTORIES) // ); addNewPanelTitledLabelledFields( // "JDBC Connection", // new TextField("host", 40), // new NumberTextField("port", DataTypes.INT, 1, 65535), // new TextField("database", 30), // new TextField("user", 30), // new PasswordField("password", 30), // new CheckBox("savePassword") // ); if (connection == null) { this.config = new LinkedHashMapEx(); setTitle("Add Record Store Connection"); } else { final String name = connection.getName(); setTitle("Edit Record Store Connection " + name); setFieldValue("name", name); final boolean savePassword = connection.isSavePassword(); setFieldValue("savePassword", savePassword); this.config = connection.getProperties(); final Map<String, String> connectionParameters = (Map<String, String>)this.config .get("connection"); for (final String fieldName : CONNECTION_FIELD_NAMES) { Object fieldValue = connectionParameters.get(fieldName); if (Property.hasValue(fieldValue)) { if ("password".equals(fieldName) && fieldValue instanceof String) { fieldValue = PasswordUtil.decrypt((String)fieldValue); } setFieldValue(fieldName, fieldValue); } } } } public RecordStoreConnectionForm(final RecordStoreConnectionRegistry registry, final String name) { this(registry); setTitle(getTitle() + " " + name); setFieldValue("name", name); } @Override protected void postSetFieldValues(final Map<String, Object> newValues) { String recordStoreType = (String)newValues.get("recordStoreType"); if (Property.hasValue(recordStoreType)) { if (this.recordStoreTypes.contains(recordStoreType)) { refreshUrlFromFieldValues(recordStoreType); } return; } final String url = (String)newValues.get("url"); if (Property.hasValue(url)) { for (final RecordStoreFactory recordStoreFactory : this.recordStoreFactoryByName.values()) { final Map<String, Object> urlFieldValues = recordStoreFactory.parseUrl(url); if (!urlFieldValues.isEmpty()) { Maps.retainIfNotEqual(urlFieldValues, newValues); if (recordStoreFactory instanceof FileRecordStoreFactory) { final FileRecordStoreFactory fileRecordStoreFactory = (FileRecordStoreFactory)recordStoreFactory; final FileField fileField = getField("file"); if (fileRecordStoreFactory.isDirectory()) { fileField.setFileSelectionMode(JFileChooser.FILES_ONLY); } else { fileField.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); } } setFieldValues(urlFieldValues); return; } } } recordStoreType = getFieldValue("recordStoreType"); refreshUrlFromFieldValues(recordStoreType); } private void refreshUrlFromFieldValues(final String recordStoreType) { if (recordStoreType != null) { final RecordStoreFactory databaseFactory = this.recordStoreFactoryByName.get(recordStoreType); if (databaseFactory != null) { final Map<String, Object> fieldValues = getFieldValues(); final String newUrl = databaseFactory.toUrl(fieldValues); if (Property.hasValue(newUrl)) { setFieldValue("url", newUrl); return; } } } } @Override public void save() { super.save(); final String name = getFieldValue("name"); this.config.put("name", name); final Map<String, Object> connectionParameters = new LinkedHashMap<>(); this.config.put("connection", connectionParameters); this.config.put("savePassword", getFieldValue("savePassword")); for (final String fieldName : CONNECTION_FIELD_NAMES) { Object fieldValue = getFieldValue(fieldName); if ("password".equals(fieldName) && fieldValue instanceof String) { fieldValue = PasswordUtil.encrypt((String)fieldValue); } connectionParameters.put(fieldName, fieldValue); } if (this.connection == null) { this.registry.newConnection(this.config); } else { final String oldName = this.connection.getName(); if (Strings.equals(oldName, name)) { this.connection.setProperties(this.config); } else { this.registry.removeConnection(this.connection); this.registry.newConnection(this.config); } } this.registry.save(); } }