package com.rthoni.intellij.codefromds.ui.dialogs; import com.intellij.database.model.DasObject; import com.intellij.database.psi.DbDataSource; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.ui.ValidationInfo; import com.intellij.ui.ColoredListCellRenderer; import com.intellij.ui.JBColor; import com.intellij.ui.components.JBList; import com.rthoni.intellij.codefromds.business.Helper; import com.rthoni.intellij.codefromds.dbo.options.ColumnSelection; import com.rthoni.intellij.codefromds.dbo.options.DataSourceSelection; import com.rthoni.intellij.codefromds.dbo.options.GenerateOptions; import com.rthoni.intellij.codefromds.dbo.options.TableSelection; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionListener; import java.awt.event.ActionListener; import java.io.File; import java.util.List; import java.util.Vector; import java.util.function.Consumer; import java.util.stream.Collectors; /** * Created by robin on 11/14/16. */ public class GenerateDialog extends DialogWrapper { private JPanel _panel; private JBList _listDatasources; private JBList _listTables; private JBList _listColumns; private TextFieldWithBrowseButton _textModels; private TextFieldWithBrowseButton _textDataSource; private TextFieldWithBrowseButton _textDataSourceTemplate; private TextFieldWithBrowseButton _textModelsTemplate; private TextFieldWithBrowseButton _textConfigPath; private JTextField _textFilesExtension; private JLabel _lblModelsPath; private JLabel _lblDataSourcePath; private JLabel _lblDataSourceTemplatePath; private JLabel _lblModelsTemplatePath; private TextFieldWithBrowseButton _textCastFile; private JLabel _lblCastFile; private GenerateOptions _options; private Project _project; public GenerateDialog(Project project) { super(project); _project = project; setTitle("Code FROM data source"); setOptions(null); init(); } public GenerateOptions getOptions() { return _options; } public void setOptions(GenerateOptions options) { _options = options; if (_options != null) { showSource(_options.getSelection()); _textModels.setText(Helper.getAbsolutePath(_project, _options.getModelsRelativePath())); _textDataSource.setText(Helper.getAbsolutePath(_project, _options.getDataSourceRelativePath())); _textDataSourceTemplate.setText(Helper.getAbsolutePath(_project, _options.getDataSourceTemplateRelativePath())); _textModelsTemplate.setText(Helper.getAbsolutePath(_project, _options.getModelsTemplateRelativePath())); _textFilesExtension.setText(_options.getFilesExtension()); _textCastFile.setText(Helper.getAbsolutePath(_project, _options.getCastFileRelativePath())); _textConfigPath.setText(_options.getConfigAbsolutePath()); } else { showSource(null); _textModels.setText(""); _textDataSource.setText(""); _textDataSourceTemplate.setText(""); _textModelsTemplate.setText(""); _textFilesExtension.setText(""); _textCastFile.setText(""); _textConfigPath.setText(""); } } @Nullable @Override protected ValidationInfo doValidate() { ValidationInfo info = null; File modelDir = _options == null ? null : new File(Helper.getAbsolutePath(_project, _options.getModelsRelativePath())); File dataSourcePath = _options == null ? null : new File(Helper.getAbsolutePath(_project, _options.getDataSourceRelativePath())); File dataSourceDir = _options == null ? null : new File(dataSourcePath.getParent()); File dataSourceTemplatePath = _options == null ? null : new File(Helper.getAbsolutePath(_project, _options.getDataSourceTemplateRelativePath())); File modelsTemplatePath = _options == null ? null : new File(Helper.getAbsolutePath(_project, _options.getModelsTemplateRelativePath())); File configPath = _options == null ? null : new File(_options.getConfigAbsolutePath()); File configDir = _options == null ? null : new File(configPath.getParent()); String extension = _options == null ? null : _options.getFilesExtension(); File castFilePath = _options == null ? null : new File(Helper.getAbsolutePath(_project, _options.getCastFileRelativePath())); if (_options == null) { info = new ValidationInfo("No Data Source Selected", _listDatasources); } else if (!modelDir.exists() || !modelDir.isDirectory()) { info = new ValidationInfo("Models folder does not exists", _textModels.getTextField()); } else if (!dataSourceDir.exists() || !dataSourceDir.isDirectory()) { info = new ValidationInfo("Data source folder does not exists", _textDataSource.getTextField()); } else if (!dataSourceTemplatePath.exists() || !dataSourceTemplatePath.isFile()) { info = new ValidationInfo("Data source template file does not exists", _textDataSourceTemplate.getTextField()); } else if (!modelsTemplatePath.exists() || !modelsTemplatePath.isFile()) { info = new ValidationInfo("Models template file does not exists", _textModelsTemplate.getTextField()); } else if (!configDir.exists() || !configDir.isDirectory()) { info = new ValidationInfo("Configuration file parent folder does not exists", _textConfigPath.getTextField()); } else if (extension == null || extension.isEmpty()) { info = new ValidationInfo("Files extension is required", _textFilesExtension); } else if (extension.startsWith(".")) { info = new ValidationInfo("Files extension must not include dot (.)", _textFilesExtension); } else if (!castFilePath.exists() || !castFilePath.isFile()) { info = new ValidationInfo("Cast file does not exists", _textCastFile.getTextField()); } return info; } @Nullable @Override protected JComponent createCenterPanel() { List dataSources = Helper.getDataSources(); _listDatasources.setListData(dataSources.stream().map(DasObject::getName).toArray(String[]::new)); _listDatasources.addListSelectionListener(e -> { if (!e.getValueIsAdjusting()) { int index = _listDatasources.getSelectedIndex(); if (index == -1) { setOptions(null); } else { setOptions(new GenerateOptions(dataSources.get(index))); } } }); _listTables.addListSelectionListener(e -> { if (!e.getValueIsAdjusting()) { int index = _listTables.getSelectedIndex(); if (index == -1) { showTable(null); } else { showTable(_options.getSelection().getTables().get(index)); } } }); setupTextField(_textModels, null, true, "Models"); setupTextField(_textDataSource, null, false, "Data Source"); setupTextField(_textDataSourceTemplate, null, false, "Data Source Template"); setupTextField(_textModelsTemplate, null, false, "Models Template"); setupTextField(_textConfigPath, null, false, "Configuration"); setupTextField(_textCastFile, null, false, "Types Cast"); setupTextFieldListener(_textModels.getTextField(), s -> { _options.setModelsRelativePath(Helper.getRelativePath(_project, s)); _lblModelsPath.setText("$ProjectRoot/" + _options.getModelsRelativePath()); }); setupTextFieldListener(_textDataSource.getTextField(), s -> { _options.setDataSourceRelativePath(Helper.getRelativePath(_project, s)); _lblDataSourcePath.setText("$ProjectRoot/" + _options.getDataSourceRelativePath()); }); setupTextFieldListener(_textDataSourceTemplate.getTextField(), s -> { _options.setDataSourceTemplateRelativePath(Helper.getRelativePath(_project, s)); _lblDataSourceTemplatePath.setText("$ProjectRoot/" + _options.getDataSourceTemplateRelativePath()); }); setupTextFieldListener(_textModelsTemplate.getTextField(), s -> { _options.setModelsTemplateRelativePath(Helper.getRelativePath(_project, s)); _lblModelsTemplatePath.setText("$ProjectRoot/" + _options.getModelsTemplateRelativePath()); }); setupTextFieldListener(_textFilesExtension, s -> _options.setFilesExtension(s)); setupTextFieldListener(_textConfigPath.getTextField(), s -> _options.setConfigAbsolutePath(s)); setupTextFieldListener(_textCastFile.getTextField(), s -> { _options.setCastFileRelativePath(Helper.getRelativePath(_project, s)); _lblCastFile.setText("$ProjectRoot/" + _options.getCastFileRelativePath()); }); _listTables.setCellRenderer(new ColoredListCellRenderer() { @Override protected void customizeCellRenderer(@NotNull JList jList, Object o, int i, boolean b, boolean b1) { TableSelection tableSelection = _options.getSelection().getTables().get(i); if (tableSelection.hasAll()) { setBackground(JBColor.GREEN); } else if (tableSelection.hasNone()) { setBackground(JBColor.RED); } else { setBackground(JBColor.ORANGE); } append(tableSelection.getTable().getName()); } }); if (dataSources.size() > 0) { _listDatasources.setSelectedIndices(new int[]{0}); } return _panel; } private void setupTextFieldListener(JTextField field, Consumer consumer) { field.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { changed(); } @Override public void removeUpdate(DocumentEvent e) { changed(); } @Override public void changedUpdate(DocumentEvent e) { changed(); } public void changed() { consumer.accept(field.getText()); } }); } private void setupTextField(TextFieldWithBrowseButton field, Project project, boolean dirsOnly, String title) { for (ActionListener l : field.getButton().getActionListeners()) { field.getButton().removeActionListener(l); } field.addBrowseFolderListener("Choose " + title + " " + (dirsOnly ? "Folder" : "File"), "Choose " + (dirsOnly ? "Folder" : "File"), project, dirsOnly ? FileChooserDescriptorFactory.createSingleFolderDescriptor() : FileChooserDescriptorFactory.createSingleFileDescriptor()); } private void showSource(DataSourceSelection source) { if (source != null) { List tables = source.getTables().stream().map(t -> t.getTable().getName()).collect(Collectors.toList()); _listTables.setListData(tables.toArray(new String[tables.size()])); if (tables.size() > 0) { showTable(source.getTables().get(0)); } else { showTable(null); } } else { _listTables.setListData(new String[]{}); showTable(null); } } private int[] getSelectedIndices(final TableSelection table) { List columns = table.getColumns(); List indices = new Vector<>(); for (int i = 0; i < columns.size(); ++i) { if (columns.get(i).isSelected()) { indices.add(i); } } return indices.stream().mapToInt(Integer::intValue).toArray(); } private void updateSelection(final TableSelection table) { List columns = table.getColumns(); for (int i = 0; i < columns.size(); ++i) { columns.get(i).setSelected(_listColumns.isSelectedIndex(i)); } } private void showTable(TableSelection table) { for (ListSelectionListener e : _listColumns.getListSelectionListeners()) { _listColumns.removeListSelectionListener(e); } if (table != null) { _listColumns.setListData(table.getColumns().stream().map(c -> c.getColumn().getName()).toArray(String[]::new)); int[] indices = getSelectedIndices(table); _listColumns.setSelectedIndices(indices); _listColumns.addListSelectionListener(e -> { if (!e.getValueIsAdjusting()) { _listTables.updateUI(); updateSelection(table); } }); } else { _listColumns.setListData(new String[]{}); } } }