/* * RapidMiner * * Copyright (C) 2001-2014 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.repository.gui; import java.awt.Color; 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.KeyEvent; import java.awt.event.KeyListener; import java.net.MalformedURLException; import java.net.URL; import java.util.LinkedList; import java.util.List; import javax.swing.AbstractButton; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import com.rapidminer.gui.security.UserCredential; import com.rapidminer.gui.security.Wallet; import com.rapidminer.gui.tools.ProgressThread; import com.rapidminer.gui.tools.ResourceAction; import com.rapidminer.gui.tools.ResourceLabel; import com.rapidminer.gui.tools.SwingTools; import com.rapidminer.gui.tools.components.LinkButton; import com.rapidminer.repository.Repository; import com.rapidminer.repository.RepositoryException; import com.rapidminer.repository.RepositoryManager; import com.rapidminer.repository.remote.RemoteRepository; import com.rapidminer.tools.I18N; /** Panel to add remote repositories * * @author Simon Fischer, Nils Woehler * */ public class RemoteRepositoryPanel extends JPanel implements RepositoryConfigurationPanel { private static final long serialVersionUID = 1L; private final JTextField urlField = new JTextField("http://localhost:8080/", 30); private final JTextField aliasField = new JTextField("NewRepository", 30); private final JTextField userField = new JTextField(System.getProperty("user.name"), 20); private final JPasswordField passwordField = new JPasswordField(20); private static final String UNKNOWN_STATUS_LABEL = I18N.getGUILabel("check_connection_settings.unknown"); private static final String SUCCESS_STATUS_LABEL = I18N.getGUILabel("check_connection_settings.success"); private static final String CHECKING_STATUS_LABEL = I18N.getGUILabel("check_connection_settings.checking"); private static final ImageIcon SUCCESS_ICON = SwingTools.createIcon("16/ok.png"); private static final ImageIcon FAILURE_ICON = SwingTools.createIcon("16/error.png"); private static final ImageIcon UNKOWN_ICON = SwingTools.createIcon("16/unknown.png"); private static final Color UNKOWN_STATUS_COLOR = Color.GRAY; private static final Color FAILURE_STATUS_COLOR = Color.RED; private static final Color SUCCESS_STATUS_COLOR = Color.GREEN.darker().darker(); private static final Color CHECKING_STATUS_COLOR = Color.BLACK; private JButton okButton; private JLabel checkLabel = new JLabel(UNKNOWN_STATUS_LABEL); private final ResourceAction checkConnectionSettingsAction = new ResourceAction(false, "check_connection_settings") { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { enableComponents(false); new ProgressThread("check_connection_settings", false) { @Override public void run() { getProgressListener().setTotal(100); setCheckButtonVisible(false); adaptConnectionLabel(CHECKING_STATUS_LABEL, null, CHECKING_STATUS_COLOR); getProgressListener().setCompleted(43); String errorMessage = RemoteRepository.checkConfiguration(urlField.getText(), userField.getText(), passwordField.getPassword()); if (errorMessage == null) { adaptConnectionLabel(SUCCESS_STATUS_LABEL, SUCCESS_ICON, SUCCESS_STATUS_COLOR); } else { adaptConnectionLabel(I18N.getMessage(I18N.getGUIBundle(), "gui.label.check_connection_settings.failure", errorMessage) , FAILURE_ICON, FAILURE_STATUS_COLOR); } enableComponents(true); getProgressListener().complete(); } }.start(); } }; private final LinkButton checkButton = new LinkButton(checkConnectionSettingsAction, true); private KeyListener resetCheckButtonKeyListener = new KeyListener() { @Override public void keyTyped(KeyEvent e) {} @Override public void keyReleased(KeyEvent e) { resetConnectionStatusLabel(); } @Override public void keyPressed(KeyEvent e) {} }; public RemoteRepositoryPanel() { GridBagLayout gbl = new GridBagLayout(); setLayout(gbl); GridBagConstraints c = new GridBagConstraints(); c.anchor = GridBagConstraints.FIRST_LINE_START; c.weighty = 1; c.weightx = .5; c.insets = new Insets(4, 4, 4, 4); // ALIAS c.gridwidth = GridBagConstraints.RELATIVE; JLabel label = new ResourceLabel("repositorydialog.alias"); label.setLabelFor(aliasField); gbl.setConstraints(label, c); add(label); c.gridwidth = GridBagConstraints.REMAINDER; gbl.setConstraints(aliasField, c); add(aliasField); // URL c.gridwidth = GridBagConstraints.RELATIVE; label = new ResourceLabel("repositorydialog.url"); label.setLabelFor(urlField); gbl.setConstraints(label, c); add(label); c.gridwidth = GridBagConstraints.REMAINDER; gbl.setConstraints(urlField, c); add(urlField); // USERNAME c.gridwidth = GridBagConstraints.RELATIVE; c.insets = new Insets(10, 4, 4, 4); label = new ResourceLabel("repositorydialog.user"); label.setLabelFor(userField); gbl.setConstraints(label, c); add(label); c.gridwidth = GridBagConstraints.REMAINDER; gbl.setConstraints(userField, c); add(userField); // Password c.insets = new Insets(4, 4, 4, 4); c.gridwidth = GridBagConstraints.RELATIVE; label = new ResourceLabel("repositorydialog.password"); label.setLabelFor(passwordField); gbl.setConstraints(label, c); add(label); c.gridwidth = GridBagConstraints.REMAINDER; gbl.setConstraints(passwordField, c); add(passwordField); // connection status c.insets = new Insets(4, 4, 4, 4); c.gridwidth = GridBagConstraints.RELATIVE; c.fill = GridBagConstraints.BOTH; label = new ResourceLabel("connection_status"); gbl.setConstraints(label, c); add(label); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.BOTH; JPanel checkPanel = new JPanel(new GridBagLayout()); checkPanel.setPreferredSize(new Dimension(200,25)); gbl.setConstraints(checkPanel, c); add(checkPanel); c.gridwidth = GridBagConstraints.RELATIVE; checkPanel.add(checkLabel, c); c.insets = new Insets(0, 0, 2, 0); checkPanel.add(checkButton, c); aliasField.selectAll(); urlField.selectAll(); userField.selectAll(); userField.addKeyListener(resetCheckButtonKeyListener); passwordField.addKeyListener(resetCheckButtonKeyListener); urlField.addKeyListener(resetCheckButtonKeyListener); resetConnectionStatusLabel(); } @Override public void makeRepository() throws RepositoryException { final URL url; try { url = new URL(urlField.getText()); } catch (MalformedURLException e) { SwingTools.showSimpleErrorMessage("illegal_url", e); return; } String alias = aliasField.getText().trim(); if (alias.length() == 0) { alias = url.toString(); } final String finalAlias = alias; checkConfiguration(alias); ProgressThread pt = new ProgressThread("add_repository") { @Override public void run() { getProgressListener().setTotal(100); getProgressListener().setCompleted(10); Repository repository = new RemoteRepository(url, finalAlias, userField.getText(), passwordField.getPassword(), false); getProgressListener().setCompleted(90); RepositoryManager.getInstance(null).addRepository(repository); UserCredential authenticationCredentials = new UserCredential(urlField.getText(), userField.getText(), passwordField.getPassword()); // use alias as ID to store credentials Wallet.getInstance().registerCredentials(finalAlias, authenticationCredentials); Wallet.getInstance().saveCache(); getProgressListener().setCompleted(100); getProgressListener().complete(); } }; pt.start(); } private void setCheckButtonVisible(boolean visible) { checkButton.setVisible(visible); checkLabel.setVisible(!visible); } private void enableComponents(boolean enabled) { aliasField.setEditable(enabled); urlField.setEditable(enabled); passwordField.setEditable(enabled); userField.setEditable(enabled); if (okButton != null) { okButton.setEnabled(enabled); } } @Override public void configureUIElementsFrom(Repository remote) { aliasField.setText(((RemoteRepository) remote).getAlias()); urlField.setText(((RemoteRepository) remote).getBaseUrl().toString()); userField.setText(((RemoteRepository) remote).getUsername()); UserCredential credentials = Wallet.getInstance().getEntry(aliasField.getText(), urlField.getText()); if (credentials != null) { passwordField.setText(new String(credentials.getPassword())); } } @Override public boolean configure(final Repository repository) { URL url; try { url = new URL(urlField.getText()); } catch (MalformedURLException e) { SwingTools.showSimpleErrorMessage("illegal_url", e); return false; } String userName = userField.getText(); char[] password = passwordField.getPassword(); String alias = aliasField.getText(); try { // only check if Alias is different if (((RemoteRepository) repository).getAlias().equals(alias)) { alias = null; } checkConfiguration(alias); } catch (RepositoryException e) { SwingTools.showSimpleErrorMessage("cannot_configure_repository", e); return false; } if (alias != null) { ((RemoteRepository) repository).rename(alias); } ((RemoteRepository) repository).setBaseUrl(url); ((RemoteRepository) repository).setUsername(userName); ((RemoteRepository) repository).setPassword(password); UserCredential authenticationCredentials = new UserCredential(urlField.getText(), userName, password); // use alias as ID to store credentials String id = ((RemoteRepository) repository).getAlias(); Wallet.getInstance().registerCredentials(id, authenticationCredentials); Wallet.getInstance().saveCache(); try { // this needs to be called after changing the credentials, // otherwise the old webservice will keep using the previous credentials ((RemoteRepository) repository).resetRepositoryService(); } catch (RepositoryException e) { SwingTools.showSimpleErrorMessage("error_connecting_to_server", e); } return true; } @Override public JComponent getComponent() { return this; } @Override public void setOkButton(JButton okButton) { this.okButton = okButton; } @Override public List<AbstractButton> getAdditionalButtons() { LinkedList<AbstractButton> buttons = new LinkedList<AbstractButton>(); // buttons.add(checkButton); return buttons; } private void resetConnectionStatusLabel() { adaptConnectionLabel(UNKNOWN_STATUS_LABEL, UNKOWN_ICON, UNKOWN_STATUS_COLOR); setCheckButtonVisible(true); } private void adaptConnectionLabel(String text, Icon icon, Color color) { checkLabel.setText(text); checkLabel.setIcon(icon); checkLabel.setBackground(color); checkLabel.setForeground(color); } /** * Throws a {@link RepositoryException} if the given alias is invalid. * @param alias * @throws RepositoryException */ private void checkConfiguration(String alias) throws RepositoryException { // make sure that it's not possible to create multiple repositories in the same location or with the same alias for (Repository repo : RepositoryManager.getInstance(null).getRepositories()) { if (repo.getName().equals(alias)) { throw new RepositoryException(I18N.getMessage(I18N.getErrorBundle(), "repository.repository_creation_duplicate_alias")); } } } }