package com.vividsolutions.jump.workbench.ui.plugin.datastore;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.filechooser.FileFilter;
import com.vividsolutions.jump.I18N;
import com.vividsolutions.jump.datastore.DataStoreDriver;
import com.vividsolutions.jump.parameter.ParameterList;
import com.vividsolutions.jump.parameter.ParameterListSchema;
import com.vividsolutions.jump.util.Blackboard;
import com.vividsolutions.jump.util.CollectionUtil;
import com.vividsolutions.jump.workbench.WorkbenchContext;
import com.vividsolutions.jump.workbench.datasource.LoadFileDataSourceQueryChooser;
import com.vividsolutions.jump.workbench.datastore.ConnectionDescriptor;
import com.vividsolutions.jump.workbench.registry.Registry;
import com.vividsolutions.jump.workbench.ui.ValidatingTextField;
import com.vividsolutions.jump.workbench.ui.plugin.PersistentBlackboardPlugIn;
public class ConnectionDescriptorPanel extends JPanel
{
private WorkbenchContext context;
private ParameterListSchema schema = new ParameterListSchema(
new String[] {}, new Class[] {});
private static int createdConnectionCount = 0;
private JTextField nameText = new JTextField();
private JComboBox driverComboBox = null;
private List editComponentList = new ArrayList();
private void updateMainPanel(ParameterList parameterList,Blackboard bb) {
mainPanel.removeAll();
editComponentList.clear();
addEditComponent(0, I18N.get("jump.workbench.ui.plugin.datastore.ConnectionDescriptorPanel.Name"), nameText);
addEditComponent(1, I18N.get("jump.workbench.ui.plugin.datastore.ConnectionDescriptorPanel.Driver"), driverComboBox);
for (int i = 0; i < schema.getNames().length; i++) {
String name = schema.getNames()[i];
editComponentList.add(createEditComponent(name,
schema.getClasses()[i], parameterList.getParameter(name),bb));
addEditComponent(i + 2, name, (Component) editComponentList
.get(editComponentList.size() - 1));
}
revalidate();
repaint();
}
private void addEditComponent(int i, String name, Component editComponent) {
mainPanel.add(new JLabel(name), new GridBagConstraints(0, i, 1, 1, 0,
0, GridBagConstraints.WEST, GridBagConstraints.NONE,
new Insets(2, 2, 2, 2), 0, 0));
mainPanel.add(editComponent, new GridBagConstraints(1, i, 1, 1, 0, 0,
GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2,
2, 2, 2), 0, 0));
}
private Component createEditComponent(String name, Class parameterClass,
Object parameter, Blackboard bb) {
Component editComponent = parameterClassHandler(name, parameterClass).createEditComponent(bb);
if (parameter != null) {
parameterClassHandler(name, parameterClass).setParameter(
editComponent, parameter);
}
return editComponent;
}
private ParameterClassHandler parameterClassHandler(String name,
Class parameterClass) {
if (name.equalsIgnoreCase("Password")) {
return PASSWORD_HANDLER;
}
return (ParameterClassHandler) parameterClassToHandlerMap
.get(parameterClass);
}
private interface ParameterClassHandler {
Component createEditComponent(Blackboard bb);
void setParameter(Component component, Object parameter);
Object getParameter(Component component);
}
private static final ParameterClassHandler PASSWORD_HANDLER = new ParameterClassHandler() {
public Component createEditComponent(Blackboard bb) {
return new JPasswordField(20);
}
public void setParameter(Component component, Object parameter) {
((JPasswordField) component).setText((String) parameter);
}
public Object getParameter(Component component) {
// The JavaDoc is not clear about *how* #getPassword is any more
// secure than #getText [Jon Aquino 2005-03-07]
return new String(((JPasswordField) component).getPassword());
}
};
private static class JMPFileChooser extends JPanel{
Blackboard bb;
JFileChooser chooser;
File f = null;
public JMPFileChooser(Blackboard bb){
this.bb = bb;
chooser = new JFileChooser();
final JMPFileChooser th = this;
final JTextField strFile = new JTextField(20);
JButton open = new JButton();
open.setText("...");
open.setMargin(new Insets(0, 0, 0, 0));
strFile.addFocusListener(new FocusListener(){
public void focusGained(FocusEvent e) {
// do nothing
}
public void focusLost(FocusEvent e) {
// check for a new value ...
String t = strFile.getText();
if(t == null){
th.f = null;
return;
}
t = t.trim();
if(t == null || "".equals(t)){
th.f = null;
return;
}
th.f = new File(t);
}
});
open.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
if(f!=null){
chooser.setSelectedFile(f);
th.setToolTipText(f.toString());
}
int selection = chooser.showOpenDialog(th);
if(selection == JFileChooser.APPROVE_OPTION ){
th.f = chooser.getSelectedFile();
if(th.f == null){
strFile.setText("");
}else{
strFile.setText(th.f.toString());
}
}
}
});
setBorder(BorderFactory.createLineBorder(getBackground(),0));
GridBagLayout gl = new GridBagLayout();
setLayout(gl);
setAlignmentX(0);
GridBagConstraints c = new GridBagConstraints(0, 0, 1, 1, 0,
0, GridBagConstraints.WEST, GridBagConstraints.NONE,
new Insets(0, 0, 0, 0), 0, 0);
add(strFile, c);
gl.setConstraints(strFile,c);
c = new GridBagConstraints(1, 0, 1, 1, 0,
0, GridBagConstraints.WEST, GridBagConstraints.NONE,
new Insets(2, 2, 2, 2), 0, 0);
add(open, c);
gl.setConstraints(open,c);
}
}
private Map parameterClassToHandlerMap = CollectionUtil
.createMap(new Object[] { String.class,
new ParameterClassHandler() {
public Component createEditComponent(Blackboard bb) {
return new JTextField(20);
}
public void setParameter(Component component,
Object parameter) {
((JTextField) component)
.setText((String) parameter);
}
public Object getParameter(Component component) {
return ((JTextField) component).getText();
}
}, File.class,
new ParameterClassHandler() {
public Component createEditComponent(Blackboard bb) {
JMPFileChooser fileChooser = new JMPFileChooser(bb);
if (bb.get(LoadFileDataSourceQueryChooser.FILE_CHOOSER_DIRECTORY_KEY) != null) {
fileChooser.f = new File(
(String) bb.get(LoadFileDataSourceQueryChooser.FILE_CHOOSER_DIRECTORY_KEY));
}
return fileChooser;
}
public void setParameter(Component component,
Object parameter) {
if(parameter!=null){
File f = (File)parameter;
((JMPFileChooser)component).f = f;
if(f!= null && f.getParent()!=null){
((JMPFileChooser)component).bb.put(LoadFileDataSourceQueryChooser.FILE_CHOOSER_DIRECTORY_KEY,f.getParent());
if(f.isFile()){
int index = f.getName().lastIndexOf('.')+1;
if(index > -1){
final String suffix = f.getName().substring(index);
if(suffix != null && !"".equals(suffix.trim()))
((JMPFileChooser)component).chooser.setFileFilter(new FileFilter(){
public boolean accept(File f) {
return f!=null && (f.isDirectory() || (f.isFile() && f.getName().endsWith(suffix)));
}
public String getDescription() {
return "";
}
});
}
}
}
}
((JTextField) component).setText(parameter==null?"":((File) parameter).toString());
}
public Object getParameter(Component component) {
File f = ((JMPFileChooser)component).f;
if(f!= null && f.getParent()!=null)
((JMPFileChooser)component).bb.put(LoadFileDataSourceQueryChooser.FILE_CHOOSER_DIRECTORY_KEY,f.getParent());
return f;
}
}, Integer.class, new ParameterClassHandler() {
public Component createEditComponent(Blackboard bb) {
return new ValidatingTextField("", 5,
ValidatingTextField.INTEGER_VALIDATOR);
}
public void setParameter(Component component,
Object parameter) {
((JTextField) component)
.setText(((Integer) parameter).toString());
}
public Object getParameter(Component component) {
return ((JTextField) component).getText().length() > 0 ? new Integer(
((JTextField) component).getText())
: null;
}
} });
private JPanel mainPanel = new JPanel(new GridBagLayout());
public ConnectionDescriptorPanel(Registry registry, final WorkbenchContext context) {
super(new GridBagLayout());
this.context = context;
nameText = new JTextField("", 20);
//nameText.setPreferredSize(new Dimension());
driverComboBox = new JComboBox() {
{
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ParameterList oldParameterList = createParameterList();
schema = ((DataStoreDriver) getSelectedItem()).getParameterListSchema();
updateMainPanel(copyWherePossible(oldParameterList, schema),PersistentBlackboardPlugIn.get(context));
}
});
setRenderer(new DefaultListCellRenderer() {
public Component getListCellRendererComponent(JList list,
Object value, int index, boolean isSelected,
boolean cellHasFocus) {
return super.getListCellRendererComponent(list,
((DataStoreDriver) value).getName(), index,
isSelected, cellHasFocus);
}
});
}
};
add(mainPanel, new GridBagConstraints(0, 0, 1, 1, 0, 0,
GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(2, 2, 2, 2), 0, 0));
add(new JPanel(new GridBagLayout()), new GridBagConstraints(1, 1, 1, 1,
1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(0, 0, 0, 0), 0, 0));
driverComboBox.setModel(new DefaultComboBoxModel(sort(new Vector(
registry.getEntries(DataStoreDriver.REGISTRY_CLASSIFICATION)),
new Comparator() {
public int compare(Object o1, Object o2) {
return compare((DataStoreDriver) o1,
(DataStoreDriver) o2);
}
public int compare(DataStoreDriver a, DataStoreDriver b) {
return a.getName().compareTo(b.getName());
}
})));
initializePreferredSize();
driverComboBox.setSelectedIndex(0);
}
private void initializePreferredSize() {
int maxWidth = 0;
int maxHeight = 0;
for (int i = 0; i < driverComboBox.getItemCount(); i++) {
driverComboBox.setSelectedIndex(i);
maxWidth = Math.max(maxWidth, (int) getPreferredSize().getWidth());
maxHeight = Math.max(maxHeight, (int) getPreferredSize()
.getHeight());
}
setPreferredSize(new Dimension(maxWidth, maxHeight));
}
private Vector sort(Vector collection, Comparator comparator) {
Collections.sort(collection, comparator);
return collection;
}
private String getValidConnectionName()
{
String fieldName = nameText.getText();
if (fieldName == null || fieldName.trim().length() == 0) {
return ((DataStoreDriver) driverComboBox.getSelectedItem()).getName() + " " + ++createdConnectionCount;
}
return fieldName.trim();
}
public ConnectionDescriptor getConnectionDescriptor() {
return new ConnectionDescriptor(
getValidConnectionName(),
driverComboBox.getSelectedItem().getClass(),
createParameterList());
}
private ParameterList createParameterList() {
ParameterList parameterList = new ParameterList(schema);
for (int i = 0; i < editComponentList.size(); i++) {
parameterList.setParameter(schema.getNames()[i],
parameterClassHandler(schema.getNames()[i],
schema.getClasses()[i]).getParameter(
(Component) editComponentList.get(i)));
}
return parameterList;
}
public void setParameters(ConnectionDescriptor connDesc)
{
nameText.setText(connDesc.getName());
int driverComboIndex = getDriverComboBoxIndex(connDesc.getDataStoreDriverClassName());
if (driverComboIndex >= 0) {
driverComboBox.setSelectedIndex(driverComboIndex);
schema = ((DataStoreDriver) driverComboBox.getSelectedItem()).getParameterListSchema();
}
updateMainPanel(connDesc.getParameterList(), PersistentBlackboardPlugIn.get(context));
}
private int getDriverComboBoxIndex(String driverClassName)
{
for (int i = 0; i < driverComboBox.getItemCount(); i++) {
DataStoreDriver driver = (DataStoreDriver) driverComboBox.getItemAt(i);
if (driver.getClass().getName().equals(driverClassName)) {
return i;
}
}
return -1;
}
/*
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
JFrame frame = new JFrame();
frame.getContentPane().add(
new ConnectionDescriptorPanel(new Registry().createEntry(
DataStoreDriver.REGISTRY_CLASSIFICATION,
new PostgisDataStoreDriver()),null));
frame.pack();
frame.setVisible(true);
}
//*/
public String validateInput() {
for (int i = 0; i < editComponentList.size(); i++) {
Object parameter = parameterClassHandler(schema.getNames()[i],
schema.getClasses()[i]).getParameter(
(Component) editComponentList.get(i));
if (parameter == null || parameter.equals("")) {
return (I18N.get("jump.workbench.ui.plugin.datastore.ConnectionDescriptorPanel.Required-field-missing") + " " + schema.getNames()[i]);
}
}
return null;
}
private ParameterList copyWherePossible(ParameterList oldParameterList,
ParameterListSchema newSchema) {
ParameterList newParameterList = new ParameterList(newSchema);
for (int i = 0; i < newSchema.getNames().length; i++) {
String name = newSchema.getNames()[i];
newParameterList.setParameter(name, oldParameterList.getSchema()
.isValidName(name)
&& newSchema.getClasses()[i] == oldParameterList
.getSchema().getClass(name) ? oldParameterList
.getParameter(name) : null);
}
return newParameterList;
}
}