/** * Copyright 2014 Microsoft Open Technologies Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.microsoftopentechnologies.intellij.forms; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.microsoftopentechnologies.intellij.helpers.LinkListener; import com.microsoftopentechnologies.intellij.helpers.UIHelper; import com.microsoftopentechnologies.intellij.helpers.azure.AzureCmdException; import com.microsoftopentechnologies.intellij.helpers.azure.AzureRestAPIHelper; import com.microsoftopentechnologies.intellij.helpers.azure.AzureRestAPIManager; import com.microsoftopentechnologies.intellij.model.SqlDb; import com.microsoftopentechnologies.intellij.model.SqlServer; import com.microsoftopentechnologies.intellij.model.Subscription; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.List; import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.Future; public class CreateNewServiceForm extends JDialog { private JPanel mainPanel; private JTextField nameTextField; private JComboBox regionComboBox; private JComboBox serverComboBox; private JTextField serverUserNameTextField; private JPasswordField serverPasswordPasswordField; private JButton btnCloseButton; private JPasswordField serverPasswordConfirmationPasswordField; private JLabel lblPrivacy; private JButton btnCreate; private JLabel lblPricing; private JLabel lblPasswordConfirmation; private JComboBox subscriptionComboBox; private Runnable serviceCreated; public CreateNewServiceForm() { final JDialog form = this; this.setContentPane(mainPanel); this.setResizable(false); this.setModal(true); this.setTitle("Create Mobile Service"); lblPrivacy.addMouseListener(new LinkListener("http://msdn.microsoft.com/en-us/vstudio/dn425032.aspx")); lblPricing.addMouseListener(new LinkListener("http://www.azure.com/en-us/pricing/details/mobile-services/")); btnCloseButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { form.setVisible(false); form.dispose(); } }); subscriptionComboBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent itemEvent) { if (itemEvent.getStateChange() == ItemEvent.SELECTED) { subcriptionSelected((Subscription) subscriptionComboBox.getSelectedItem()); } } }); regionComboBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { for (int i = 0; i < serverComboBox.getItemCount(); i++) { if (serverComboBox.getItemAt(i) instanceof SqlDb) { SqlDb sqlDb = (SqlDb) serverComboBox.getItemAt(i); if (sqlDb.getServer().getRegion().equals(regionComboBox.getSelectedItem().toString())) { serverComboBox.setSelectedIndex(i); return; } } } serverComboBox.setSelectedIndex(serverComboBox.getItemCount() - 1); } }); serverComboBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent itemEvent) { if (itemEvent.getStateChange() == ItemEvent.SELECTED) { updateVisibleFields(itemEvent.getItem()); } } }); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { try { List<Subscription> subsList = AzureRestAPIManager.getManager().getSubscriptionList(); DefaultComboBoxModel subscriptionDefaultComboBoxModel = new DefaultComboBoxModel(subsList.toArray(new Subscription[subsList.size()])); subscriptionComboBox.setModel(subscriptionDefaultComboBoxModel); if (subsList.size() > 0) { subcriptionSelected(subsList.get(0)); } } catch (Throwable e) { form.setCursor(Cursor.getDefaultCursor()); UIHelper.showException("Error retrieving the subscription list: ", e, "Error retrieving the subscription list"); } } }); btnCreate.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { try { UUID id = ((Subscription) subscriptionComboBox.getSelectedItem()).getId(); String name = nameTextField.getText(); String region = regionComboBox.getSelectedItem().toString(); String server = (serverComboBox.getSelectedItem() instanceof SqlDb ? ((SqlDb) serverComboBox.getSelectedItem()).getServer().getName() : null); String admin = serverUserNameTextField.getText(); String pass = new String(serverPasswordPasswordField.getPassword()); String db = (serverComboBox.getSelectedItem() instanceof SqlDb ? ((SqlDb) serverComboBox.getSelectedItem()).getName() : null); String conf = new String(serverPasswordConfirmationPasswordField.getPassword()); String error = ""; if (name.isEmpty()) { error += "The service name must not be empty \n"; } if (region.isEmpty()) { error += "A region must be selected \n"; } if (admin.isEmpty()) { error += "User name must not be empty \n"; } if (pass.isEmpty()) { error += "Password must not be empty \n"; } if (server != null && db == null) { error += "Database must not be empty \n"; } if (!error.isEmpty()) { JOptionPane.showMessageDialog(form, error, "Error creating the service", JOptionPane.ERROR_MESSAGE); return; } if (!nameTextField.getText().matches("^[A-Za-z][A-Za-z0-9-]+[A-Za-z0-9]$")) { JOptionPane.showMessageDialog(form, "Invalid service name. Service name must start with a letter, \n" + "contain only letters, numbers, and hyphens, " + "and end with a letter or number.", "Error creating the service", JOptionPane.ERROR_MESSAGE); return; } if (server == null) { if (!pass.matches("^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$") || pass.contains(admin)) { JOptionPane.showMessageDialog(form, "Invalid password. The password must: \n" + " - Not contain all login name\n" + " - Have at least one upper case english letter\n" + " - Have at least one lower case english letter\n" + " - Have at least one digit\n" + " - Have at least one special character\n" + " - Be minimum 8 in length", "Error creating the service", JOptionPane.ERROR_MESSAGE); return; } if (!pass.equals(conf)) { JOptionPane.showMessageDialog(form, "Password confirmation should match password", "Error creating the service", JOptionPane.ERROR_MESSAGE); form.setCursor(Cursor.getDefaultCursor()); return; } } form.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); if (AzureRestAPIHelper.existsMobileService(name)) { JOptionPane.showMessageDialog(form, "The service name is used by another mobile service", "Error creating the service", JOptionPane.ERROR_MESSAGE); form.setCursor(Cursor.getDefaultCursor()); return; } AzureRestAPIManager.getManager().createService(id, region, admin, pass, name, server, db); serviceCreated.run(); form.setCursor(Cursor.getDefaultCursor()); form.setVisible(false); form.dispose(); } catch (Throwable e) { form.setCursor(Cursor.getDefaultCursor()); UIHelper.showException("An error occurred while creating the service.", e, "Error creating the service"); } } }); } }); } private void updateVisibleFields(Object selectedServer) { boolean isExistingDb = selectedServer instanceof SqlDb; lblPasswordConfirmation.setVisible(!isExistingDb); serverPasswordConfirmationPasswordField.setVisible(!isExistingDb); if (isExistingDb) { SqlDb db = (SqlDb) selectedServer; serverUserNameTextField.setText(db.getServer().getAdmin()); } else { serverUserNameTextField.setText(""); } } private void subcriptionSelected(final Subscription subscription) { regionComboBox.setModel(new DefaultComboBoxModel(new String[]{"(loading...)"})); ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { @Override public void run() { try { final List<String> locations = AzureRestAPIManager.getManager().getLocations(subscription.getId()); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { regionComboBox.setModel(new DefaultComboBoxModel(locations.toArray())); } }, ModalityState.any()); } catch (AzureCmdException e) { UIHelper.showException("Error retrieving the location list: ", e, "Error retrieving the location list"); } } }); serverComboBox.setModel(new DefaultComboBoxModel(new String[]{"(loading...)"})); ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { @Override public void run() { try { final List<SqlDb> databaseList = new ArrayList<SqlDb>(); List<SqlServer> sqlServerList = AzureRestAPIManager.getManager().getSqlServers(subscription.getId()); ArrayList<Future<List<SqlDb>>> futures = new ArrayList<Future<List<SqlDb>>>(); for (final SqlServer server : sqlServerList) { futures.add(ApplicationManager.getApplication().executeOnPooledThread(new Callable<List<SqlDb>>() { @Override public List<SqlDb> call() throws Exception { return AzureRestAPIManager.getManager().getSqlDb(subscription.getId(), server); } })); } for (Future<List<SqlDb>> future : futures) { for (SqlDb sqlDb : future.get()) { if (!sqlDb.getEdition().equals("System")) databaseList.add(sqlDb); } } ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { DefaultComboBoxModel defaultComboBoxModel = new DefaultComboBoxModel(databaseList.toArray()); defaultComboBoxModel.addElement("<< Create a Free SQL Database >>"); serverComboBox.setModel(defaultComboBoxModel); updateVisibleFields(defaultComboBoxModel.getSelectedItem()); } }, ModalityState.any()); } catch (Exception e) { UIHelper.showException("Error retrieving the server and database list: ", e, "Error retrieving the server and database list"); } } }); } public void setServiceCreated(Runnable serviceCreated) { this.serviceCreated = serviceCreated; } }