Java tutorial
/* Copyright (C) 2015, University of Kansas Center for Research * * Specify Software Project, specify@ku.edu, Biodiversity Institute, * 1345 Jayhawk Boulevard, Lawrence, Kansas, 66045, USA * * This program 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 2 * of the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package edu.ku.brc.specify.config.init; import static edu.ku.brc.ui.UIHelper.createDuplicateJGoodiesDef; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; import java.util.Properties; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import org.apache.commons.lang.StringUtils; import com.jgoodies.forms.builder.PanelBuilder; import com.jgoodies.forms.layout.FormLayout; import edu.ku.brc.dbsupport.DBConnection; import edu.ku.brc.dbsupport.DBMSUserMgr; import edu.ku.brc.dbsupport.PermissionInfo; import edu.ku.brc.ui.UIHelper; import edu.ku.brc.ui.UIRegistry; import edu.ku.brc.util.Pair; /** * @author rod * * @code_status Alpha * * Apr 01, 2009 * */ @SuppressWarnings("serial") public class MasterUserPanel extends GenericFormPanel { protected String propName = "next"; protected Boolean isOK = null; protected JButton createMUBtn; protected JLabel label; protected String errorKey = null; // Advanced Part protected JButton skipStepBtn; protected boolean manualLoginOK = false; protected JLabel advLabel; protected boolean isEmbedded = false; /** * @param name * @param title * @param helpContext * @param labels * @param fields * @param nextBtn * @param makeStretchy */ public MasterUserPanel(String name, String title, String helpContext, String[] labels, String[] fields, Integer[] numColumns, JButton nextBtn, JButton prevBtn, boolean makeStretchy) { super(name, title, helpContext, labels, fields, numColumns, nextBtn, prevBtn, makeStretchy); } /* (non-Javadoc) * @see edu.ku.brc.specify.config.init.GenericFormPanel#init(java.lang.String, java.lang.String[], boolean[], java.lang.String[], java.lang.Integer[]) */ @Override protected void init(final String title, final String[] fields, final boolean[] required, final String[] types, final Integer[] numColumns) { super.init(title, fields, required, types, numColumns); label = UIHelper.createLabel(" ", SwingConstants.CENTER); createMUBtn = UIHelper.createI18NButton("CREATE_MASTER_BTN"); PanelBuilder tstPB = new PanelBuilder(new FormLayout("f:p:g,p,f:p:g", "p")); tstPB.add(createMUBtn, cc.xy(2, 1)); PanelBuilder panelPB = new PanelBuilder(new FormLayout("f:p:g", "20px,p,2px,p,2px,p")); panelPB.add(tstPB.getPanel(), cc.xy(1, 2)); panelPB.add(getProgressBar(), cc.xy(1, 4)); panelPB.add(label, cc.xy(1, 6)); builder.add(panelPB.getPanel(), cc.xyw(3, row, 2)); row += 2; // Advance part of pane advLabel = UIHelper.createI18NLabel("ADV_MU_DESC", SwingConstants.CENTER); skipStepBtn = UIHelper.createI18NButton("ADV_MU_TEST"); JComponent sep = builder.addSeparator(UIRegistry.getResourceString("ADV_TITLE"), cc.xyw(3, row, 2)); row += 2; builder.add(advLabel, cc.xyw(3, row, 2)); row += 2; tstPB = new PanelBuilder(new FormLayout("f:p:g,p,f:p:g", "p")); tstPB.add(skipStepBtn, cc.xy(2, 1)); builder.add(tstPB.getPanel(), cc.xyw(3, row, 2)); row += 2; skipStepBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { createMUBtn.setEnabled(false); skipStepBtn.setEnabled(false); boolean ok = skipDBCreate(); createMUBtn.setEnabled(true); skipStepBtn.setEnabled(true); advLabel.setText(UIRegistry.getResourceString(ok ? "ADV_DB_OK" : "ADV_DB_ERR")); } }); createMUBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { createMasterUser(); } }); progressBar.setVisible(false); if (UIRegistry.isMobile()) { skipStepBtn.setVisible(false); advLabel.setVisible(false); sep.setVisible(false); } } /* (non-Javadoc) * @see edu.ku.brc.specify.config.init.BaseSetupPanel#doingNext() */ @Override public void doingNext() { isEmbedded = DBConnection.getInstance().isEmbedded(); if (isEmbedded) { ((JTextField) comps.get("saUserName")).setText(properties.getProperty("dbUserName")); ((JTextField) comps.get("saPassword")).setText(properties.getProperty("dbPassword")); ((JTextField) comps.get("saUserName")).setEnabled(false); ((JTextField) comps.get("saPassword")).setEnabled(false); } } /** * @return the Row and Column JGoodies definitions */ protected Pair<String, String> getRowColDefs() { String rowDef = "p,5px" + (fieldsNames.length > 0 ? "," + createDuplicateJGoodiesDef("p", "2px", fieldsNames.length) : "") + getAdditionalRowDefs() + ",2px,p,2px,p,8px,p"; return new Pair<String, String>("p,2px,p,f:p:g", rowDef); } /** * */ protected boolean skipDBCreate() { getValues(properties); DBMSUserMgr mgr = DBMSUserMgr.getInstance(); String dbName = properties.getProperty("dbName"); String hostName = properties.getProperty("hostName"); String saUserName = ((JTextField) comps.get("saUserName")).getText(); String saPassword = ((JTextField) comps.get("saPassword")).getText(); if (!isEmbedded) { try { if (mgr.connect(saUserName, saPassword, hostName, dbName)) { if (checkMasterUserPerms(mgr, saUserName)) { nextBtn.setEnabled(true); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { nextBtn.doClick(); } }); return true; } } } finally { mgr.close(); } } else { nextBtn.setEnabled(true); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { nextBtn.doClick(); } }); return true; } return false; } /* (non-Javadoc) * @see edu.ku.brc.specify.config.init.GenericFormPanel#getValues(java.util.Properties) */ @Override public void getValues(Properties props) { super.getValues(props); } /* (non-Javadoc) * @see edu.ku.brc.specify.config.init.GenericFormPanel#getAdditionalRowDefs() */ @Override protected String getAdditionalRowDefs() { return ",2px,p"; } /* (non-Javadoc) * @see edu.ku.brc.specify.config.init.GenericFormPanel#isUIValid() */ @Override public boolean isUIValid() { boolean isValid = super.isUIValid(); if (properties != null) { String dbUsername = properties.getProperty("dbUserName"); String saUserName = ((JTextField) comps.get("saUserName")).getText(); String saPassword = ((JTextField) comps.get("saPassword")).getText(); if (!DatabasePanel.checkForValidText(label, saUserName, "ERR_BAD_USRNAME", "NO_SPC_USRNAME", false) || !DatabasePanel.checkForValidText(label, saPassword, null, "NO_SPC_PWDNAME", false)) { isOK = false; createMUBtn.setEnabled(false); return false; } if (dbUsername.equals(saUserName) && !isEmbedded) { label.setForeground(Color.RED); label.setText(UIRegistry.getResourceString("DB_SA_USRNAME_MATCH")); createMUBtn.setEnabled(false); return false; } createMUBtn.setEnabled(true); label.setText(""); } return isValid && isOK != null && isOK; } /** * @param enable */ protected void setUIEnabled(final boolean enable) { for (JComponent c : compList) { c.setEnabled(enable); } createMUBtn.setEnabled(enable); } /* (non-Javadoc) * @see edu.ku.brc.specify.config.init.BaseSetupPanel#textChanged(javax.swing.JTextField) */ @Override protected void textChanged(final JTextField txt) { super.textChanged(txt); if (isOK != null && !isOK) { isOK = null; createMUBtn.setVisible(true); label.setText(" "); properties.put("masterChanged", true); } } /** * @param mgr * @return */ private boolean checkMasterUserPerms(DBMSUserMgr mgr, String masterUserName) { int[] MASTER_PERMS = { DBMSUserMgr.PERM_SELECT, DBMSUserMgr.PERM_UPDATE, DBMSUserMgr.PERM_DELETE, DBMSUserMgr.PERM_INSERT, DBMSUserMgr.PERM_LOCK_TABLES }; List<PermissionInfo> masterPerms = new ArrayList<PermissionInfo>(MASTER_PERMS.length); for (int p : MASTER_PERMS) { masterPerms.add(new PermissionInfo("?", "", p, false)); } List<PermissionInfo> perms = mgr.getPermissionsForCurrentUser(); String dbName = properties.getProperty(DBNAME); Pair<List<PermissionInfo>, List<PermissionInfo>> missingPerms = PermissionInfo.getMissingPerms(perms, masterPerms, dbName); if (missingPerms.getFirst().size() > 0) { String missingPermStr = PermissionInfo.getMissingPermissionString(mgr, missingPerms.getFirst(), dbName); UIRegistry.showLocalizedError("SEC_MISSING_PERMS", masterUserName, missingPermStr); return false; } return true; } /** * @return */ @SuppressWarnings("unchecked") protected boolean checkPermsForMasterUserCreation() { boolean result = true; //In order for the master user creation code to work the it user must have create_user (actually not if the user has already has grants //on another db, but for now...) and grant on the database, and select on the mysql db (only user and db tables, I think, but for now...) List<PermissionInfo> perms = (List<PermissionInfo>) properties.get(DBUSERPERMS); if (perms != null) { boolean hasCreateUser = false; boolean hasGrant = false; boolean hasSelectOnMysql = false; boolean hasReload = false; String dbName = properties.getProperty(DBNAME); String dbUserName = properties.getProperty(DBUSERNAME); for (PermissionInfo pi : perms) { if (pi.getPerm() == DBMSUserMgr.PERM_CREATE_USER && (pi.getDb().equals("*") || pi.getDb().equals(dbName))) { hasCreateUser = true; } else if (pi.getPerm() == DBMSUserMgr.PERM_GRANT && (pi.getDb().equals("*") || pi.getDb().equals(dbName))) { hasGrant = true; } else if (pi.getPerm() == DBMSUserMgr.PERM_SELECT && (pi.getDb().equals("*") || pi.getDb().equals("mysql"))) { hasSelectOnMysql = true; } else if (pi.getPerm() == DBMSUserMgr.PERM_RELOAD) { hasReload = true; } if (hasCreateUser && hasGrant && hasSelectOnMysql && hasReload) { break; } } if (!hasCreateUser) { DBMSUserMgr mgr = DBMSUserMgr.getInstance(); String dbPassword = properties.getProperty("dbPassword"); String hostName = properties.getProperty("hostName"); String saUserName = ((JTextField) comps.get("saUserName")).getText(); if (mgr.connectToDBMS(dbUserName, dbPassword, hostName)) { try { //MySQLDMBSUserMgr.doesUserExists() only works if client and host are on the same machine //so basically create user will be required for all remote connections whether or not it is REALLY needed. hasCreateUser = mgr.doesUserExists(saUserName); } finally { mgr.close(); } } } result = hasCreateUser && hasGrant && hasSelectOnMysql && hasReload; if (!result) { List<PermissionInfo> missingPerms = new ArrayList<PermissionInfo>(); if (!hasCreateUser) { missingPerms.add(new PermissionInfo(dbName, "", DBMSUserMgr.PERM_CREATE_USER, false)); } if (!hasGrant) { missingPerms.add(new PermissionInfo(dbName, "", DBMSUserMgr.PERM_GRANT, false)); } if (!hasSelectOnMysql) { missingPerms.add(new PermissionInfo("mysql", "", DBMSUserMgr.PERM_SELECT, false)); } if (!hasReload) { missingPerms.add(new PermissionInfo("mysql", "", DBMSUserMgr.PERM_RELOAD, false)); } String missingPermStr = PermissionInfo.getMissingPermissionString(DBMSUserMgr.getInstance(), missingPerms, dbName); UIRegistry.showLocalizedError("SEC_MISSING_PERMS", dbUserName, missingPermStr); } } return result; } /** * */ protected void createMasterUser() { String saUsrNm = ((JTextField) comps.get("saUserName")).getText(); if (StringUtils.isNotEmpty(saUsrNm) && saUsrNm.equalsIgnoreCase("root")) { UIRegistry.showLocalizedError("MASTER_NO_ROOT"); ((JTextField) comps.get("saUserName")).setText(""); return; } if (!checkPermsForMasterUserCreation()) { return; } if (isOK == null || !isOK) { progressBar.setIndeterminate(true); progressBar.setVisible(true); setUIEnabled(false); label.setText(UIRegistry.getResourceString("CONN_DB")); createMUBtn.setVisible(false); SwingWorker<Object, Object> worker = new SwingWorker<Object, Object>() { @Override protected Object doInBackground() throws Exception { MasterUserPanel.this.label.setForeground(Color.BLACK); isOK = false; if (!isEmbedded) { DBMSUserMgr mgr = DBMSUserMgr.getInstance(); String dbUserName = properties.getProperty("dbUserName"); String dbPassword = properties.getProperty("dbPassword"); String dbName = properties.getProperty("dbName"); String hostName = properties.getProperty("hostName"); String saUserName = ((JTextField) comps.get("saUserName")).getText(); String saPassword = ((JTextField) comps.get("saPassword")).getText(); if (mgr.connectToDBMS(dbUserName, dbPassword, hostName)) { if (mgr.doesUserExists(saUserName)) { if (!mgr.setPermissions(saUserName, dbName, DBMSUserMgr.PERM_ALL_BASIC)) { errorKey = "ERR_SET_PERM"; } else { isOK = true; } } if (!mgr.doesUserExists(saUserName)) { firePropertyChange(propName, 0, 1); isOK = mgr.createUser(saUserName, saPassword, dbName, DBMSUserMgr.PERM_ALL_BASIC); if (!isOK) { errorKey = "ERR_CRE_MASTER"; } else { isOK = true; } } } else { errorKey = "NO_CONN_ROOT"; isOK = false; } if (mgr != null) { mgr.close(); } } else { isOK = true; } return null; } /* (non-Javadoc) * @see javax.swing.SwingWorker#done() */ @Override protected void done() { super.done(); progressBar.setIndeterminate(false); progressBar.setVisible(false); setUIEnabled(true); updateBtnUI(); createMUBtn.setVisible(!isOK); if (isOK) { setUIEnabled(false); label.setText(UIRegistry.getResourceString("MASTER_CREATED")); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { nextBtn.doClick(); } }); } else { label.setText(UIRegistry.getResourceString(errorKey)); UIRegistry.showLocalizedError(errorKey); } } }; worker.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(final PropertyChangeEvent evt) { if (propName.equals(evt.getPropertyName())) { MasterUserPanel.this.label.setText(UIRegistry.getLocalizedMessage("CREATE_MASTER")); } } }); worker.execute(); } } }