Java tutorial
/** * Copyright (c) Microsoft Corporation * <p/> * All rights reserved. * <p/> * MIT License * <p/> * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * <p/> * The above copyright notice and this permission notice shall be included in all copies or substantial portions of * the Software. * <p/> * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.microsoft.intellij.ui.azureroles; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.module.Module; import com.intellij.openapi.options.BaseConfigurable; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.ValidationInfo; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.ui.AnActionButton; import com.intellij.ui.AnActionButtonRunnable; import com.intellij.ui.AnActionButtonUpdater; import com.intellij.ui.ToolbarDecorator; import com.intellij.ui.table.TableView; import com.intellij.util.ui.ColumnInfo; import com.intellij.util.ui.ListTableModel; import com.intellij.util.ui.table.ComboBoxTableCellEditor; import com.interopbridges.tools.windowsazure.*; import com.microsoft.intellij.ui.AzureAbstractPanel; import com.microsoft.intellij.util.PluginUtil; import com.microsoftopentechnologies.azurecommons.util.WAEclipseHelperMethods; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.table.TableCellEditor; import java.awt.*; import java.util.List; import static com.microsoft.intellij.ui.messages.AzureBundle.message; public class RoleEndpointsPanel extends BaseConfigurable implements AzureAbstractPanel, SearchableConfigurable, Configurable.NoScroll { /** * End point range's minimum value. */ private final static int RANGE_MIN = 1; /** * End point range's maximum value. */ private final static int RANGE_MAX = 65535; private JPanel contentPane; private TableView<WindowsAzureEndpoint> tblEndpoints; private JPanel tablePanel; private Module module; private WindowsAzureProjectManager waProjManager; private final WindowsAzureRole windowsAzureRole; private List<WindowsAzureEndpoint> listEndPoints; private ListTableModel<WindowsAzureEndpoint> myModel; public RoleEndpointsPanel(Module module, WindowsAzureProjectManager waProjManager, WindowsAzureRole windowsAzureRole) { this.module = module; this.waProjManager = waProjManager; this.windowsAzureRole = windowsAzureRole; try { //Get endpoints to be displayed in endpoints table listEndPoints = windowsAzureRole.getEndpoints(); } catch (WindowsAzureInvalidProjectOperationException e) { PluginUtil.displayErrorDialogAndLog(message("adRolErrTitle"), message("adRolErrMsgBox1") + message("adRolErrMsgBox2"), e); } init(); } private void init() { initializeModel(); tblEndpoints.setRowHeight(ComboBoxTableCellEditor.INSTANCE.getComponent().getPreferredSize().height); } private void initializeModel() { myModel = new EndpointsTableModel(listEndPoints); tblEndpoints.setModelAndUpdateColumns(myModel); tblEndpoints.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); } private void createUIComponents() { tblEndpoints = new TableView<WindowsAzureEndpoint>(); tablePanel = ToolbarDecorator.createDecorator(tblEndpoints, null) .setAddAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { addEndpoint(); } }).setEditAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { editEndpoint(); } }).setRemoveAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { removeEndpoint(); } }).setEditActionUpdater(new AnActionButtonUpdater() { @Override public boolean isEnabled(AnActionEvent e) { return tblEndpoints.getSelectedObject() != null; } }).setRemoveActionUpdater(new AnActionButtonUpdater() { @Override public boolean isEnabled(AnActionEvent e) { return tblEndpoints.getSelectedObject() != null; } }).disableUpDownActions().createPanel(); tablePanel.setPreferredSize(new Dimension(-1, 200)); } private void addEndpoint() { EndpointDialog endpointDialog = new EndpointDialog(windowsAzureRole, null); endpointDialog.show(); if (endpointDialog.isOK()) { ((EndpointsTableModel) tblEndpoints.getModel()).fireTableDataChanged(); setModified(true); } } /** * Listener method for edit button which opens a dialog * to edit an endpoint. */ private void editEndpoint() { WindowsAzureEndpoint waEndpoint = tblEndpoints.getSelectedObject(); /* * Check end point selected for modification * is associated with caching then give error * and does not allow to edit. */ try { if (waEndpoint.isCachingEndPoint()) { PluginUtil.displayErrorDialog(message("cachDsblErTtl"), message("endPtEdtErMsg")); } else if (waEndpoint.isStickySessionEndpoint() && waEndpoint.isSSLEndpoint()) { PluginUtil.displayErrorDialog(message("sslSesDsbl"), message("sslSesAffMsg")); } else if (waEndpoint.isStickySessionEndpoint()) { PluginUtil.displayErrorDialog(message("sesAffDsblErTl"), message("sesAffMsg")); } else if (waEndpoint.isSSLEndpoint()) { PluginUtil.displayErrorDialog(message("sslDsblErTl"), message("sslMsg")); } else if (waEndpoint.isSSLRedirectEndPoint()) { PluginUtil.displayErrorDialog(message("sslDsblErTl"), message("sslMsg")); } else { EndpointDialog endpointDialog = new EndpointDialog(windowsAzureRole, waEndpoint); endpointDialog.show(); if (endpointDialog.isOK()) { ((EndpointsTableModel) tblEndpoints.getModel()).fireTableDataChanged(); setModified(true); } } } catch (WindowsAzureInvalidProjectOperationException e) { PluginUtil.displayErrorDialog(message("genErrTitle"), message("chEndPtErMsg")); } } /** * Listener method for remove button which * deletes the selected endpoint. */ private void removeEndpoint() { WindowsAzureEndpoint waEndpoint = tblEndpoints.getSelectedObject(); try { WindowsAzureEndpoint debugEndpt = windowsAzureRole.getDebuggingEndpoint(); String dbgEndptName = ""; if (debugEndpt != null) { dbgEndptName = debugEndpt.getName(); } // delete the selected endpoint /* * Check end point selected for removal * is associated with Caching then give error * and does not allow to remove. */ if (waEndpoint.isCachingEndPoint()) { PluginUtil.displayErrorDialog(message("cachDsblErTtl"), message("endPtRmvErMsg")); } /* * Check end point selected for removal * is associated with Debugging. */ else if (waEndpoint.getName().equalsIgnoreCase(dbgEndptName)) { StringBuilder msg = new StringBuilder(message("dlgEPDel")); msg.append(message("dlgEPDel1")); msg.append(message("dlgEPDel2")); int choice = Messages.showYesNoDialog(msg.toString(), message("dlgDelEndPt1"), Messages.getQuestionIcon()); if (choice == Messages.YES) { waEndpoint.delete(); setModified(true); windowsAzureRole.setDebuggingEndpoint(null); } } /* * Endpoint associated with both SSL * and Session affinity */ else if (waEndpoint.isStickySessionEndpoint() && waEndpoint.isSSLEndpoint()) { int choice = Messages.showOkCancelDialog(message("bothDelMsg"), message("dlgDelEndPt1"), Messages.getQuestionIcon()); if (choice == Messages.OK) { setModified(true); if (waEndpoint.getEndPointType().equals(WindowsAzureEndpointType.Input)) { windowsAzureRole.setSessionAffinityInputEndpoint(null); windowsAzureRole.setSslOffloading(null, null); waEndpoint.delete(); } else { windowsAzureRole.setSessionAffinityInputEndpoint(null); windowsAzureRole.setSslOffloading(null, null); } } } /* * Check end point selected for removal * is associated with Load balancing * i.e (HTTP session affinity). */ else if (waEndpoint.isStickySessionEndpoint()) { int choice = Messages.showOkCancelDialog(message("ssnAffDelMsg"), message("dlgDelEndPt1"), Messages.getQuestionIcon()); if (choice == Messages.OK) { setModified(true); if (waEndpoint.getEndPointType().equals(WindowsAzureEndpointType.Input)) { windowsAzureRole.setSessionAffinityInputEndpoint(null); waEndpoint.delete(); } else { windowsAzureRole.setSessionAffinityInputEndpoint(null); } } } /* * Endpoint associated with SSL */ else if (waEndpoint.isSSLEndpoint()) { int choice = Messages.showOkCancelDialog(message("sslDelMsg"), message("dlgDelEndPt1"), Messages.getQuestionIcon()); if (choice == Messages.OK) { setModified(true); if (waEndpoint.getEndPointType().equals(WindowsAzureEndpointType.Input)) { windowsAzureRole.setSslOffloading(null, null); waEndpoint.delete(); } else { windowsAzureRole.setSslOffloading(null, null); } } } /* * Endpoint associated with SSL redirection. */ else if (waEndpoint.isSSLRedirectEndPoint()) { int choice = Messages.showOkCancelDialog(message("sslRedirectDelMsg"), message("dlgDelEndPt1"), Messages.getQuestionIcon()); if (choice == Messages.OK) { windowsAzureRole.deleteSslOffloadingRedirectionEndpoint(); setModified(true); } } /* * Normal end point. */ else { int choice = Messages.showOkCancelDialog(message("dlgDelEndPt2"), message("dlgDelEndPt1"), Messages.getQuestionIcon()); if (choice == Messages.OK) { setModified(true); waEndpoint.delete(); } } } catch (WindowsAzureInvalidProjectOperationException e) { PluginUtil.displayErrorDialogAndLog(message("adRolErrMsgBox1") + message("adRolErrMsgBox2"), message("adRolErrTitle"), e); } } @Override public JComponent getPanel() { return contentPane; } @Override public String getDisplayName() { return message("cmhLblEndPts"); } @Override public boolean doOKAction() { try { apply(); } catch (ConfigurationException e) { PluginUtil.displayErrorDialogAndLog(e.getTitle(), e.getMessage(), e); return false; } return true; } @Override public String getSelectedValue() { return null; } @Override public ValidationInfo doValidate() { return null; } @Nullable @Override public String getHelpTopic() { return "windows_azure_endpoint_page"; } @Nullable @Override public JComponent createComponent() { return contentPane; } @Override public void apply() throws ConfigurationException { try { if (isModified()) { waProjManager.save(); setModified(false); } LocalFileSystem.getInstance().findFileByPath(PluginUtil.getModulePath(module)).refresh(true, true); } catch (WindowsAzureInvalidProjectOperationException e) { throw new ConfigurationException(message("adRolErrMsgBox1") + message("adRolErrMsgBox2"), message("adRolErrTitle")); } } @Override public void reset() { setModified(false); } @Override public void disposeUIResources() { } @NotNull @Override public String getId() { return getDisplayName(); } @Nullable @Override public Runnable enableSearch(String option) { return null; } private void setEndpointType(WindowsAzureEndpoint endpoint, WindowsAzureEndpointType type, String prvPort, String pubPort) throws WindowsAzureInvalidProjectOperationException { if (windowsAzureRole.isValidEndpoint(endpoint.getName(), type, prvPort, pubPort)) { endpoint.setPrivatePort(prvPort); setModified(true); endpoint.setEndPointType(type); } else { Messages.showInfoMessage(message("changeErr"), message("dlgTypeTitle")); } } private final ColumnInfo<WindowsAzureEndpoint, String> NAME = new ColumnInfo<WindowsAzureEndpoint, String>( message("dlgColName")) { public String valueOf(WindowsAzureEndpoint object) { return object.getName(); } /** * Handles the modification of endpoint name. * * @param endpoint : the endpoint being modified. * @param endptName : new value for endpoint name. */ @Override public void setValue(WindowsAzureEndpoint endpoint, String endptName) { // Validate endpoint name /* * Check endpoint name contain * alphanumeric and underscore characters only. * Starts with alphabet. */ if (WAEclipseHelperMethods.isAlphaNumericUnderscore(endptName)) { try { boolean isValid = windowsAzureRole.isAvailableEndpointName(endptName, endpoint.getEndPointType()); /* * Check already used endpoint name is given. */ if (isValid || endptName.equalsIgnoreCase(endpoint.getName())) { endpoint.setName(endptName); setModified(true); } else { PluginUtil.displayErrorDialog(message("dlgInvdEdPtName1"), message("dlgInvdEdPtName2")); } } catch (WindowsAzureInvalidProjectOperationException e) { PluginUtil.displayErrorDialogAndLog(message("adRolErrTitle"), message("adRolErrMsgBox1") + message("adRolErrMsgBox2"), e); } } else { PluginUtil.displayErrorDialog(message("dlgInvdEdPtName1"), message("enPtAlphNuMsg")); } } }; private final ColumnInfo<WindowsAzureEndpoint, WindowsAzureEndpointType> TYPE = new ColumnInfo<WindowsAzureEndpoint, WindowsAzureEndpointType>( message("dlgColType")) { public WindowsAzureEndpointType valueOf(WindowsAzureEndpoint object) { try { return object.getEndPointType(); } catch (WindowsAzureInvalidProjectOperationException e) { //display error message if any exception occurs while //reading role data PluginUtil.displayErrorDialogAndLog(message("rolsErr"), message("adRolErrMsgBox1") + message("adRolErrMsgBox2"), e); return null; } } @Override public TableCellEditor getEditor(final WindowsAzureEndpoint endpoint) { return ComboBoxTableCellEditor.INSTANCE; } /** * Handles the modification of endpoint type. * * @param endpoint : the endpoint being modified. * @param type : new value for endpoint type. */ @Override public void setValue(WindowsAzureEndpoint endpoint, WindowsAzureEndpointType type) { try { WindowsAzureEndpointType oldType = endpoint.getEndPointType(); String endpointName = endpoint.getName(); String prvPort = endpoint.getPrivatePort(); String pubPort = endpoint.getPort(); if (WindowsAzureEndpointType.Input == type) { // User changed type to Input /* * While changing type from Internal * if private port is in the form of range, * then assign minimum of that range * as a private port because private port * range is not valid for other types of endpoints. */ if (oldType.equals(WindowsAzureEndpointType.Internal)) { if (prvPort.contains("-")) { String[] portRange = prvPort.split("-"); prvPort = portRange[0]; } pubPort = prvPort; } else if (oldType.equals(WindowsAzureEndpointType.InstanceInput) && pubPort.contains("-")) { String[] portRange = pubPort.split("-"); pubPort = portRange[0]; } setEndpointType(endpoint, WindowsAzureEndpointType.Input, prvPort, pubPort); } else if (WindowsAzureEndpointType.Internal == type) { // User changed type to Internal WindowsAzureEndpoint debugEndpt = windowsAzureRole.getDebuggingEndpoint(); String dbgEndptName = ""; if (debugEndpt != null) { dbgEndptName = debugEndpt.getName(); } Boolean disableDebug = false; if (endpointName.equalsIgnoreCase(dbgEndptName)) { int choice = Messages .showYesNoDialog( String.format("%s%s%s", message("dlgEPDel"), message("dlgEPChangeType"), message("dlgEPDel2")), message("dlgTypeTitle"), Messages.getQuestionIcon()); if (choice == Messages.YES) { disableDebug = true; } } setEndpointType(endpoint, WindowsAzureEndpointType.Internal, prvPort, ""); if (disableDebug) { windowsAzureRole.setDebuggingEndpoint(null); } } else if (WindowsAzureEndpointType.InstanceInput == type) { // User changed type to InstanceInput Boolean changeType = true; if (oldType.equals(WindowsAzureEndpointType.Internal)) { if (prvPort.contains("-")) { String[] portRange = prvPort.split("-"); prvPort = portRange[0]; } pubPort = prvPort; } else if (oldType.equals(WindowsAzureEndpointType.Input) && prvPort == null) { if (windowsAzureRole.isValidEndpoint(endpointName, WindowsAzureEndpointType.InstanceInput, pubPort, pubPort)) { prvPort = pubPort; } else { changeType = false; PluginUtil.displayWarningDialog(message("dlgTypeTitle"), String.format(message("inpInstTypeMsg"), pubPort)); } } if (changeType) { setEndpointType(endpoint, WindowsAzureEndpointType.InstanceInput, prvPort, pubPort); } } } catch (WindowsAzureInvalidProjectOperationException ex) { PluginUtil.displayErrorDialogAndLog(message("adRolErrTitle"), message("adRolErrMsgBox1") + message("adRolErrMsgBox2"), ex); } } }; private final ColumnInfo<WindowsAzureEndpoint, String> PUBLIC_PORT = new ColumnInfo<WindowsAzureEndpoint, String>( message("dlgColPubPort")) { public String valueOf(WindowsAzureEndpoint object) { return object.getPort(); } /** * Handles the modification of endpoint's public port. * * @param endpoint : the endpoint being modified. * @param port : new value for endpoint's public port. */ @Override public void setValue(WindowsAzureEndpoint endpoint, String port) { try { /* * Check only one '-' is present, * while specifying range for Instance end point. * If end point is Internal or Input then, * it will not satisfy if condition * and dash count will be zero. */ int dashCnt = 0; if (endpoint.getEndPointType().equals(WindowsAzureEndpointType.InstanceInput)) { dashCnt = StringUtils.countMatches(port.trim(), "-"); if (dashCnt > 1) { PluginUtil.displayErrorDialog(message("dlgInvldPort"), message("dashErrMsg")); } } if (dashCnt <= 1) { // Check for valid range 1 to 65535 Boolean isPortValid = true; try { /* * If public port contains '-' * then split string and * get two integer values out of it. * else directly check for value. */ if (dashCnt == 1) { String[] range = port.split("-"); int rngStart = Integer.parseInt(range[0]); int rngEnd = Integer.parseInt(range[1]); if (!(rngStart >= RANGE_MIN && rngStart <= RANGE_MAX && rngEnd >= RANGE_MIN && rngEnd <= RANGE_MAX)) { isPortValid = false; } } else { int portNum = Integer.parseInt(port.toString()); if (!(portNum >= RANGE_MIN && portNum <= RANGE_MAX)) { isPortValid = false; } } } catch (NumberFormatException e) { isPortValid = false; } if (isPortValid) { // Validate port boolean isValid = windowsAzureRole.isValidEndpoint(endpoint.getName(), endpoint.getEndPointType(), endpoint.getPrivatePort(), port); if (isValid) { endpoint.setPort(port); setModified(true); } else { PluginUtil.displayErrorDialog(message("dlgInvldPort"), message("dlgPortInUse")); } } else { PluginUtil.displayErrorDialog(message("dlgInvldPort"), message("rngErrMsg")); } } } catch (WindowsAzureInvalidProjectOperationException ex) { PluginUtil.displayErrorDialogAndLog(message("adRolErrTitle"), message("adRolErrMsgBox1") + message("adRolErrMsgBox2"), ex); } } }; private final ColumnInfo<WindowsAzureEndpoint, String> PRIVATE_PORT = new ColumnInfo<WindowsAzureEndpoint, String>( message("dlgColPrivatePort")) { public String valueOf(WindowsAzureEndpoint object) { return object.getPrivatePort(); } /** * Handles the modification of endpoint's private port. * * @param endpoint : the endpoint being modified. * @param port : new value for endpoint's private port. */ @Override public void setValue(WindowsAzureEndpoint endpoint, String port) { try { /* * Check only one '-' is present, * while specifying range for Internal end point. * If end point is Instance or Input then, * it will not satisfy if condition * and dash count will be zero. */ int dashCnt = 0; if (endpoint.getEndPointType().equals(WindowsAzureEndpointType.Internal)) { dashCnt = StringUtils.countMatches(port.toString().trim(), "-"); if (dashCnt > 1) { PluginUtil.displayErrorDialog(message("dlgInvldPort"), message("dashErrMsg")); } } if (dashCnt <= 1) { // Check for valid range 1 to 65535 Boolean isPortValid = true; try { /* * If public port contains '-' * then split string and * get two integer values out of it. * else directly check for value. */ if (dashCnt == 1) { String[] range = port.split("-"); int rngStart = Integer.parseInt(range[0]); int rngEnd = Integer.parseInt(range[1]); if (!(rngStart >= RANGE_MIN && rngStart <= RANGE_MAX && rngEnd >= RANGE_MIN && rngEnd <= RANGE_MAX)) { isPortValid = false; } } else { // no dash if (!((port.isEmpty() || port.equalsIgnoreCase("*")) && (endpoint.getEndPointType() .equals(WindowsAzureEndpointType.Internal) || endpoint.getEndPointType().equals(WindowsAzureEndpointType.Input)))) { int portNum = Integer.parseInt(port); if (!(portNum >= RANGE_MIN && portNum <= RANGE_MAX)) { isPortValid = false; } } } } catch (NumberFormatException e) { isPortValid = false; } if (isPortValid) { // Validate port if (port.isEmpty() || port.equalsIgnoreCase("*")) { port = null; } boolean isValid = windowsAzureRole.isValidEndpoint(endpoint.getName(), endpoint.getEndPointType(), port, endpoint.getPort()); if (isValid) { boolean canChange = true; boolean isDebugEnabled = false; boolean isSuspended = false; WindowsAzureEndpoint endPt = windowsAzureRole.getDebuggingEndpoint(); /* * check if the endpoint is associated with debug, * if yes then set isDebugEnabled to true and * store the suspended mode value. Disable debug endpoint * and then enable it with the modified endpoint. */ if (endPt != null && endpoint.getName().equalsIgnoreCase(endPt.getName())) { if (port == null) { PluginUtil.displayErrorDialog(message("dlgInvldPort"), message("dbgPort")); canChange = false; } else { isSuspended = windowsAzureRole.getStartSuspended(); windowsAzureRole.setDebuggingEndpoint(null); setModified(true); isDebugEnabled = true; } } if (canChange) { endpoint.setPrivatePort(port); setModified(true); if (isDebugEnabled) { windowsAzureRole.setDebuggingEndpoint(endpoint); windowsAzureRole.setStartSuspended(isSuspended); } } } else { PluginUtil.displayErrorDialog(message("dlgInvldPort"), message("dlgPortInUse")); } } else { PluginUtil.displayErrorDialog(message("dlgInvldPort"), message("rngErrMsg")); } } } catch (WindowsAzureInvalidProjectOperationException ex) { PluginUtil.displayErrorDialogAndLog(message("adRolErrTitle"), message("adRolErrMsgBox1") + message("adRolErrMsgBox2"), ex); } } }; private class EndpointsTableModel extends ListTableModel<WindowsAzureEndpoint> { private EndpointsTableModel(List<WindowsAzureEndpoint> listEndPoints) { super(new ColumnInfo[] { NAME, TYPE, PUBLIC_PORT, PRIVATE_PORT }, listEndPoints, 0); } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return true; } } }