From fa8f0f903cbe447933d46aa6cb0e7ca539a96f28 Mon Sep 17 00:00:00 2001 From: Zhaoxi Zhang Date: Sun, 30 Jul 2017 15:33:39 -0700 Subject: [PATCH 1/5] AWS Explorer --- .gitignore | 3 + aws-intellij-toolkit.iml | 12 +++ .../intellij/ui/explorer/ExplorerToolbar.form | 11 +++ .../intellij/ui/explorer/ExplorerToolbar.java | 82 ++++++++++++++++ .../ui/ui/widgets/AwsRegionPanel.form | 23 +++++ .../ui/ui/widgets/AwsRegionPanel.java | 55 +++++++++++ .../intellij/actions/UploadLambdaFunction.kt | 4 +- .../core/preferences/PreferenceConstants.kt | 8 ++ .../core/region/AwsDefaultRegionProvider.kt | 46 +++++++++ .../intellij/core/region/AwsRegion.kt | 39 ++++++++ .../core/region/AwsRegionChangeListener.kt | 8 ++ .../intellij/core/region/AwsRegionManager.kt | 67 +++++++++++++ .../lambda/explorer/AwsExplorerLambdaNode.kt | 41 ++++++++ .../intellij/s3/explorer/AwsExplorerS3Node.kt | 40 ++++++++ .../ui/explorer/AwsExplorerFactory.kt | 24 +++++ .../intellij/ui/explorer/AwsExplorerMain.kt | 1 + .../intellij/ui/explorer/AwsExplorerNode.kt | 96 +++++++++++++++++++ .../ui/explorer/AwsExplorerService.kt | 27 ++++++ .../explorer/AwsExplorerToolWindowFactory.kt | 6 +- .../ui/explorer/AwsExplorerTreeBuilder.kt | 21 ++++ .../ui/explorer/AwsExplorerTreeStructure.kt | 31 ++++++ src/main/resources/META-INF/plugin.xml | 8 +- 22 files changed, 649 insertions(+), 4 deletions(-) create mode 100644 aws-intellij-toolkit.iml create mode 100644 src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.form create mode 100644 src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.java create mode 100644 src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.form create mode 100644 src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java create mode 100644 src/main/kotlin/com/amazonaws/intellij/core/preferences/PreferenceConstants.kt create mode 100644 src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt create mode 100644 src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegion.kt create mode 100644 src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionChangeListener.kt create mode 100644 src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt create mode 100644 src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt create mode 100644 src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt create mode 100644 src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt create mode 100644 src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt create mode 100644 src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt create mode 100644 src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeBuilder.kt create mode 100644 src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeStructure.kt diff --git a/.gitignore b/.gitignore index 8e022fe9931..9e5bd01e993 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ out/ target/ /.idea/ +build/ +.DS_Store +.iml diff --git a/aws-intellij-toolkit.iml b/aws-intellij-toolkit.iml new file mode 100644 index 00000000000..4e58607b98d --- /dev/null +++ b/aws-intellij-toolkit.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.form b/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.form new file mode 100644 index 00000000000..b87ebf1d40c --- /dev/null +++ b/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.form @@ -0,0 +1,11 @@ + +
+ + + + + + + + +
diff --git a/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.java b/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.java new file mode 100644 index 00000000000..59540cdc836 --- /dev/null +++ b/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.java @@ -0,0 +1,82 @@ +package com.amazonaws.intellij.ui.explorer; + +import com.amazonaws.intellij.core.region.AwsDefaultRegionProvider; +import com.amazonaws.intellij.ui.ui.widgets.AwsRegionPanel; +import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.ide.util.treeView.NodeRenderer; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; +import com.intellij.ui.components.JBScrollPane; +import com.intellij.ui.components.panels.Wrapper; +import com.intellij.ui.treeStructure.Tree; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NonNls; + +import javax.annotation.Nonnull; +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; + +/** + * Created by zhaoxiz on 7/20/17. + */ +public class ExplorerToolbar { + private final AwsDefaultRegionProvider regionProvider; + private final Project project; + private AwsRegionPanel regionPanel; + private JPanel mainPanel; + private Wrapper wrapper; + + public ExplorerToolbar(@Nonnull Project project, @NonNls Wrapper wrapper) { + this.project = project; + this.regionProvider = AwsDefaultRegionProvider.getInstance(project); + this.wrapper = wrapper; + this.regionPanel = new AwsRegionPanel(regionProvider.getCurrentRegion()); + + regionPanel.addActionListener(e -> onAwsRegionComboSelected()); + onAwsRegionComboSelected(); + + mainPanel.add(regionPanel.getRegionPanel()); + } + + private void onAwsRegionComboSelected() { + String selectedRegion = regionPanel.getSelectedRegion(); + + DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode()); + JTree awsTree = createTree(); + + AwsExplorerTreeBuilder builder = new AwsExplorerTreeBuilder(awsTree, model, project, selectedRegion); + + Disposer.register(project, builder); + wrapper.setContent(new JBScrollPane(awsTree)); + + regionProvider.setCurrentRegion(selectedRegion); + } + + public JComponent getMainPanel() { + return mainPanel; + } + + private JTree createTree() { + Tree awsTree = new Tree(); + UIUtil.setLineStyleAngled(awsTree); + awsTree.setRootVisible(false); + awsTree.setAutoscrolls(true); + awsTree.setCellRenderer(new AwsTreeCellRenderer()); + return awsTree; + } + + private static class AwsTreeCellRenderer extends NodeRenderer { + @Override + public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + super.customizeCellRenderer(tree, value, selected, expanded, leaf, row, hasFocus); + if (value instanceof DefaultMutableTreeNode) { + DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) value; + if (treeNode.getUserObject() instanceof NodeDescriptor) { + NodeDescriptor descriptor = (NodeDescriptor) treeNode.getUserObject(); + setIcon(descriptor.getIcon()); + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.form b/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.form new file mode 100644 index 00000000000..06836232820 --- /dev/null +++ b/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.form @@ -0,0 +1,23 @@ + +
+ + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java b/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java new file mode 100644 index 00000000000..7e6d6313c22 --- /dev/null +++ b/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java @@ -0,0 +1,55 @@ +package com.amazonaws.intellij.ui.ui.widgets; + +import com.amazonaws.intellij.core.region.AwsRegion; +import com.amazonaws.intellij.core.region.AwsRegionManager; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionListener; + +/** + * Created by zhaoxiz on 7/28/17. + */ +public class AwsRegionPanel { + private JPanel regionPanel; + private com.intellij.openapi.ui.ComboBox regionCombo; + + public AwsRegionPanel(String defaultRegion) { + + regionCombo.setRenderer(new DefaultListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + label.setIcon(((AwsRegion) value).getIcon()); + return label; + } + }); + + for (AwsRegion region : AwsRegionManager.INSTANCE.getRegions()) { + regionCombo.addItem(region); + } + selectRegion(defaultRegion); + } + + public void addActionListener(ActionListener actionListener) { + regionCombo.addActionListener(actionListener); + } + + public JPanel getRegionPanel() { + return regionPanel; + } + + private void selectRegion(String regionId) { + for (AwsRegion region : AwsRegionManager.INSTANCE.getRegions()) { + if (region.getId().equals(regionId)) { + regionCombo.setSelectedItem(region); + break; + } + } + } + + public String getSelectedRegion() { + return ((AwsRegion) regionCombo.getSelectedItem()).getId(); + } + +} diff --git a/src/main/kotlin/com/amazonaws/intellij/actions/UploadLambdaFunction.kt b/src/main/kotlin/com/amazonaws/intellij/actions/UploadLambdaFunction.kt index a36d6e83374..454d2fa0579 100644 --- a/src/main/kotlin/com/amazonaws/intellij/actions/UploadLambdaFunction.kt +++ b/src/main/kotlin/com/amazonaws/intellij/actions/UploadLambdaFunction.kt @@ -39,13 +39,13 @@ class UploadLambdaFunction : AnAction() { val res = AwsResourceManager.getInstance(project).lambdaClient().invoke(invoke) JOptionPane.showMessageDialog(null, String(res.payload.array()), null, JOptionPane.PLAIN_MESSAGE, LAMBDA_SERVICE_ICON_LARGE) } - Notifications.Bus.notify(Notification("AWS Toolkit", "AWS Lambda Created", "${functionDetails.name} created run it", NotificationType.INFORMATION, notificationListener)) + Notifications.Bus.notify(Notification("AWS Toolkit", "AWS LAMBDA Created", "${functionDetails.name} created run it", NotificationType.INFORMATION, notificationListener)) } } uploadModal.show() } private fun handleError(msg: String) { - Notifications.Bus.notify(Notification("AWS Tookit", "Upload Lambda Failed", msg, NotificationType.ERROR)) + Notifications.Bus.notify(Notification("AWS Tookit", "Upload LAMBDA Failed", msg, NotificationType.ERROR)) } } \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/core/preferences/PreferenceConstants.kt b/src/main/kotlin/com/amazonaws/intellij/core/preferences/PreferenceConstants.kt new file mode 100644 index 00000000000..4c8d789b89d --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/core/preferences/PreferenceConstants.kt @@ -0,0 +1,8 @@ +package com.amazonaws.intellij.core.preferences + +/** + * Created by zhaoxiz on 7/21/17. + */ + +const val P_CURRENT_AWS_REGION = "com.amazonaws.intellij.currentAwsRegionId" +const val V_CURRENT_AWS_REGION = "us-west-2" \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt new file mode 100644 index 00000000000..ac7887642c9 --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt @@ -0,0 +1,46 @@ +package com.amazonaws.intellij.core.region + +import com.intellij.openapi.components.PersistentStateComponent +import com.intellij.openapi.components.ServiceManager +import com.intellij.openapi.components.State +import com.intellij.openapi.components.Storage +import com.intellij.openapi.project.Project +import com.intellij.util.xmlb.XmlSerializerUtil + +/** + * Created by zhaoxiz on 7/21/17. + */ +@State(name = "AwsDefaultRegionProvider", storages = arrayOf(Storage("aws.xml"))) +class AwsDefaultRegionProvider(): + PersistentStateComponent { + + val regionChangeListeners = mutableListOf() + var currentRegion: String = DEFAULT_REGION + get() = field ?: DEFAULT_REGION + set(value) { + val oldValue = field + field = value ?: DEFAULT_REGION + onCurrentRegionChanged(oldValue, field) + } + + override fun loadState(state: AwsDefaultRegionProvider) { + XmlSerializerUtil.copyBean(state, this) + } + + override fun getState(): AwsDefaultRegionProvider { + return this + } + + private fun onCurrentRegionChanged(oldValue: String, newValue: String) { + regionChangeListeners.forEach { it.onCurrentRegionChanged(oldValue, newValue) } + } + + companion object { + + private const val DEFAULT_REGION = "us-west-2" + @JvmStatic + fun getInstance(project: Project): AwsDefaultRegionProvider { + return ServiceManager.getService(project, AwsDefaultRegionProvider::class.java) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegion.kt b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegion.kt new file mode 100644 index 00000000000..ff817af8e2e --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegion.kt @@ -0,0 +1,39 @@ +package com.amazonaws.intellij.core.region + +import com.amazonaws.regions.Region +import com.amazonaws.regions.RegionUtils +import com.amazonaws.regions.Regions +import com.intellij.openapi.util.IconLoader +import javax.swing.Icon + +/** + * Created by zhaoxiz on 7/20/17. + */ +data class AwsRegion(val id: String, val name: String, val icon: Icon) { + private companion object { + val UNKNOWN_REGION_FLAG = "/icons/aws-box.gif" + val REGION_FLAG_MAPPING = hashMapOf( + "us-east-1" to "/icons/flags/us.png", + "us-east-2" to "/icons/flags/us.png", + "us-west-1" to "/icons/flags/us.png", + "us-west-2" to "/icons/flags/us.png", + "ap-northeast-1" to "/icons/flags/japan.png", + "ap-southeast-1" to "/icons/flags/singapore.png", + "ap-southeast-2" to "/icons/flags/australia.png", + "eu-west-1" to "/icons/flags/ireland.png", + "eu-central-1" to "/icons/flags/eu.png", + "eu-west-2" to "/icons/flags/eu.png" + ) + } + + constructor(id: String, name: String): + this(id, name, IconLoader.getIcon (if (REGION_FLAG_MAPPING.get(id) == null) UNKNOWN_REGION_FLAG else REGION_FLAG_MAPPING.get(id) as String)) + + override fun toString(): String { + return name + } + + fun isServiceSupported(serviceId: String): Boolean { + return RegionUtils.getRegion(id).isServiceSupported(serviceId) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionChangeListener.kt b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionChangeListener.kt new file mode 100644 index 00000000000..a69c6cfd164 --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionChangeListener.kt @@ -0,0 +1,8 @@ +package com.amazonaws.intellij.core.region + +/** + * Created by zhaoxiz on 7/24/17. + */ +interface AwsRegionChangeListener { + fun onCurrentRegionChanged(oldValue: String, newValue: String) +} \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt new file mode 100644 index 00000000000..eb59c78ba50 --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt @@ -0,0 +1,67 @@ +package com.amazonaws.intellij.core.region + +import com.amazonaws.partitions.model.Partition +import com.amazonaws.partitions.model.Partitions +import com.amazonaws.partitions.model.Region +import com.amazonaws.regions.RegionUtils +import com.amazonaws.util.IOUtils +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.DeserializationFeature +import com.fasterxml.jackson.databind.MapperFeature +import com.fasterxml.jackson.databind.ObjectMapper +import java.io.IOException +import java.io.InputStream + +/** + * Created by zhaoxiz on 7/20/17. + */ +object AwsRegionManager { + + private val regions = mutableListOf() + + init { + val partitions = PartitionLoader.build() + if (partitions != null && partitions.partitions != null) { + for (partition: Partition in partitions.partitions) for ((key, value) in partition.regions) { + regions.add(AwsRegion(key, value.description)) + } + } + } + + fun getRegions(): List { + return regions + } + + fun isServiceSupported(region: String, serviceName: String): Boolean { + return RegionUtils.getRegion(region).isServiceSupported(serviceName) + } +} + +private object PartitionLoader { + //TODO This endpoint file should be update-to-date file + private const val JAVA_SDK_PARTITION_RESOURCE_PATH = "com/amazonaws/partitions/endpoints.json" + + private val mapper = ObjectMapper() + .disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS) + .disable(MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .enable(JsonParser.Feature.ALLOW_COMMENTS) + + fun build(): Partitions? { + val inputStream = PartitionLoader::class.java.classLoader.getResourceAsStream(JAVA_SDK_PARTITION_RESOURCE_PATH) + + return loadPartitionsFromStream(inputStream, JAVA_SDK_PARTITION_RESOURCE_PATH) + } + + private fun loadPartitionsFromStream(stream: InputStream, location: String): Partitions? { + return try { + mapper.readValue(stream, Partitions::class.java) + } catch (e: IOException) { + //TODO How do we report this error when failed to load the endpoints + println("Error: failed to load file from $location !") + null + } finally { + IOUtils.closeQuietly(stream, null) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt b/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt new file mode 100644 index 00000000000..a9cce48f8c1 --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt @@ -0,0 +1,41 @@ +package com.amazonaws.intellij.lambda.explorer + +import com.amazonaws.intellij.ui.LAMBDA_SERVICE_ICON +import com.amazonaws.intellij.ui.SQS_QUEUE_ICON +import com.amazonaws.intellij.ui.explorer.AwsExplorerNode +import com.amazonaws.intellij.ui.explorer.AwsExplorerServiceRootNode +import com.amazonaws.services.lambda.AWSLambda +import com.amazonaws.services.lambda.AWSLambdaClientBuilder +import com.amazonaws.services.lambda.model.FunctionConfiguration +import com.intellij.ide.projectView.PresentationData +import com.intellij.ide.util.treeView.AbstractTreeNode +import com.intellij.openapi.project.Project + +/** + * Created by zhaoxiz on 7/28/17. + */ +class AwsExplorerLambdaRootNode(project: Project?, region: String): + AwsExplorerServiceRootNode(project, "AWS Lambda", region, LAMBDA_SERVICE_ICON) { + + private var client: AWSLambda = AWSLambdaClientBuilder.standard() + .withRegion(region) + .build() + + override fun loadResources(): MutableList { + return client.listFunctions().functions + } + + override fun mapResourceToNode(resource: FunctionConfiguration) = AwsExplorerFunctionNode(project, resource, region) +} + +class AwsExplorerFunctionNode(project: Project?, private val function: FunctionConfiguration, region: String): + AwsExplorerNode(project, function, region, SQS_QUEUE_ICON) { //TODO replace to Function icon + + override fun getChildren(): MutableCollection> { + return mutableListOf() + } + + override fun toString(): String { + return function.functionName + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt b/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt new file mode 100644 index 00000000000..dab43790a52 --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt @@ -0,0 +1,40 @@ +package com.amazonaws.intellij.s3.explorer + +import com.amazonaws.intellij.ui.S3_BUCKET_ICON +import com.amazonaws.intellij.ui.S3_SERVICE_ICON +import com.amazonaws.intellij.ui.explorer.AwsExplorerNode +import com.amazonaws.intellij.ui.explorer.AwsExplorerServiceRootNode +import com.amazonaws.services.s3.AmazonS3 +import com.amazonaws.services.s3.AmazonS3ClientBuilder +import com.amazonaws.services.s3.model.Bucket +import com.intellij.ide.util.treeView.AbstractTreeNode +import com.intellij.openapi.project.Project + +/** + * Created by zhaoxiz on 7/28/17. + */ +class AwsExplorerS3RootNode(project: Project?, region: String): + AwsExplorerServiceRootNode(project, "Amazon S3", region, S3_SERVICE_ICON) { + + private var client: AmazonS3 = AmazonS3ClientBuilder.standard() + .withRegion(region) + .build() + + override fun loadResources(): MutableList { + return client.listBuckets() + } + + override fun mapResourceToNode(resource: Bucket) = AwsExplorerBucketNode(project, resource, region) +} + +class AwsExplorerBucketNode(project: Project?, private val bucket: Bucket, region: String): + AwsExplorerNode(project, bucket, region, S3_BUCKET_ICON) { + + override fun getChildren(): MutableCollection> { + return mutableListOf() + } + + override fun toString(): String { + return bucket.name + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt new file mode 100644 index 00000000000..52f08cc92a2 --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt @@ -0,0 +1,24 @@ +package com.amazonaws.intellij.ui.explorer + +import com.intellij.openapi.project.DumbAware +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.SimpleToolWindowPanel +import com.intellij.openapi.wm.ToolWindow +import com.intellij.openapi.wm.ToolWindowFactory +import com.intellij.ui.components.panels.Wrapper + +/** + * Created by zhaoxiz on 7/19/17. + */ +class AwsExplorerFactory : ToolWindowFactory, DumbAware { + + override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) { + val simpleToolWindowPanel = SimpleToolWindowPanel(true, false) + val wrapperPane = Wrapper() + + simpleToolWindowPanel.setToolbar(ExplorerToolbar(project, wrapperPane).mainPanel) + simpleToolWindowPanel.setContent(wrapperPane) + toolWindow.component.parent.add(simpleToolWindowPanel) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerMain.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerMain.kt index 5e85b14c114..453bf2dc7d6 100644 --- a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerMain.kt +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerMain.kt @@ -53,6 +53,7 @@ class AwsExplorerMainView(eventHandler: AwsExplorerMainEventHandler, s3DetailsVi main.leftComponent.preferredSize = Dimension(500, 100) main.dividerSize = 2 add(main) + add(resources) } fun updateResources(root: TreeNode) { diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt new file mode 100644 index 00000000000..9a0aef825f5 --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt @@ -0,0 +1,96 @@ +package com.amazonaws.intellij.ui.explorer + +import com.amazonaws.intellij.core.region.AwsRegionManager +import com.amazonaws.intellij.ui.AWS_ICON +import com.intellij.ide.projectView.PresentationData +import com.intellij.ide.util.treeView.AbstractTreeNode +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.ClearableLazyValue +import com.intellij.ui.SimpleTextAttributes +import javax.swing.Icon + +/** + * Created by zhaoxiz on 7/27/17. + */ + +abstract class AwsExplorerNode(project: Project?, value: T, val region: String, val awsIcon: Icon?): + AbstractTreeNode(project, value) { + + override fun update(presentation: PresentationData?) { + presentation?.setIcon(awsIcon) + } + + override fun toString() = value.toString() +} + + +class AwsExplorerRootNode(project: Project?, region: String): + AwsExplorerNode(project, "ROOT", region, AWS_ICON) { + + override fun getChildren(): MutableCollection> { + val childrenList = mutableListOf>() + AwsExplorerService.values() + .filter { AwsRegionManager.isServiceSupported(region, it.serviceId) } + .mapTo(childrenList) { it.buildServiceRoodNode(project, region) } + return childrenList + } +} + +abstract class AwsExplorerServiceRootNode(project: Project?, value: String, region: String, awsIcon: Icon): + AwsExplorerNode(project, value, region, awsIcon) { + val cache: ClearableLazyValue>> + + init { + cache = object : ClearableLazyValue>>() { + override fun compute(): MutableCollection> { + return try { + val resources = loadResources() + if (resources.isEmpty()) + // Return EmptyNode as the single node of the list + mutableListOf(AwsExplorerEmptyNode(project, region)).toMutableList() + else + resources.map { mapResourceToNode(it) }.toMutableList() + } catch (e: Exception) { + // Return the ErrorNode as the single Node of the list + mutableListOf(AwsExplorerErrorNode(project, e, region)).toMutableList() + } + } + } + } + + override fun getChildren(): MutableCollection> { + return cache.value + } + + // This method may throw RuntimeException, must handle it + abstract fun loadResources(): MutableList + + abstract fun mapResourceToNode(resource: Resource): AwsExplorerNode +} + +class AwsExplorerErrorNode(project: Project?, exception: Exception, region: String): AwsExplorerNode(project, exception, region, null) { + override fun getChildren(): MutableCollection> { + return mutableListOf() + } + + override fun toString(): String { + return "Error Loading Resources..." + } + + override fun update(presentation: PresentationData?) { + super.update(presentation) + presentation?.tooltip = value.message + presentation?.addText(toString(), SimpleTextAttributes.ERROR_ATTRIBUTES) + } +} + +class AwsExplorerEmptyNode(project: Project?, region: String): AwsExplorerNode(project, "empty", region, null) { + override fun getChildren(): MutableCollection> { + return mutableListOf() + } + + override fun update(presentation: PresentationData?) { + super.update(presentation) + presentation?.addText(toString(), SimpleTextAttributes.GRAYED_ATTRIBUTES) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt new file mode 100644 index 00000000000..4f3b3c7b107 --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt @@ -0,0 +1,27 @@ +package com.amazonaws.intellij.ui.explorer + +import com.amazonaws.intellij.lambda.explorer.AwsExplorerLambdaRootNode +import com.amazonaws.intellij.s3.explorer.AwsExplorerS3RootNode +import com.amazonaws.services.lambda.AWSLambda +import com.amazonaws.services.s3.AmazonS3 +import com.intellij.ide.util.treeView.AbstractTreeNode +import com.intellij.openapi.project.Project + +/** + * Created by zhaoxiz on 7/27/17. + */ +enum class AwsExplorerService(val serviceId: String) { + S3(AmazonS3.ENDPOINT_PREFIX) { + override fun buildServiceRoodNode(project: Project?, region: String): AwsExplorerS3RootNode { + return AwsExplorerS3RootNode(project, region) + } + }, + LAMBDA(AWSLambda.ENDPOINT_PREFIX) { + override fun buildServiceRoodNode(project: Project?, region: String): AwsExplorerLambdaRootNode { + return AwsExplorerLambdaRootNode(project, region) + } + }, + ; + + abstract fun buildServiceRoodNode(project: Project?, region: String): AbstractTreeNode +} \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerToolWindowFactory.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerToolWindowFactory.kt index b6d3e6954da..0df59d2442c 100644 --- a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerToolWindowFactory.kt +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerToolWindowFactory.kt @@ -28,7 +28,11 @@ interface HasIcon { val icon: Icon } -class AwsTreeNode(override val icon: Icon, val value: T, toName: (T) -> String = { it.toString() }) : HasIcon, DefaultMutableTreeNode(toName(value)) +open class AwsTreeNode( + override val icon: Icon, + val value: T, + toName: (T) -> String = { it.toString() } +) : HasIcon, DefaultMutableTreeNode(toName(value)) class TreeCellRenderer : DefaultTreeCellRenderer() { override fun getTreeCellRendererComponent(tree: JTree?, value: Any?, sel: Boolean, expanded: Boolean, leaf: Boolean, row: Int, hasFocus: Boolean): Component { diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeBuilder.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeBuilder.kt new file mode 100644 index 00000000000..0a6be5493c1 --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeBuilder.kt @@ -0,0 +1,21 @@ +package com.amazonaws.intellij.ui.explorer + +import com.intellij.ide.util.treeView.AbstractTreeBuilder +import com.intellij.ide.util.treeView.NodeDescriptor +import com.intellij.openapi.project.Project +import javax.swing.JTree +import javax.swing.tree.DefaultTreeModel + +/** + * Created by zhaoxiz on 7/27/17. + */ + +class AwsExplorerTreeBuilder(tree: JTree, treeModel: DefaultTreeModel, private val project: Project, private val region: String): + AbstractTreeBuilder(tree, treeModel, AwsExplorerTreeStructure(project, region), null, false) { + + init { + initRootNode() + } + + override fun isAlwaysShowPlus(descriptor: NodeDescriptor<*>?) = descriptor is AwsExplorerServiceRootNode<*> +} diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeStructure.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeStructure.kt new file mode 100644 index 00000000000..216775a18e7 --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeStructure.kt @@ -0,0 +1,31 @@ +package com.amazonaws.intellij.ui.explorer + +import com.intellij.ide.projectView.TreeStructureProvider +import com.intellij.ide.util.treeView.AbstractTreeStructureBase +import com.intellij.openapi.project.Project + +/** + * Created by zhaoxiz on 7/27/17. + */ + +class AwsExplorerTreeStructure(project: Project, val region: String) : AbstractTreeStructureBase(project) { + + override fun getProviders(): List? { + return emptyList() + } + + override fun getRootElement(): AwsExplorerRootNode { + return AwsExplorerRootNode(myProject, region) + } + + override fun commit() { + } + + override fun hasSomethingToCommit(): Boolean { + return false + } + + override fun isToBuildChildrenInBackground(element: Any?): Boolean { + return true + } +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 2bf67fcaafc..1952e0e0354 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -28,13 +28,19 @@ + + + + + @@ -50,4 +56,4 @@ - \ No newline at end of file + From f4bc62cb28699b775adb274207ae942adc0c02df Mon Sep 17 00:00:00 2001 From: Zhaoxi Zhang Date: Mon, 7 Aug 2017 12:49:44 -0700 Subject: [PATCH 2/5] Address feedback. --- .gitignore | 2 +- aws-intellij-toolkit.iml | 12 ------------ .../intellij/ui/explorer/ExplorerToolbar.java | 3 +-- .../ui/ui/widgets/AwsRegionPanel.java | 19 +++++++++---------- .../intellij/actions/UploadLambdaFunction.kt | 4 ++-- .../core/preferences/PreferenceConstants.kt | 2 +- .../core/region/AwsDefaultRegionProvider.kt | 10 ---------- .../core/region/AwsRegionChangeListener.kt | 8 -------- .../lambda/explorer/AwsExplorerLambdaNode.kt | 2 +- .../intellij/ui/explorer/AwsExplorerNode.kt | 9 ++++++--- .../ui/explorer/AwsExplorerService.kt | 6 +++--- 11 files changed, 24 insertions(+), 53 deletions(-) delete mode 100644 aws-intellij-toolkit.iml delete mode 100644 src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionChangeListener.kt diff --git a/.gitignore b/.gitignore index 9e5bd01e993..40fb6ddd7eb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ target/ /.idea/ build/ .DS_Store -.iml +*.iml diff --git a/aws-intellij-toolkit.iml b/aws-intellij-toolkit.iml deleted file mode 100644 index 4e58607b98d..00000000000 --- a/aws-intellij-toolkit.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.java b/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.java index 59540cdc836..c66307b5c11 100644 --- a/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.java +++ b/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.java @@ -12,7 +12,6 @@ import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; -import javax.annotation.Nonnull; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; @@ -27,7 +26,7 @@ public class ExplorerToolbar { private JPanel mainPanel; private Wrapper wrapper; - public ExplorerToolbar(@Nonnull Project project, @NonNls Wrapper wrapper) { + public ExplorerToolbar(@NonNls Project project, @NonNls Wrapper wrapper) { this.project = project; this.regionProvider = AwsDefaultRegionProvider.getInstance(project); this.wrapper = wrapper; diff --git a/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java b/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java index 7e6d6313c22..a9e2da1881d 100644 --- a/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java +++ b/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java @@ -2,17 +2,19 @@ import com.amazonaws.intellij.core.region.AwsRegion; import com.amazonaws.intellij.core.region.AwsRegionManager; +import com.intellij.openapi.ui.ComboBox; import javax.swing.*; import java.awt.*; import java.awt.event.ActionListener; +import java.util.Optional; /** * Created by zhaoxiz on 7/28/17. */ public class AwsRegionPanel { private JPanel regionPanel; - private com.intellij.openapi.ui.ComboBox regionCombo; + private ComboBox regionCombo; public AwsRegionPanel(String defaultRegion) { @@ -25,9 +27,7 @@ public Component getListCellRendererComponent(JList list, Object value, int inde } }); - for (AwsRegion region : AwsRegionManager.INSTANCE.getRegions()) { - regionCombo.addItem(region); - } + AwsRegionManager.INSTANCE.getRegions().forEach((region)-> {regionCombo.addItem(region);}); selectRegion(defaultRegion); } @@ -40,15 +40,14 @@ public JPanel getRegionPanel() { } private void selectRegion(String regionId) { - for (AwsRegion region : AwsRegionManager.INSTANCE.getRegions()) { - if (region.getId().equals(regionId)) { - regionCombo.setSelectedItem(region); - break; - } - } + + AwsRegionManager.INSTANCE.getRegions().stream().filter((region) -> region.getId().equals(regionId)) + .findFirst().ifPresent((region) -> {regionCombo.setSelectedItem(region);}); + } public String getSelectedRegion() { + assert ((AwsRegion) regionCombo.getSelectedItem()) != null; return ((AwsRegion) regionCombo.getSelectedItem()).getId(); } diff --git a/src/main/kotlin/com/amazonaws/intellij/actions/UploadLambdaFunction.kt b/src/main/kotlin/com/amazonaws/intellij/actions/UploadLambdaFunction.kt index 454d2fa0579..a36d6e83374 100644 --- a/src/main/kotlin/com/amazonaws/intellij/actions/UploadLambdaFunction.kt +++ b/src/main/kotlin/com/amazonaws/intellij/actions/UploadLambdaFunction.kt @@ -39,13 +39,13 @@ class UploadLambdaFunction : AnAction() { val res = AwsResourceManager.getInstance(project).lambdaClient().invoke(invoke) JOptionPane.showMessageDialog(null, String(res.payload.array()), null, JOptionPane.PLAIN_MESSAGE, LAMBDA_SERVICE_ICON_LARGE) } - Notifications.Bus.notify(Notification("AWS Toolkit", "AWS LAMBDA Created", "${functionDetails.name} created run it", NotificationType.INFORMATION, notificationListener)) + Notifications.Bus.notify(Notification("AWS Toolkit", "AWS Lambda Created", "${functionDetails.name} created run it", NotificationType.INFORMATION, notificationListener)) } } uploadModal.show() } private fun handleError(msg: String) { - Notifications.Bus.notify(Notification("AWS Tookit", "Upload LAMBDA Failed", msg, NotificationType.ERROR)) + Notifications.Bus.notify(Notification("AWS Tookit", "Upload Lambda Failed", msg, NotificationType.ERROR)) } } \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/core/preferences/PreferenceConstants.kt b/src/main/kotlin/com/amazonaws/intellij/core/preferences/PreferenceConstants.kt index 4c8d789b89d..ee939b403b1 100644 --- a/src/main/kotlin/com/amazonaws/intellij/core/preferences/PreferenceConstants.kt +++ b/src/main/kotlin/com/amazonaws/intellij/core/preferences/PreferenceConstants.kt @@ -5,4 +5,4 @@ package com.amazonaws.intellij.core.preferences */ const val P_CURRENT_AWS_REGION = "com.amazonaws.intellij.currentAwsRegionId" -const val V_CURRENT_AWS_REGION = "us-west-2" \ No newline at end of file +const val V_DEFAULT_CURRENT_AWS_REGION = "us-west-2" \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt index ac7887642c9..847930dcaca 100644 --- a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt +++ b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt @@ -14,14 +14,8 @@ import com.intellij.util.xmlb.XmlSerializerUtil class AwsDefaultRegionProvider(): PersistentStateComponent { - val regionChangeListeners = mutableListOf() var currentRegion: String = DEFAULT_REGION get() = field ?: DEFAULT_REGION - set(value) { - val oldValue = field - field = value ?: DEFAULT_REGION - onCurrentRegionChanged(oldValue, field) - } override fun loadState(state: AwsDefaultRegionProvider) { XmlSerializerUtil.copyBean(state, this) @@ -31,10 +25,6 @@ class AwsDefaultRegionProvider(): return this } - private fun onCurrentRegionChanged(oldValue: String, newValue: String) { - regionChangeListeners.forEach { it.onCurrentRegionChanged(oldValue, newValue) } - } - companion object { private const val DEFAULT_REGION = "us-west-2" diff --git a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionChangeListener.kt b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionChangeListener.kt deleted file mode 100644 index a69c6cfd164..00000000000 --- a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionChangeListener.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.amazonaws.intellij.core.region - -/** - * Created by zhaoxiz on 7/24/17. - */ -interface AwsRegionChangeListener { - fun onCurrentRegionChanged(oldValue: String, newValue: String) -} \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt b/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt index a9cce48f8c1..3d2da4bf17a 100644 --- a/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt +++ b/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt @@ -17,7 +17,7 @@ import com.intellij.openapi.project.Project class AwsExplorerLambdaRootNode(project: Project?, region: String): AwsExplorerServiceRootNode(project, "AWS Lambda", region, LAMBDA_SERVICE_ICON) { - private var client: AWSLambda = AWSLambdaClientBuilder.standard() + private val client: AWSLambda = AWSLambdaClientBuilder.standard() .withRegion(region) .build() diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt index 9a0aef825f5..161545d66a7 100644 --- a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt @@ -2,6 +2,8 @@ package com.amazonaws.intellij.ui.explorer import com.amazonaws.intellij.core.region.AwsRegionManager import com.amazonaws.intellij.ui.AWS_ICON +import com.google.common.collect.ImmutableCollection +import com.google.common.collect.ImmutableList import com.intellij.ide.projectView.PresentationData import com.intellij.ide.util.treeView.AbstractTreeNode import com.intellij.openapi.project.Project @@ -27,12 +29,13 @@ abstract class AwsExplorerNode(project: Project?, value: T, val region: Strin class AwsExplorerRootNode(project: Project?, region: String): AwsExplorerNode(project, "ROOT", region, AWS_ICON) { - override fun getChildren(): MutableCollection> { + override fun getChildren(): ImmutableCollection> { val childrenList = mutableListOf>() AwsExplorerService.values() .filter { AwsRegionManager.isServiceSupported(region, it.serviceId) } - .mapTo(childrenList) { it.buildServiceRoodNode(project, region) } - return childrenList + .mapTo(childrenList) { it.buildServiceRootNode(project, region) } + + return ImmutableList.copyOf(childrenList) } } diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt index 4f3b3c7b107..d616246a533 100644 --- a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt @@ -12,16 +12,16 @@ import com.intellij.openapi.project.Project */ enum class AwsExplorerService(val serviceId: String) { S3(AmazonS3.ENDPOINT_PREFIX) { - override fun buildServiceRoodNode(project: Project?, region: String): AwsExplorerS3RootNode { + override fun buildServiceRootNode(project: Project?, region: String): AwsExplorerS3RootNode { return AwsExplorerS3RootNode(project, region) } }, LAMBDA(AWSLambda.ENDPOINT_PREFIX) { - override fun buildServiceRoodNode(project: Project?, region: String): AwsExplorerLambdaRootNode { + override fun buildServiceRootNode(project: Project?, region: String): AwsExplorerLambdaRootNode { return AwsExplorerLambdaRootNode(project, region) } }, ; - abstract fun buildServiceRoodNode(project: Project?, region: String): AbstractTreeNode + abstract fun buildServiceRootNode(project: Project?, region: String): AbstractTreeNode } \ No newline at end of file From 9105362642138057cdf1bac4f7f91f783c1aa126 Mon Sep 17 00:00:00 2001 From: Zhaoxi Zhang Date: Tue, 8 Aug 2017 00:26:06 -0700 Subject: [PATCH 3/5] Address a lot of feedback for kotlin. --- .../intellij/ui/explorer/ExplorerToolbar.form | 11 --- .../intellij/ui/explorer/ExplorerToolbar.java | 81 ------------------- .../ui/ui/widgets/AwsRegionPanel.form | 4 +- .../ui/ui/widgets/AwsRegionPanel.java | 18 ++--- .../intellij/aws/AwsResourceManager.kt | 2 +- .../core/preferences/PreferenceConstants.kt | 8 -- .../core/region/AwsDefaultRegionProvider.kt | 4 +- .../intellij/core/region/AwsRegion.kt | 6 +- .../intellij/core/region/AwsRegionManager.kt | 48 +++++------ .../lambda/explorer/AwsExplorerLambdaNode.kt | 9 ++- .../intellij/s3/explorer/AwsExplorerS3Node.kt | 8 +- .../ui/explorer/AwsExplorerFactory.kt | 2 +- .../intellij/ui/explorer/AwsExplorerNode.kt | 37 +++++---- .../ui/explorer/ExplorerToolWindow.kt | 58 +++++++++++++ 14 files changed, 123 insertions(+), 173 deletions(-) delete mode 100644 src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.form delete mode 100644 src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.java delete mode 100644 src/main/kotlin/com/amazonaws/intellij/core/preferences/PreferenceConstants.kt create mode 100644 src/main/kotlin/com/amazonaws/intellij/ui/explorer/ExplorerToolWindow.kt diff --git a/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.form b/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.form deleted file mode 100644 index b87ebf1d40c..00000000000 --- a/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.form +++ /dev/null @@ -1,11 +0,0 @@ - -
- - - - - - - - -
diff --git a/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.java b/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.java deleted file mode 100644 index c66307b5c11..00000000000 --- a/src/main/java/com/amazonaws/intellij/ui/explorer/ExplorerToolbar.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.amazonaws.intellij.ui.explorer; - -import com.amazonaws.intellij.core.region.AwsDefaultRegionProvider; -import com.amazonaws.intellij.ui.ui.widgets.AwsRegionPanel; -import com.intellij.ide.util.treeView.NodeDescriptor; -import com.intellij.ide.util.treeView.NodeRenderer; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Disposer; -import com.intellij.ui.components.JBScrollPane; -import com.intellij.ui.components.panels.Wrapper; -import com.intellij.ui.treeStructure.Tree; -import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NonNls; - -import javax.swing.*; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; - -/** - * Created by zhaoxiz on 7/20/17. - */ -public class ExplorerToolbar { - private final AwsDefaultRegionProvider regionProvider; - private final Project project; - private AwsRegionPanel regionPanel; - private JPanel mainPanel; - private Wrapper wrapper; - - public ExplorerToolbar(@NonNls Project project, @NonNls Wrapper wrapper) { - this.project = project; - this.regionProvider = AwsDefaultRegionProvider.getInstance(project); - this.wrapper = wrapper; - this.regionPanel = new AwsRegionPanel(regionProvider.getCurrentRegion()); - - regionPanel.addActionListener(e -> onAwsRegionComboSelected()); - onAwsRegionComboSelected(); - - mainPanel.add(regionPanel.getRegionPanel()); - } - - private void onAwsRegionComboSelected() { - String selectedRegion = regionPanel.getSelectedRegion(); - - DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode()); - JTree awsTree = createTree(); - - AwsExplorerTreeBuilder builder = new AwsExplorerTreeBuilder(awsTree, model, project, selectedRegion); - - Disposer.register(project, builder); - wrapper.setContent(new JBScrollPane(awsTree)); - - regionProvider.setCurrentRegion(selectedRegion); - } - - public JComponent getMainPanel() { - return mainPanel; - } - - private JTree createTree() { - Tree awsTree = new Tree(); - UIUtil.setLineStyleAngled(awsTree); - awsTree.setRootVisible(false); - awsTree.setAutoscrolls(true); - awsTree.setCellRenderer(new AwsTreeCellRenderer()); - return awsTree; - } - - private static class AwsTreeCellRenderer extends NodeRenderer { - @Override - public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { - super.customizeCellRenderer(tree, value, selected, expanded, leaf, row, hasFocus); - if (value instanceof DefaultMutableTreeNode) { - DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) value; - if (treeNode.getUserObject() instanceof NodeDescriptor) { - NodeDescriptor descriptor = (NodeDescriptor) treeNode.getUserObject(); - setIcon(descriptor.getIcon()); - } - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.form b/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.form index 06836232820..f3e61adc58e 100644 --- a/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.form +++ b/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.form @@ -1,8 +1,8 @@
- + - + diff --git a/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java b/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java index a9e2da1881d..89369b9efa8 100644 --- a/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java +++ b/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java @@ -3,6 +3,7 @@ import com.amazonaws.intellij.core.region.AwsRegion; import com.amazonaws.intellij.core.region.AwsRegionManager; import com.intellij.openapi.ui.ComboBox; +import com.intellij.ui.CollectionComboBoxModel; import javax.swing.*; import java.awt.*; @@ -15,9 +16,9 @@ public class AwsRegionPanel { private JPanel regionPanel; private ComboBox regionCombo; + private final CollectionComboBoxModel regionModel = new CollectionComboBoxModel<>(); public AwsRegionPanel(String defaultRegion) { - regionCombo.setRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { @@ -27,7 +28,9 @@ public Component getListCellRendererComponent(JList list, Object value, int inde } }); - AwsRegionManager.INSTANCE.getRegions().forEach((region)-> {regionCombo.addItem(region);}); + regionCombo.setModel(regionModel); + + AwsRegionManager.INSTANCE.getRegions().forEach(regionModel::add); selectRegion(defaultRegion); } @@ -40,15 +43,12 @@ public JPanel getRegionPanel() { } private void selectRegion(String regionId) { - AwsRegionManager.INSTANCE.getRegions().stream().filter((region) -> region.getId().equals(regionId)) - .findFirst().ifPresent((region) -> {regionCombo.setSelectedItem(region);}); - + .findFirst().ifPresent(regionModel::setSelectedItem); } public String getSelectedRegion() { - assert ((AwsRegion) regionCombo.getSelectedItem()) != null; - return ((AwsRegion) regionCombo.getSelectedItem()).getId(); + assert regionModel.getSelected() != null; + return regionModel.getSelected().getId(); } - -} +} \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/aws/AwsResourceManager.kt b/src/main/kotlin/com/amazonaws/intellij/aws/AwsResourceManager.kt index 9cb3d5a8929..89e66c43a3f 100644 --- a/src/main/kotlin/com/amazonaws/intellij/aws/AwsResourceManager.kt +++ b/src/main/kotlin/com/amazonaws/intellij/aws/AwsResourceManager.kt @@ -40,7 +40,7 @@ class AwsResourceBundle internal constructor() : S3ClientProvider, LambdaClientP } private class AwsResources(val region: String) { - val s3Client: AmazonS3 = AmazonS3Client() //AmazonS3ClientBuilder.standard().withRegion(region).build() + val s3Client: AmazonS3 = AmazonS3Client() //AmazonS3ClientBuilder.standard().withRegion(region).parse() val lambdaClient: AWSLambda = AWSLambdaClientBuilder.standard().withRegion(region).build() val iamClient: AmazonIdentityManagement = AmazonIdentityManagementClientBuilder.standard().withRegion(region).build() } diff --git a/src/main/kotlin/com/amazonaws/intellij/core/preferences/PreferenceConstants.kt b/src/main/kotlin/com/amazonaws/intellij/core/preferences/PreferenceConstants.kt deleted file mode 100644 index ee939b403b1..00000000000 --- a/src/main/kotlin/com/amazonaws/intellij/core/preferences/PreferenceConstants.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.amazonaws.intellij.core.preferences - -/** - * Created by zhaoxiz on 7/21/17. - */ - -const val P_CURRENT_AWS_REGION = "com.amazonaws.intellij.currentAwsRegionId" -const val V_DEFAULT_CURRENT_AWS_REGION = "us-west-2" \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt index 847930dcaca..bec71ef5fa6 100644 --- a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt +++ b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt @@ -13,9 +13,7 @@ import com.intellij.util.xmlb.XmlSerializerUtil @State(name = "AwsDefaultRegionProvider", storages = arrayOf(Storage("aws.xml"))) class AwsDefaultRegionProvider(): PersistentStateComponent { - var currentRegion: String = DEFAULT_REGION - get() = field ?: DEFAULT_REGION override fun loadState(state: AwsDefaultRegionProvider) { XmlSerializerUtil.copyBean(state, this) @@ -26,8 +24,8 @@ class AwsDefaultRegionProvider(): } companion object { - private const val DEFAULT_REGION = "us-west-2" + @JvmStatic fun getInstance(project: Project): AwsDefaultRegionProvider { return ServiceManager.getService(project, AwsDefaultRegionProvider::class.java) diff --git a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegion.kt b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegion.kt index ff817af8e2e..f0479fa8392 100644 --- a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegion.kt +++ b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegion.kt @@ -9,10 +9,10 @@ import javax.swing.Icon /** * Created by zhaoxiz on 7/20/17. */ -data class AwsRegion(val id: String, val name: String, val icon: Icon) { +data class AwsRegion private constructor(val id: String, val name: String, val icon: Icon) { private companion object { val UNKNOWN_REGION_FLAG = "/icons/aws-box.gif" - val REGION_FLAG_MAPPING = hashMapOf( + val REGION_FLAG_MAPPING = mapOf( "us-east-1" to "/icons/flags/us.png", "us-east-2" to "/icons/flags/us.png", "us-west-1" to "/icons/flags/us.png", @@ -27,7 +27,7 @@ data class AwsRegion(val id: String, val name: String, val icon: Icon) { } constructor(id: String, name: String): - this(id, name, IconLoader.getIcon (if (REGION_FLAG_MAPPING.get(id) == null) UNKNOWN_REGION_FLAG else REGION_FLAG_MAPPING.get(id) as String)) + this(id, name, IconLoader.getIcon (REGION_FLAG_MAPPING.getOrDefault(id, UNKNOWN_REGION_FLAG))) override fun toString(): String { return name diff --git a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt index eb59c78ba50..487a4757497 100644 --- a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt +++ b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt @@ -1,14 +1,16 @@ package com.amazonaws.intellij.core.region -import com.amazonaws.partitions.model.Partition import com.amazonaws.partitions.model.Partitions -import com.amazonaws.partitions.model.Region import com.amazonaws.regions.RegionUtils import com.amazonaws.util.IOUtils import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.MapperFeature import com.fasterxml.jackson.databind.ObjectMapper +import com.intellij.notification.Notification +import com.intellij.notification.NotificationType +import com.intellij.notification.Notifications +import com.intellij.openapi.diagnostic.Logger import java.io.IOException import java.io.InputStream @@ -16,20 +18,15 @@ import java.io.InputStream * Created by zhaoxiz on 7/20/17. */ object AwsRegionManager { - - private val regions = mutableListOf() + var regions: List init { - val partitions = PartitionLoader.build() - if (partitions != null && partitions.partitions != null) { - for (partition: Partition in partitions.partitions) for ((key, value) in partition.regions) { - regions.add(AwsRegion(key, value.description)) - } + val partitions = PartitionLoader.parse() + val loadedRegions = mutableListOf() + partitions?.partitions?.forEach { + it.regions?.forEach { key, value -> loadedRegions.add(AwsRegion(key, value.description))} } - } - - fun getRegions(): List { - return regions + regions = loadedRegions } fun isServiceSupported(region: String, serviceName: String): Boolean { @@ -40,6 +37,7 @@ object AwsRegionManager { private object PartitionLoader { //TODO This endpoint file should be update-to-date file private const val JAVA_SDK_PARTITION_RESOURCE_PATH = "com/amazonaws/partitions/endpoints.json" + private val LOG = Logger.getInstance(PartitionLoader::class.java) private val mapper = ObjectMapper() .disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS) @@ -47,21 +45,15 @@ private object PartitionLoader { .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .enable(JsonParser.Feature.ALLOW_COMMENTS) - fun build(): Partitions? { - val inputStream = PartitionLoader::class.java.classLoader.getResourceAsStream(JAVA_SDK_PARTITION_RESOURCE_PATH) - - return loadPartitionsFromStream(inputStream, JAVA_SDK_PARTITION_RESOURCE_PATH) - } - - private fun loadPartitionsFromStream(stream: InputStream, location: String): Partitions? { - return try { - mapper.readValue(stream, Partitions::class.java) - } catch (e: IOException) { - //TODO How do we report this error when failed to load the endpoints - println("Error: failed to load file from $location !") - null - } finally { - IOUtils.closeQuietly(stream, null) + fun parse(): Partitions? { + PartitionLoader::class.java.classLoader.getResourceAsStream(JAVA_SDK_PARTITION_RESOURCE_PATH).use { + return try { + mapper.readValue(it, Partitions::class.java) + } catch (e: IOException) { + LOG.error("Error: failed to load file from $JAVA_SDK_PARTITION_RESOURCE_PATH !", e) + Notifications.Bus.notify(Notification("AWS Tookit", "Failed to load region endpoint file", e.message?:e.javaClass.name, NotificationType.ERROR)) + null + } } } } \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt b/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt index 3d2da4bf17a..5c2f9856d20 100644 --- a/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt +++ b/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt @@ -7,7 +7,6 @@ import com.amazonaws.intellij.ui.explorer.AwsExplorerServiceRootNode import com.amazonaws.services.lambda.AWSLambda import com.amazonaws.services.lambda.AWSLambdaClientBuilder import com.amazonaws.services.lambda.model.FunctionConfiguration -import com.intellij.ide.projectView.PresentationData import com.intellij.ide.util.treeView.AbstractTreeNode import com.intellij.openapi.project.Project @@ -17,11 +16,13 @@ import com.intellij.openapi.project.Project class AwsExplorerLambdaRootNode(project: Project?, region: String): AwsExplorerServiceRootNode(project, "AWS Lambda", region, LAMBDA_SERVICE_ICON) { + //TODO we need to move to ClientFactory for initializing service client private val client: AWSLambda = AWSLambdaClientBuilder.standard() .withRegion(region) .build() - override fun loadResources(): MutableList { + override fun loadResources(): Collection { + //TODO We need to list all the functions, not just one page return client.listFunctions().functions } @@ -31,8 +32,8 @@ class AwsExplorerLambdaRootNode(project: Project?, region: String): class AwsExplorerFunctionNode(project: Project?, private val function: FunctionConfiguration, region: String): AwsExplorerNode(project, function, region, SQS_QUEUE_ICON) { //TODO replace to Function icon - override fun getChildren(): MutableCollection> { - return mutableListOf() + override fun getChildren(): Collection> { + return emptyList() } override fun toString(): String { diff --git a/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt b/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt index dab43790a52..cdfd2313448 100644 --- a/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt +++ b/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt @@ -16,11 +16,13 @@ import com.intellij.openapi.project.Project class AwsExplorerS3RootNode(project: Project?, region: String): AwsExplorerServiceRootNode(project, "Amazon S3", region, S3_SERVICE_ICON) { + //TODO use a ClientFactory instead private var client: AmazonS3 = AmazonS3ClientBuilder.standard() .withRegion(region) .build() - override fun loadResources(): MutableList { + //TODO we need to load all the buckets + override fun loadResources(): Collection { return client.listBuckets() } @@ -30,8 +32,8 @@ class AwsExplorerS3RootNode(project: Project?, region: String): class AwsExplorerBucketNode(project: Project?, private val bucket: Bucket, region: String): AwsExplorerNode(project, bucket, region, S3_BUCKET_ICON) { - override fun getChildren(): MutableCollection> { - return mutableListOf() + override fun getChildren(): Collection> { + return emptyList() } override fun toString(): String { diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt index 52f08cc92a2..104f7630eb0 100644 --- a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt @@ -16,7 +16,7 @@ class AwsExplorerFactory : ToolWindowFactory, DumbAware { val simpleToolWindowPanel = SimpleToolWindowPanel(true, false) val wrapperPane = Wrapper() - simpleToolWindowPanel.setToolbar(ExplorerToolbar(project, wrapperPane).mainPanel) + simpleToolWindowPanel.setToolbar(ExplorerToolWindow(project, wrapperPane).mainPanel) simpleToolWindowPanel.setContent(wrapperPane) toolWindow.component.parent.add(simpleToolWindowPanel) } diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt index 161545d66a7..83065cfaf8e 100644 --- a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt @@ -2,8 +2,6 @@ package com.amazonaws.intellij.ui.explorer import com.amazonaws.intellij.core.region.AwsRegionManager import com.amazonaws.intellij.ui.AWS_ICON -import com.google.common.collect.ImmutableCollection -import com.google.common.collect.ImmutableList import com.intellij.ide.projectView.PresentationData import com.intellij.ide.util.treeView.AbstractTreeNode import com.intellij.openapi.project.Project @@ -14,7 +12,6 @@ import javax.swing.Icon /** * Created by zhaoxiz on 7/27/17. */ - abstract class AwsExplorerNode(project: Project?, value: T, val region: String, val awsIcon: Icon?): AbstractTreeNode(project, value) { @@ -25,55 +22,56 @@ abstract class AwsExplorerNode(project: Project?, value: T, val region: Strin override fun toString() = value.toString() } - class AwsExplorerRootNode(project: Project?, region: String): AwsExplorerNode(project, "ROOT", region, AWS_ICON) { - override fun getChildren(): ImmutableCollection> { + override fun getChildren(): Collection> { val childrenList = mutableListOf>() AwsExplorerService.values() .filter { AwsRegionManager.isServiceSupported(region, it.serviceId) } .mapTo(childrenList) { it.buildServiceRootNode(project, region) } - return ImmutableList.copyOf(childrenList) + return childrenList } } abstract class AwsExplorerServiceRootNode(project: Project?, value: String, region: String, awsIcon: Icon): AwsExplorerNode(project, value, region, awsIcon) { - val cache: ClearableLazyValue>> + val cache: ClearableLazyValue>> init { - cache = object : ClearableLazyValue>>() { - override fun compute(): MutableCollection> { + cache = object : ClearableLazyValue>>() { + override fun compute(): Collection> { return try { val resources = loadResources() if (resources.isEmpty()) // Return EmptyNode as the single node of the list - mutableListOf(AwsExplorerEmptyNode(project, region)).toMutableList() + listOf(AwsExplorerEmptyNode(project, region)) else - resources.map { mapResourceToNode(it) }.toMutableList() + resources.map { mapResourceToNode(it) } } catch (e: Exception) { // Return the ErrorNode as the single Node of the list - mutableListOf(AwsExplorerErrorNode(project, e, region)).toMutableList() + listOf(AwsExplorerErrorNode(project, e, region)) } } } } - override fun getChildren(): MutableCollection> { + override fun getChildren(): Collection> { return cache.value } // This method may throw RuntimeException, must handle it - abstract fun loadResources(): MutableList + abstract fun loadResources(): Collection abstract fun mapResourceToNode(resource: Resource): AwsExplorerNode } -class AwsExplorerErrorNode(project: Project?, exception: Exception, region: String): AwsExplorerNode(project, exception, region, null) { - override fun getChildren(): MutableCollection> { - return mutableListOf() +class AwsExplorerErrorNode(project: Project?, exception: Exception, region: String): + AwsExplorerNode(project, exception, region, null) { + + override fun getChildren(): Collection> { + return emptyList() } override fun toString(): String { @@ -88,8 +86,9 @@ class AwsExplorerErrorNode(project: Project?, exception: Exception, region: Stri } class AwsExplorerEmptyNode(project: Project?, region: String): AwsExplorerNode(project, "empty", region, null) { - override fun getChildren(): MutableCollection> { - return mutableListOf() + + override fun getChildren(): Collection> { + return emptyList() } override fun update(presentation: PresentationData?) { diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/ExplorerToolWindow.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/ExplorerToolWindow.kt new file mode 100644 index 00000000000..db27ab38230 --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/ExplorerToolWindow.kt @@ -0,0 +1,58 @@ +package com.amazonaws.intellij.ui.explorer +import com.amazonaws.intellij.core.region.AwsDefaultRegionProvider +import com.amazonaws.intellij.ui.ui.widgets.AwsRegionPanel +import com.intellij.ide.util.treeView.NodeDescriptor +import com.intellij.ide.util.treeView.NodeRenderer +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Disposer +import com.intellij.ui.components.JBScrollPane +import com.intellij.ui.components.panels.Wrapper +import com.intellij.ui.treeStructure.Tree +import com.intellij.util.ui.UIUtil +import java.awt.FlowLayout +import javax.swing.JPanel +import javax.swing.JTree +import javax.swing.tree.DefaultMutableTreeNode +import javax.swing.tree.DefaultTreeModel + +class ExplorerToolWindow(val project: Project, val treePanelWrapper: Wrapper) { + private val regionProvider: AwsDefaultRegionProvider = AwsDefaultRegionProvider.getInstance(project) + private val regionPanel: AwsRegionPanel + val mainPanel: JPanel + + init{ + this.regionPanel = AwsRegionPanel(regionProvider.currentRegion) + regionPanel.addActionListener({ onAwsRegionComboSelected() }) + onAwsRegionComboSelected() + mainPanel = JPanel(FlowLayout(FlowLayout.LEADING, 0, 0)) + mainPanel.add(regionPanel.regionPanel) + } + + private fun onAwsRegionComboSelected() { + val selectedRegion = regionPanel.selectedRegion + val model = DefaultTreeModel(DefaultMutableTreeNode()) + val awsTree = createTree() + val builder = AwsExplorerTreeBuilder(awsTree, model, project, selectedRegion) + Disposer.register(project, builder) + treePanelWrapper.setContent(JBScrollPane(awsTree)) + regionProvider.currentRegion = selectedRegion + } + + private fun createTree(): JTree { + val awsTree = Tree() + UIUtil.setLineStyleAngled(awsTree) + awsTree.isRootVisible = false + awsTree.autoscrolls = true + awsTree.cellRenderer = AwsTreeCellRenderer() + return awsTree + } + + private class AwsTreeCellRenderer:NodeRenderer() { + override fun customizeCellRenderer(tree: JTree, value: Any, selected: Boolean, expanded: Boolean, leaf: Boolean, row: Int, hasFocus: Boolean) { + super.customizeCellRenderer(tree, value, selected, expanded, leaf, row, hasFocus) + if (value is DefaultMutableTreeNode && value.userObject is NodeDescriptor<*>) { + icon = (value.userObject as NodeDescriptor<*>).icon + } + } + } +} \ No newline at end of file From 3b3ca20b030874a987383c9846c8948aa41ae2a0 Mon Sep 17 00:00:00 2001 From: Zhaoxi Zhang Date: Thu, 10 Aug 2017 23:53:23 -0700 Subject: [PATCH 4/5] Remove all the form and java files, refactor the RegionPanel UI and some other small refactors. --- .../ui/ui/widgets/AwsRegionPanel.form | 23 -------- .../ui/ui/widgets/AwsRegionPanel.java | 54 ------------------- .../core/region/AwsDefaultRegionProvider.kt | 20 +++---- .../intellij/core/region/AwsRegionManager.kt | 22 ++++++-- .../lambda/explorer/AwsExplorerLambdaNode.kt | 8 +-- .../intellij/s3/explorer/AwsExplorerS3Node.kt | 8 +-- .../ui/explorer/AwsExplorerFactory.kt | 8 +-- .../intellij/ui/explorer/AwsExplorerNode.kt | 25 ++++----- .../ui/explorer/AwsExplorerService.kt | 6 +-- .../ui/explorer/ExplorerToolWindow.kt | 24 ++++++--- .../intellij/ui/widgets/AwsRegionPanel.kt | 45 ++++++++++++++++ .../amazonaws/intellij/utils/ErrorReport.kt | 8 +++ 12 files changed, 122 insertions(+), 129 deletions(-) delete mode 100644 src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.form delete mode 100644 src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java create mode 100644 src/main/kotlin/com/amazonaws/intellij/ui/widgets/AwsRegionPanel.kt create mode 100644 src/main/kotlin/com/amazonaws/intellij/utils/ErrorReport.kt diff --git a/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.form b/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.form deleted file mode 100644 index f3e61adc58e..00000000000 --- a/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.form +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java b/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java deleted file mode 100644 index 89369b9efa8..00000000000 --- a/src/main/java/com/amazonaws/intellij/ui/ui/widgets/AwsRegionPanel.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.amazonaws.intellij.ui.ui.widgets; - -import com.amazonaws.intellij.core.region.AwsRegion; -import com.amazonaws.intellij.core.region.AwsRegionManager; -import com.intellij.openapi.ui.ComboBox; -import com.intellij.ui.CollectionComboBoxModel; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionListener; -import java.util.Optional; - -/** - * Created by zhaoxiz on 7/28/17. - */ -public class AwsRegionPanel { - private JPanel regionPanel; - private ComboBox regionCombo; - private final CollectionComboBoxModel regionModel = new CollectionComboBoxModel<>(); - - public AwsRegionPanel(String defaultRegion) { - regionCombo.setRenderer(new DefaultListCellRenderer() { - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - label.setIcon(((AwsRegion) value).getIcon()); - return label; - } - }); - - regionCombo.setModel(regionModel); - - AwsRegionManager.INSTANCE.getRegions().forEach(regionModel::add); - selectRegion(defaultRegion); - } - - public void addActionListener(ActionListener actionListener) { - regionCombo.addActionListener(actionListener); - } - - public JPanel getRegionPanel() { - return regionPanel; - } - - private void selectRegion(String regionId) { - AwsRegionManager.INSTANCE.getRegions().stream().filter((region) -> region.getId().equals(regionId)) - .findFirst().ifPresent(regionModel::setSelectedItem); - } - - public String getSelectedRegion() { - assert regionModel.getSelected() != null; - return regionModel.getSelected().getId(); - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt index bec71ef5fa6..1f91ddd311d 100644 --- a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt +++ b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt @@ -5,27 +5,29 @@ import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.components.State import com.intellij.openapi.components.Storage import com.intellij.openapi.project.Project -import com.intellij.util.xmlb.XmlSerializerUtil /** * Created by zhaoxiz on 7/21/17. */ @State(name = "AwsDefaultRegionProvider", storages = arrayOf(Storage("aws.xml"))) class AwsDefaultRegionProvider(): - PersistentStateComponent { - var currentRegion: String = DEFAULT_REGION + PersistentStateComponent { - override fun loadState(state: AwsDefaultRegionProvider) { - XmlSerializerUtil.copyBean(state, this) + data class RegionState(var currentRegion: String? = AwsRegionManager.defaultRegion.id) + private var regionState: RegionState = RegionState() + var currentRegion: AwsRegion + get() = AwsRegionManager.lookupRegionById(regionState.currentRegion?: AwsRegionManager.defaultRegion.id) + set(value) { regionState.currentRegion = value.id } + + override fun loadState(regionState: RegionState) { + this.regionState.currentRegion = regionState.currentRegion } - override fun getState(): AwsDefaultRegionProvider { - return this + override fun getState(): RegionState { + return regionState } companion object { - private const val DEFAULT_REGION = "us-west-2" - @JvmStatic fun getInstance(project: Project): AwsDefaultRegionProvider { return ServiceManager.getService(project, AwsDefaultRegionProvider::class.java) diff --git a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt index 487a4757497..73323c6132a 100644 --- a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt +++ b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt @@ -1,5 +1,6 @@ package com.amazonaws.intellij.core.region +import com.amazonaws.intellij.utils.notifyException import com.amazonaws.partitions.model.Partitions import com.amazonaws.regions.RegionUtils import com.amazonaws.util.IOUtils @@ -7,6 +8,7 @@ import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.MapperFeature import com.fasterxml.jackson.databind.ObjectMapper +import com.google.common.collect.ImmutableMap import com.intellij.notification.Notification import com.intellij.notification.NotificationType import com.intellij.notification.Notifications @@ -18,15 +20,25 @@ import java.io.InputStream * Created by zhaoxiz on 7/20/17. */ object AwsRegionManager { - var regions: List + private const val DEFAULT_REGION = "us-west-2" + val regions: Map + val defaultRegion: AwsRegion init { val partitions = PartitionLoader.parse() - val loadedRegions = mutableListOf() + + val mutableRegionMap = mutableMapOf() partitions?.partitions?.forEach { - it.regions?.forEach { key, value -> loadedRegions.add(AwsRegion(key, value.description))} + it.regions?.forEach { key, region -> mutableRegionMap.put(key, AwsRegion(key, region.description))} } - regions = loadedRegions + + regions = ImmutableMap.copyOf(mutableRegionMap) + //TODO Is there a better way to notify the customer and report the error to us instead of just crash? + defaultRegion = regions.get(DEFAULT_REGION)!! + } + + fun lookupRegionById(regionId: String): AwsRegion { + return regions[regionId]?: defaultRegion } fun isServiceSupported(region: String, serviceName: String): Boolean { @@ -51,7 +63,7 @@ private object PartitionLoader { mapper.readValue(it, Partitions::class.java) } catch (e: IOException) { LOG.error("Error: failed to load file from $JAVA_SDK_PARTITION_RESOURCE_PATH !", e) - Notifications.Bus.notify(Notification("AWS Tookit", "Failed to load region endpoint file", e.message?:e.javaClass.name, NotificationType.ERROR)) + notifyException("Failed to load region endpoint file", e) null } } diff --git a/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt b/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt index 5c2f9856d20..320b5c31a00 100644 --- a/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt +++ b/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt @@ -13,7 +13,7 @@ import com.intellij.openapi.project.Project /** * Created by zhaoxiz on 7/28/17. */ -class AwsExplorerLambdaRootNode(project: Project?, region: String): +class AwsExplorerLambdaRootNode(project: Project, region: String): AwsExplorerServiceRootNode(project, "AWS Lambda", region, LAMBDA_SERVICE_ICON) { //TODO we need to move to ClientFactory for initializing service client @@ -26,13 +26,13 @@ class AwsExplorerLambdaRootNode(project: Project?, region: String): return client.listFunctions().functions } - override fun mapResourceToNode(resource: FunctionConfiguration) = AwsExplorerFunctionNode(project, resource, region) + override fun mapResourceToNode(resource: FunctionConfiguration) = AwsExplorerFunctionNode(project!!, resource, region) } -class AwsExplorerFunctionNode(project: Project?, private val function: FunctionConfiguration, region: String): +class AwsExplorerFunctionNode(project: Project, private val function: FunctionConfiguration, region: String): AwsExplorerNode(project, function, region, SQS_QUEUE_ICON) { //TODO replace to Function icon - override fun getChildren(): Collection> { + override fun getChildren(): Collection> { return emptyList() } diff --git a/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt b/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt index cdfd2313448..7d499fbf3b1 100644 --- a/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt +++ b/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt @@ -13,7 +13,7 @@ import com.intellij.openapi.project.Project /** * Created by zhaoxiz on 7/28/17. */ -class AwsExplorerS3RootNode(project: Project?, region: String): +class AwsExplorerS3RootNode(project: Project, region: String): AwsExplorerServiceRootNode(project, "Amazon S3", region, S3_SERVICE_ICON) { //TODO use a ClientFactory instead @@ -26,13 +26,13 @@ class AwsExplorerS3RootNode(project: Project?, region: String): return client.listBuckets() } - override fun mapResourceToNode(resource: Bucket) = AwsExplorerBucketNode(project, resource, region) + override fun mapResourceToNode(resource: Bucket) = AwsExplorerBucketNode(project!!, resource, region) } -class AwsExplorerBucketNode(project: Project?, private val bucket: Bucket, region: String): +class AwsExplorerBucketNode(project: Project, private val bucket: Bucket, region: String): AwsExplorerNode(project, bucket, region, S3_BUCKET_ICON) { - override fun getChildren(): Collection> { + override fun getChildren(): Collection> { return emptyList() } diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt index 104f7630eb0..70ca216f9b5 100644 --- a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt @@ -13,12 +13,6 @@ import com.intellij.ui.components.panels.Wrapper class AwsExplorerFactory : ToolWindowFactory, DumbAware { override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) { - val simpleToolWindowPanel = SimpleToolWindowPanel(true, false) - val wrapperPane = Wrapper() - - simpleToolWindowPanel.setToolbar(ExplorerToolWindow(project, wrapperPane).mainPanel) - simpleToolWindowPanel.setContent(wrapperPane) - toolWindow.component.parent.add(simpleToolWindowPanel) + toolWindow.component.parent.add(ExplorerToolWindow(project)) } - } \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt index 83065cfaf8e..58e68519e29 100644 --- a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerNode.kt @@ -12,7 +12,7 @@ import javax.swing.Icon /** * Created by zhaoxiz on 7/27/17. */ -abstract class AwsExplorerNode(project: Project?, value: T, val region: String, val awsIcon: Icon?): +abstract class AwsExplorerNode(project: Project, value: T, val region: String, val awsIcon: Icon?): AbstractTreeNode(project, value) { override fun update(presentation: PresentationData?) { @@ -22,20 +22,20 @@ abstract class AwsExplorerNode(project: Project?, value: T, val region: Strin override fun toString() = value.toString() } -class AwsExplorerRootNode(project: Project?, region: String): +class AwsExplorerRootNode(project: Project, region: String): AwsExplorerNode(project, "ROOT", region, AWS_ICON) { override fun getChildren(): Collection> { val childrenList = mutableListOf>() AwsExplorerService.values() .filter { AwsRegionManager.isServiceSupported(region, it.serviceId) } - .mapTo(childrenList) { it.buildServiceRootNode(project, region) } + .mapTo(childrenList) { it.buildServiceRootNode(project!!, region) } return childrenList } } -abstract class AwsExplorerServiceRootNode(project: Project?, value: String, region: String, awsIcon: Icon): +abstract class AwsExplorerServiceRootNode(project: Project, value: String, region: String, awsIcon: Icon): AwsExplorerNode(project, value, region, awsIcon) { val cache: ClearableLazyValue>> @@ -44,14 +44,15 @@ abstract class AwsExplorerServiceRootNode(project: Project?, value: St override fun compute(): Collection> { return try { val resources = loadResources() - if (resources.isEmpty()) + if (resources.isEmpty()) { // Return EmptyNode as the single node of the list - listOf(AwsExplorerEmptyNode(project, region)) - else + listOf(AwsExplorerEmptyNode(project, region)) + } else { resources.map { mapResourceToNode(it) } + } } catch (e: Exception) { // Return the ErrorNode as the single Node of the list - listOf(AwsExplorerErrorNode(project, e, region)) + listOf(AwsExplorerErrorNode(project, e, region)) } } } @@ -67,10 +68,10 @@ abstract class AwsExplorerServiceRootNode(project: Project?, value: St abstract fun mapResourceToNode(resource: Resource): AwsExplorerNode } -class AwsExplorerErrorNode(project: Project?, exception: Exception, region: String): +class AwsExplorerErrorNode(project: Project, exception: Exception, region: String): AwsExplorerNode(project, exception, region, null) { - override fun getChildren(): Collection> { + override fun getChildren(): Collection> { return emptyList() } @@ -85,9 +86,9 @@ class AwsExplorerErrorNode(project: Project?, exception: Exception, region: Stri } } -class AwsExplorerEmptyNode(project: Project?, region: String): AwsExplorerNode(project, "empty", region, null) { +class AwsExplorerEmptyNode(project: Project, region: String): AwsExplorerNode(project, "empty", region, null) { - override fun getChildren(): Collection> { + override fun getChildren(): Collection> { return emptyList() } diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt index d616246a533..7e462f699f5 100644 --- a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt @@ -12,16 +12,16 @@ import com.intellij.openapi.project.Project */ enum class AwsExplorerService(val serviceId: String) { S3(AmazonS3.ENDPOINT_PREFIX) { - override fun buildServiceRootNode(project: Project?, region: String): AwsExplorerS3RootNode { + override fun buildServiceRootNode(project: Project, region: String): AwsExplorerS3RootNode { return AwsExplorerS3RootNode(project, region) } }, LAMBDA(AWSLambda.ENDPOINT_PREFIX) { - override fun buildServiceRootNode(project: Project?, region: String): AwsExplorerLambdaRootNode { + override fun buildServiceRootNode(project: Project, region: String): AwsExplorerLambdaRootNode { return AwsExplorerLambdaRootNode(project, region) } }, ; - abstract fun buildServiceRootNode(project: Project?, region: String): AbstractTreeNode + abstract fun buildServiceRootNode(project: Project, region: String): AbstractTreeNode } \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/ExplorerToolWindow.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/ExplorerToolWindow.kt index db27ab38230..de2cf2909b8 100644 --- a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/ExplorerToolWindow.kt +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/ExplorerToolWindow.kt @@ -1,38 +1,46 @@ package com.amazonaws.intellij.ui.explorer import com.amazonaws.intellij.core.region.AwsDefaultRegionProvider -import com.amazonaws.intellij.ui.ui.widgets.AwsRegionPanel +import com.amazonaws.intellij.ui.widgets.AwsRegionPanel import com.intellij.ide.util.treeView.NodeDescriptor import com.intellij.ide.util.treeView.NodeRenderer import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.SimpleToolWindowPanel import com.intellij.openapi.util.Disposer import com.intellij.ui.components.JBScrollPane import com.intellij.ui.components.panels.Wrapper import com.intellij.ui.treeStructure.Tree import com.intellij.util.ui.UIUtil import java.awt.FlowLayout +import java.awt.event.ActionListener import javax.swing.JPanel import javax.swing.JTree import javax.swing.tree.DefaultMutableTreeNode import javax.swing.tree.DefaultTreeModel -class ExplorerToolWindow(val project: Project, val treePanelWrapper: Wrapper) { +class ExplorerToolWindow(val project: Project): + SimpleToolWindowPanel(true, false) { + + private val treePanelWrapper: Wrapper = Wrapper(); private val regionProvider: AwsDefaultRegionProvider = AwsDefaultRegionProvider.getInstance(project) private val regionPanel: AwsRegionPanel - val mainPanel: JPanel + private val mainPanel: JPanel init{ - this.regionPanel = AwsRegionPanel(regionProvider.currentRegion) - regionPanel.addActionListener({ onAwsRegionComboSelected() }) - onAwsRegionComboSelected() + regionPanel = AwsRegionPanel(regionProvider.currentRegion) + regionPanel.addActionListener(ActionListener { onAwsRegionComboSelected() }) + mainPanel = JPanel(FlowLayout(FlowLayout.LEADING, 0, 0)) mainPanel.add(regionPanel.regionPanel) + setToolbar(mainPanel) + setContent(treePanelWrapper) + onAwsRegionComboSelected() } private fun onAwsRegionComboSelected() { - val selectedRegion = regionPanel.selectedRegion + val selectedRegion = regionPanel.getSelectedRegion() ?: return val model = DefaultTreeModel(DefaultMutableTreeNode()) val awsTree = createTree() - val builder = AwsExplorerTreeBuilder(awsTree, model, project, selectedRegion) + val builder = AwsExplorerTreeBuilder(awsTree, model, project, selectedRegion.id) Disposer.register(project, builder) treePanelWrapper.setContent(JBScrollPane(awsTree)) regionProvider.currentRegion = selectedRegion diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/widgets/AwsRegionPanel.kt b/src/main/kotlin/com/amazonaws/intellij/ui/widgets/AwsRegionPanel.kt new file mode 100644 index 00000000000..801887f4442 --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/ui/widgets/AwsRegionPanel.kt @@ -0,0 +1,45 @@ +package com.amazonaws.intellij.ui.widgets + +import com.amazonaws.intellij.core.region.AwsRegion +import com.amazonaws.intellij.core.region.AwsRegionManager +import com.intellij.openapi.ui.ComboBox +import com.intellij.ui.CollectionComboBoxModel +import com.intellij.ui.ListCellRendererWrapper +import java.awt.FlowLayout +import java.awt.event.ActionListener +import javax.swing.JLabel +import javax.swing.JList +import javax.swing.JPanel + +class AwsRegionPanel(private val defaultRegion: AwsRegion) { + val regionPanel: JPanel = JPanel() + private val regionCombo: ComboBox = ComboBox() + private val regionModel = CollectionComboBoxModel(AwsRegionManager.regions.values.toList()) + + init { + regionCombo.renderer = object : ListCellRendererWrapper() { + override fun customize(list: JList<*>, value: AwsRegion, index: Int, selected: Boolean, hasFocus: Boolean) { + setIcon(value.icon) + } + } + setupUI() + regionCombo.model = regionModel + regionModel.selectedItem = defaultRegion + } + + fun addActionListener(actionListener: ActionListener) { + regionCombo.addActionListener(actionListener) + } + + fun getSelectedRegion(): AwsRegion? { + return regionModel.selected + } + + private fun setupUI() { + regionPanel.layout = FlowLayout(FlowLayout.CENTER, 0, 0) + val regionLabel = JLabel("Region") + regionPanel.add(regionLabel) + regionPanel.add(regionCombo) + regionLabel.labelFor = regionCombo + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/amazonaws/intellij/utils/ErrorReport.kt b/src/main/kotlin/com/amazonaws/intellij/utils/ErrorReport.kt new file mode 100644 index 00000000000..369245250da --- /dev/null +++ b/src/main/kotlin/com/amazonaws/intellij/utils/ErrorReport.kt @@ -0,0 +1,8 @@ +package com.amazonaws.intellij.utils + +import com.intellij.notification.Notification +import com.intellij.notification.NotificationType +import com.intellij.notification.Notifications + + +fun notifyException(action: String, e: Exception) = Notifications.Bus.notify(Notification("AWS Tookit", action, e.message ?: e.javaClass.name, NotificationType.ERROR)) \ No newline at end of file From c756742d9986acc0c29eeaa213ac51c8db517caf Mon Sep 17 00:00:00 2001 From: Zhaoxi Zhang Date: Wed, 16 Aug 2017 16:55:30 -0700 Subject: [PATCH 5/5] Changed the region setting in aws.xml to 'region' and removed the auto-gennerated headers comments. --- .../intellij/core/region/AwsDefaultRegionProvider.kt | 5 +---- .../com/amazonaws/intellij/core/region/AwsRegion.kt | 3 --- .../amazonaws/intellij/core/region/AwsRegionManager.kt | 8 -------- .../intellij/lambda/explorer/AwsExplorerLambdaNode.kt | 3 --- .../amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt | 3 --- .../amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt | 3 --- .../amazonaws/intellij/ui/explorer/AwsExplorerService.kt | 3 --- .../intellij/ui/explorer/AwsExplorerTreeBuilder.kt | 4 ---- .../intellij/ui/explorer/AwsExplorerTreeStructure.kt | 4 ---- .../kotlin/com/amazonaws/intellij/utils/ErrorReport.kt | 1 - 10 files changed, 1 insertion(+), 36 deletions(-) diff --git a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt index 1f91ddd311d..59bf2a76a1d 100644 --- a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt +++ b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsDefaultRegionProvider.kt @@ -6,10 +6,7 @@ import com.intellij.openapi.components.State import com.intellij.openapi.components.Storage import com.intellij.openapi.project.Project -/** - * Created by zhaoxiz on 7/21/17. - */ -@State(name = "AwsDefaultRegionProvider", storages = arrayOf(Storage("aws.xml"))) +@State(name = "region", storages = arrayOf(Storage("aws.xml"))) class AwsDefaultRegionProvider(): PersistentStateComponent { diff --git a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegion.kt b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegion.kt index f0479fa8392..e582146d54b 100644 --- a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegion.kt +++ b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegion.kt @@ -6,9 +6,6 @@ import com.amazonaws.regions.Regions import com.intellij.openapi.util.IconLoader import javax.swing.Icon -/** - * Created by zhaoxiz on 7/20/17. - */ data class AwsRegion private constructor(val id: String, val name: String, val icon: Icon) { private companion object { val UNKNOWN_REGION_FLAG = "/icons/aws-box.gif" diff --git a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt index 73323c6132a..a4e3f4f2b90 100644 --- a/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt +++ b/src/main/kotlin/com/amazonaws/intellij/core/region/AwsRegionManager.kt @@ -3,22 +3,14 @@ package com.amazonaws.intellij.core.region import com.amazonaws.intellij.utils.notifyException import com.amazonaws.partitions.model.Partitions import com.amazonaws.regions.RegionUtils -import com.amazonaws.util.IOUtils import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.MapperFeature import com.fasterxml.jackson.databind.ObjectMapper import com.google.common.collect.ImmutableMap -import com.intellij.notification.Notification -import com.intellij.notification.NotificationType -import com.intellij.notification.Notifications import com.intellij.openapi.diagnostic.Logger import java.io.IOException -import java.io.InputStream -/** - * Created by zhaoxiz on 7/20/17. - */ object AwsRegionManager { private const val DEFAULT_REGION = "us-west-2" val regions: Map diff --git a/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt b/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt index 320b5c31a00..ffcf531e50a 100644 --- a/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt +++ b/src/main/kotlin/com/amazonaws/intellij/lambda/explorer/AwsExplorerLambdaNode.kt @@ -10,9 +10,6 @@ import com.amazonaws.services.lambda.model.FunctionConfiguration import com.intellij.ide.util.treeView.AbstractTreeNode import com.intellij.openapi.project.Project -/** - * Created by zhaoxiz on 7/28/17. - */ class AwsExplorerLambdaRootNode(project: Project, region: String): AwsExplorerServiceRootNode(project, "AWS Lambda", region, LAMBDA_SERVICE_ICON) { diff --git a/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt b/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt index 7d499fbf3b1..2679543c8f8 100644 --- a/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt +++ b/src/main/kotlin/com/amazonaws/intellij/s3/explorer/AwsExplorerS3Node.kt @@ -10,9 +10,6 @@ import com.amazonaws.services.s3.model.Bucket import com.intellij.ide.util.treeView.AbstractTreeNode import com.intellij.openapi.project.Project -/** - * Created by zhaoxiz on 7/28/17. - */ class AwsExplorerS3RootNode(project: Project, region: String): AwsExplorerServiceRootNode(project, "Amazon S3", region, S3_SERVICE_ICON) { diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt index 70ca216f9b5..604813d66c0 100644 --- a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerFactory.kt @@ -7,9 +7,6 @@ import com.intellij.openapi.wm.ToolWindow import com.intellij.openapi.wm.ToolWindowFactory import com.intellij.ui.components.panels.Wrapper -/** - * Created by zhaoxiz on 7/19/17. - */ class AwsExplorerFactory : ToolWindowFactory, DumbAware { override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) { diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt index 7e462f699f5..de9ab7c0e98 100644 --- a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerService.kt @@ -7,9 +7,6 @@ import com.amazonaws.services.s3.AmazonS3 import com.intellij.ide.util.treeView.AbstractTreeNode import com.intellij.openapi.project.Project -/** - * Created by zhaoxiz on 7/27/17. - */ enum class AwsExplorerService(val serviceId: String) { S3(AmazonS3.ENDPOINT_PREFIX) { override fun buildServiceRootNode(project: Project, region: String): AwsExplorerS3RootNode { diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeBuilder.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeBuilder.kt index 0a6be5493c1..32e12b90af4 100644 --- a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeBuilder.kt +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeBuilder.kt @@ -6,10 +6,6 @@ import com.intellij.openapi.project.Project import javax.swing.JTree import javax.swing.tree.DefaultTreeModel -/** - * Created by zhaoxiz on 7/27/17. - */ - class AwsExplorerTreeBuilder(tree: JTree, treeModel: DefaultTreeModel, private val project: Project, private val region: String): AbstractTreeBuilder(tree, treeModel, AwsExplorerTreeStructure(project, region), null, false) { diff --git a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeStructure.kt b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeStructure.kt index 216775a18e7..2b6b48a3cc5 100644 --- a/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeStructure.kt +++ b/src/main/kotlin/com/amazonaws/intellij/ui/explorer/AwsExplorerTreeStructure.kt @@ -4,10 +4,6 @@ import com.intellij.ide.projectView.TreeStructureProvider import com.intellij.ide.util.treeView.AbstractTreeStructureBase import com.intellij.openapi.project.Project -/** - * Created by zhaoxiz on 7/27/17. - */ - class AwsExplorerTreeStructure(project: Project, val region: String) : AbstractTreeStructureBase(project) { override fun getProviders(): List? { diff --git a/src/main/kotlin/com/amazonaws/intellij/utils/ErrorReport.kt b/src/main/kotlin/com/amazonaws/intellij/utils/ErrorReport.kt index 369245250da..b5a871b7803 100644 --- a/src/main/kotlin/com/amazonaws/intellij/utils/ErrorReport.kt +++ b/src/main/kotlin/com/amazonaws/intellij/utils/ErrorReport.kt @@ -4,5 +4,4 @@ import com.intellij.notification.Notification import com.intellij.notification.NotificationType import com.intellij.notification.Notifications - fun notifyException(action: String, e: Exception) = Notifications.Bus.notify(Notification("AWS Tookit", action, e.message ?: e.javaClass.name, NotificationType.ERROR)) \ No newline at end of file