diff options
Diffstat (limited to 'java/remote-servers')
12 files changed, 544 insertions, 326 deletions
diff --git a/java/remote-servers/impl/remote-servers-java-impl.iml b/java/remote-servers/impl/remote-servers-java-impl.iml index 6999e2deac71..15781473aa45 100644 --- a/java/remote-servers/impl/remote-servers-java-impl.iml +++ b/java/remote-servers/impl/remote-servers-java-impl.iml @@ -15,6 +15,7 @@ <orderEntry type="module" module-name="remote-servers-impl" /> <orderEntry type="module" module-name="java-impl" /> <orderEntry type="module" module-name="openapi" /> + <orderEntry type="module" module-name="idea-ui" /> </component> </module> diff --git a/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml b/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml index 24a0776ccd29..692199e3bb2c 100644 --- a/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml +++ b/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml @@ -2,7 +2,7 @@ <extensionPoints> <extensionPoint qualifiedName="com.intellij.remoteServer.moduleBuilderContribution" - interface="com.intellij.remoteServer.impl.module.CloudModuleBuilderContribution"/> + interface="com.intellij.remoteServer.impl.module.CloudModuleBuilderContributionFactory"/> </extensionPoints> <extensions defaultExtensionNs="com.intellij"> diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfigurable.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfigurable.java index 14bd043a7f23..e235eeeb55aa 100644 --- a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfigurable.java +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfigurable.java @@ -15,152 +15,20 @@ */ package com.intellij.remoteServer.impl.module; -import com.intellij.openapi.Disposable; import com.intellij.openapi.options.ConfigurationException; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Disposer; import com.intellij.remoteServer.configuration.RemoteServer; -import com.intellij.remoteServer.runtime.Deployment; -import com.intellij.remoteServer.runtime.ServerConnection; -import com.intellij.remoteServer.runtime.ServerConnector; -import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance; -import com.intellij.remoteServer.util.*; -import com.intellij.util.concurrency.Semaphore; -import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import javax.swing.*; -import java.util.Collection; -import java.util.concurrent.atomic.AtomicReference; +import java.awt.*; -public abstract class CloudApplicationConfigurable< - SC extends CloudConfigurationBase, - DC extends CloudDeploymentNameConfiguration, - SR extends CloudMultiSourceServerRuntimeInstance<DC, ?, ?, ?>, - AC extends CloudApplicationConfiguration> { +public abstract class CloudApplicationConfigurable { - private final Project myProject; - private final Disposable myParentDisposable; + public abstract Component getComponent(); - private DelayedRunner myRunner; + public abstract void setAccount(RemoteServer<?> account); - private RemoteServer<?> myAccount; - - public CloudApplicationConfigurable(@Nullable Project project, Disposable parentDisposable) { - myProject = project; - myParentDisposable = parentDisposable; - } - - public void setAccount(RemoteServer<?> account) { - myAccount = account; - clearCloudData(); - } - - protected RemoteServer<SC> getAccount() { - return (RemoteServer<SC>)myAccount; - } - - public JComponent getComponent() { - JComponent result = getMainPanel(); - if (myRunner == null) { - myRunner = new DelayedRunner(result) { - - private RemoteServer<?> myPreviousAccount; - - @Override - protected boolean wasChanged() { - boolean result = myPreviousAccount != myAccount; - if (result) { - myPreviousAccount = myAccount; - } - return result; - } - - @Override - protected void run() { - loadCloudData(); - } - }; - Disposer.register(myParentDisposable, myRunner); - } - return result; - } - - protected void clearCloudData() { - getExistingComboBox().removeAllItems(); - } - - protected void loadCloudData() { - new ConnectionTask<Collection<Deployment>>("Loading existing applications list") { - - @Override - protected void run(final ServerConnection<DC> connection, - final Semaphore semaphore, - final AtomicReference<Collection<Deployment>> result) { - connection.connectIfNeeded(new ServerConnector.ConnectionCallback<DC>() { - - @Override - public void connected(@NotNull ServerRuntimeInstance<DC> serverRuntimeInstance) { - connection.computeDeployments(new Runnable() { - - @Override - public void run() { - result.set(connection.getDeployments()); - semaphore.up(); - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - if (!Disposer.isDisposed(myParentDisposable)) { - setupExistingApplications(result.get()); - } - } - }); - } - }); - } - - @Override - public void errorOccurred(@NotNull String errorMessage) { - runtimeErrorOccurred(errorMessage); - semaphore.up(); - } - }); - } - - @Override - protected Collection<Deployment> run(SR serverRuntimeInstance) throws ServerRuntimeException { - return null; - } - }.performAsync(); - } - - private void setupExistingApplications(Collection<Deployment> deployments) { - JComboBox existingComboBox = getExistingComboBox(); - existingComboBox.removeAllItems(); - for (Deployment deployment : deployments) { - existingComboBox.addItem(deployment.getName()); - } - } - - protected Project getProject() { - return myProject; - } - - protected abstract JComboBox getExistingComboBox(); - - protected abstract JComponent getMainPanel(); - - public abstract AC createConfiguration(); + public abstract CloudApplicationConfiguration createConfiguration(); public abstract void validate() throws ConfigurationException; - - protected abstract class ConnectionTask<T> extends CloudConnectionTask<T, SC, DC, SR> { - - public ConnectionTask(String title) { - super(myProject, title, CloudApplicationConfigurable.this.getAccount()); - } - } } diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfiguration.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfiguration.java index 9af0f1ad472b..af9fa723e82a 100644 --- a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfiguration.java +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfiguration.java @@ -18,19 +18,4 @@ package com.intellij.remoteServer.impl.module; public abstract class CloudApplicationConfiguration { - private boolean myExisting; - private final String myExistingAppName; - - protected CloudApplicationConfiguration(boolean existing, String existingAppName) { - myExisting = existing; - myExistingAppName = existingAppName; - } - - public boolean isExisting() { - return myExisting; - } - - public String getExistingAppName() { - return myExistingAppName; - } } diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java index 4aa8d60bcea4..62e256c14c8e 100644 --- a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java @@ -16,6 +16,7 @@ package com.intellij.remoteServer.impl.module; import com.intellij.icons.AllIcons; +import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportModelBase; import com.intellij.ide.util.projectWizard.JavaModuleBuilder; import com.intellij.ide.util.projectWizard.ModuleBuilderListener; import com.intellij.ide.util.projectWizard.ModuleWizardStep; @@ -23,20 +24,42 @@ import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.Disposable; import com.intellij.openapi.module.JavaModuleType; import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; +import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.remoteServer.ServerType; import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.util.containers.hash.HashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.util.Map; public class CloudModuleBuilder extends JavaModuleBuilder { private RemoteServer<?> myAccount; private CloudApplicationConfiguration myApplicationConfiguration; + private FrameworkSupportModelBase myFrameworkSupportModel; + + private Map<ServerType<?>, CloudModuleBuilderContribution> myCloudType2Contribution; + private Project myProject; public CloudModuleBuilder() { + myCloudType2Contribution = new HashMap<ServerType<?>, CloudModuleBuilderContribution>(); + + ModuleConfigurationUpdater configurationUpdater = new ModuleConfigurationUpdater() { + + public void update(@NotNull final Module module, @NotNull final ModifiableRootModel rootModel) { + preConfigureModule(module, rootModel); + } + }; + addModuleConfigurationUpdater(configurationUpdater); + addListener(new ModuleBuilderListener() { @Override @@ -93,7 +116,8 @@ public class CloudModuleBuilder extends JavaModuleBuilder { @Nullable @Override public ModuleWizardStep getCustomOptionsStep(WizardContext context, Disposable parentDisposable) { - return new CloudModuleWizardStep(this, context.getProject(), parentDisposable); + myProject = context.getProject(); + return new CloudModuleWizardStep(this, myProject, parentDisposable); } public void setAccount(RemoteServer<?> account) { @@ -108,7 +132,43 @@ public class CloudModuleBuilder extends JavaModuleBuilder { myApplicationConfiguration = applicationConfiguration; } + public CloudApplicationConfiguration getApplicationConfiguration() { + return myApplicationConfiguration; + } + + public CloudModuleBuilderContribution getContribution(ServerType<?> cloudType) { + CloudModuleBuilderContribution result = myCloudType2Contribution.get(cloudType); + if (result == null) { + result = CloudModuleBuilderContributionFactory.getInstanceByType(cloudType).createContribution(this); + myCloudType2Contribution.put(cloudType, result); + } + return result; + } + + private CloudModuleBuilderContribution getContribution() { + return getContribution(myAccount.getType()); + } + + private void preConfigureModule(Module module, ModifiableRootModel model) { + getContribution().preConfigureModule(module, model); + } + private void configureModule(final Module module) { - CloudModuleBuilderContribution.getInstanceByType(myAccount.getType()).configureModule(module, myAccount, myApplicationConfiguration); + getContribution().configureModule(module); + } + + public FrameworkSupportModelBase getFrameworkSupportModel() { + if (myFrameworkSupportModel == null) { + final LibrariesContainer librariesContainer = LibrariesContainerFactory.createContainer(myProject); + myFrameworkSupportModel = new FrameworkSupportModelBase(myProject, this, librariesContainer) { + + @NotNull + @Override + public String getBaseDirectoryForLibrariesPath() { + return StringUtil.notNullize(getContentEntryPath()); + } + }; + } + return myFrameworkSupportModel; } } diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContribution.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContribution.java index 6643c89cc1c4..dd2d9d9af563 100644 --- a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContribution.java +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContribution.java @@ -16,33 +16,51 @@ package com.intellij.remoteServer.impl.module; import com.intellij.openapi.Disposable; -import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.remoteServer.ServerType; -import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration; +import com.intellij.remoteServer.configuration.deployment.DeploymentSource; import org.jetbrains.annotations.Nullable; public abstract class CloudModuleBuilderContribution { - public static final ExtensionPointName<CloudModuleBuilderContribution> EP_NAME - = ExtensionPointName.create("com.intellij.remoteServer.moduleBuilderContribution"); + private final CloudModuleBuilder myModuleBuilder; - public abstract ServerType<?> getCloudType(); + private final ServerType<?> myCloudType; + private CloudApplicationConfigurable myApplicationConfigurable; - public abstract CloudApplicationConfigurable createApplicationConfigurable(@Nullable Project project, Disposable parentDisposable); + public CloudModuleBuilderContribution(CloudModuleBuilder moduleBuilder, ServerType<?> cloudType) { + myModuleBuilder = moduleBuilder; + myCloudType = cloudType; + } + + protected CloudModuleBuilder getModuleBuilder() { + return myModuleBuilder; + } - public abstract void configureModule(Module module, - RemoteServer<?> account, - CloudApplicationConfiguration configuration); + protected ServerType<?> getCloudType() { + return myCloudType; + } - public static CloudModuleBuilderContribution getInstanceByType(ServerType<?> cloudType) { - for (CloudModuleBuilderContribution contribution : EP_NAME.getExtensions()) { - if (contribution.getCloudType() == cloudType) { - return contribution; - } + public CloudApplicationConfigurable getApplicationConfigurable(@Nullable Project project, Disposable parentDisposable) { + if (myApplicationConfigurable == null) { + myApplicationConfigurable = createApplicationConfigurable(project, parentDisposable); } - return null; + return myApplicationConfigurable; + } + + public void preConfigureModule(Module module, ModifiableRootModel model) { + + } + + public abstract void configureModule(Module module); + + protected abstract CloudApplicationConfigurable createApplicationConfigurable(@Nullable Project project, Disposable parentDisposable); + + protected DeploymentConfiguration createDeploymentConfiguration(DeploymentSource deploymentSource) { + return myCloudType.createDeploymentConfigurator(null).createDefaultConfiguration(deploymentSource); } } diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionBase.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionBase.java deleted file mode 100644 index 6a927d97bb93..000000000000 --- a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionBase.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.remoteServer.impl.module; - -import com.intellij.execution.RunManagerEx; -import com.intellij.execution.RunnerAndConfigurationSettings; -import com.intellij.execution.configurations.ConfigurationType; -import com.intellij.openapi.Disposable; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModulePointer; -import com.intellij.openapi.module.ModulePointerManager; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.MessageType; -import com.intellij.remoteServer.ServerType; -import com.intellij.remoteServer.configuration.RemoteServer; -import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerConfigurationType; -import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration; -import com.intellij.remoteServer.impl.configuration.deployment.ModuleDeploymentSourceImpl; -import com.intellij.remoteServer.util.*; -import com.intellij.remoteServer.util.ssh.SshKeyChecker; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - - -public abstract class CloudModuleBuilderContributionBase< - SC extends CloudConfigurationBase, - DC extends CloudDeploymentNameConfiguration, - AC extends CloudApplicationConfiguration, - SR extends CloudMultiSourceServerRuntimeInstance<DC, ?, ?, ?>> - extends CloudModuleBuilderContribution { - - @Override - public void configureModule(Module module, - RemoteServer<?> account, - CloudApplicationConfiguration applicationConfiguration) { - RemoteServer<SC> castedAccount = (RemoteServer<SC>)account; - final AC castedApplicationConfiguration = (AC)applicationConfiguration; - - DC deploymentConfiguration = createDeploymentConfiguration(); - - if (applicationConfiguration.isExisting()) { - deploymentConfiguration.setDefaultDeploymentName(false); - deploymentConfiguration.setDeploymentName(applicationConfiguration.getExistingAppName()); - } - - final DeployToServerRunConfiguration<SC, DC> runConfiguration = createRunConfiguration(module, castedAccount, deploymentConfiguration); - - final String cloudName = account.getType().getPresentableName(); - final Project project = module.getProject(); - new CloudConnectionTask<Object, SC, DC, SR>(project, CloudBundle.getText("cloud.support", cloudName), castedAccount) { - - CloudNotifier myNotifier = new CloudNotifier(cloudName); - - boolean myFirstAttempt = true; - - @Override - protected Object run(SR serverRuntime) throws ServerRuntimeException { - doConfigureModule(castedApplicationConfiguration, runConfiguration, myFirstAttempt, serverRuntime); - myNotifier.showMessage(CloudBundle.getText("cloud.support.added", cloudName), MessageType.INFO); - return null; - } - - @Override - protected void runtimeErrorOccurred(@NotNull String errorMessage) { - myFirstAttempt = false; - new SshKeyChecker().checkServerError(errorMessage, myNotifier, project, this); - } - }.performAsync(); - } - - private DeployToServerRunConfiguration<SC, DC> createRunConfiguration(Module module, - RemoteServer<SC> server, - DC deploymentConfiguration) { - Project project = module.getProject(); - - String serverName = server.getName(); - - String name = generateRunConfigurationName(serverName, module.getName()); - - final RunManagerEx runManager = RunManagerEx.getInstanceEx(project); - final RunnerAndConfigurationSettings runSettings - = runManager.createRunConfiguration(name, getRunConfigurationType().getConfigurationFactories()[0]); - - final DeployToServerRunConfiguration<SC, DC> result = (DeployToServerRunConfiguration<SC, DC>)runSettings.getConfiguration(); - - result.setServerName(serverName); - - final ModulePointer modulePointer = ModulePointerManager.getInstance(project).create(module); - result.setDeploymentSource(new ModuleDeploymentSourceImpl(modulePointer)); - - result.setDeploymentConfiguration(deploymentConfiguration); - - runManager.addConfiguration(runSettings, false); - runManager.setSelectedConfiguration(runSettings); - - return result; - } - - private static String generateRunConfigurationName(String serverName, String moduleName) { - return CloudBundle.getText("run.configuration.name", serverName, moduleName); - } - - private DeployToServerConfigurationType getRunConfigurationType() { - String id = DeployToServerConfigurationType.getId(getCloudType()); - for (ConfigurationType configurationType : ConfigurationType.CONFIGURATION_TYPE_EP.getExtensions()) { - if (configurationType instanceof DeployToServerConfigurationType) { - DeployToServerConfigurationType deployConfigurationType = (DeployToServerConfigurationType)configurationType; - if (deployConfigurationType.getId().equals(id)) { - return deployConfigurationType; - } - } - } - return null; - } - - @Override - public abstract ServerType<SC> getCloudType(); - - @Override - public abstract CloudApplicationConfigurable<SC, DC, SR, AC> createApplicationConfigurable(@Nullable Project project, - Disposable parentDisposable); - - protected abstract DC createDeploymentConfiguration(); - - protected abstract void doConfigureModule(AC applicationConfiguration, - DeployToServerRunConfiguration<SC, DC> runConfiguration, - boolean firstAttempt, - SR serverRuntime) throws ServerRuntimeException; -} diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionFactory.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionFactory.java new file mode 100644 index 000000000000..20ebc29fe148 --- /dev/null +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionFactory.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.remoteServer.impl.module; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.remoteServer.ServerType; + + +public abstract class CloudModuleBuilderContributionFactory { + + public static final ExtensionPointName<CloudModuleBuilderContributionFactory> EP_NAME + = ExtensionPointName.create("com.intellij.remoteServer.moduleBuilderContribution"); + + public abstract ServerType<?> getCloudType(); + + public abstract CloudModuleBuilderContribution createContribution(CloudModuleBuilder moduleBuilder); + + public static CloudModuleBuilderContributionFactory getInstanceByType(ServerType<?> cloudType) { + for (CloudModuleBuilderContributionFactory contribution : EP_NAME.getExtensions()) { + if (contribution.getCloudType() == cloudType) { + return contribution; + } + } + return null; + } +} diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderSourceContribution.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderSourceContribution.java new file mode 100644 index 000000000000..b5fdcc3995c8 --- /dev/null +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderSourceContribution.java @@ -0,0 +1,191 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.remoteServer.impl.module; + +import com.intellij.ide.util.newProjectWizard.StepSequence; +import com.intellij.ide.util.newProjectWizard.modes.CreateFromSourcesMode; +import com.intellij.ide.util.projectWizard.AbstractStepWithProgress; +import com.intellij.ide.util.projectWizard.ModuleWizardStep; +import com.intellij.ide.util.projectWizard.ProjectBuilder; +import com.intellij.ide.util.projectWizard.WizardContext; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.ui.MessageType; +import com.intellij.openapi.util.Disposer; +import com.intellij.remoteServer.ServerType; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration; +import com.intellij.remoteServer.util.*; +import com.intellij.remoteServer.util.ssh.SshKeyChecker; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + + +public abstract class CloudModuleBuilderSourceContribution< + SC extends CloudConfigurationBase, + DC extends CloudDeploymentNameConfiguration, + AC extends CloudSourceApplicationConfiguration, + SR extends CloudMultiSourceServerRuntimeInstance<DC, ?, ?, ?>> + extends CloudModuleBuilderContribution { + + private CloudNotifier myNotifier; + + public CloudModuleBuilderSourceContribution(CloudModuleBuilder moduleBuilder, ServerType<SC> cloudType) { + super(moduleBuilder, cloudType); + } + + @Override + public void configureModule(final Module module) { + final CloudModuleBuilder moduleBuilder = getModuleBuilder(); + RemoteServer<SC> account = (RemoteServer<SC>)moduleBuilder.getAccount(); + final AC applicationConfiguration = (AC)moduleBuilder.getApplicationConfiguration(); + + DC deploymentConfiguration = createDeploymentConfiguration(); + + if (applicationConfiguration.isExisting()) { + deploymentConfiguration.setDefaultDeploymentName(false); + deploymentConfiguration.setDeploymentName(applicationConfiguration.getExistingAppName()); + } + + final DeployToServerRunConfiguration<SC, DC> runConfiguration + = CloudRunConfigurationUtil.createRunConfiguration(account, module, deploymentConfiguration); + + final ServerType<?> cloudType = account.getType(); + final Project project = module.getProject(); + new CloudConnectionTask<Object, SC, DC, SR>(project, + CloudBundle.getText("cloud.support", cloudType.getPresentableName()), + account) { + + boolean myFirstAttempt = true; + + @Override + protected Object run(SR serverRuntime) throws ServerRuntimeException { + doConfigureModule(applicationConfiguration, runConfiguration, myFirstAttempt, serverRuntime); + return null; + } + + @Override + protected void runtimeErrorOccurred(@NotNull String errorMessage) { + myFirstAttempt = false; + new SshKeyChecker().checkServerError(errorMessage, getNotifier(), project, this); + } + + @Override + protected void postPerform(Object result) { + detectModuleStructure(module, moduleBuilder.getContentEntryPath()); + } + + @Override + protected boolean shouldStartInBackground() { + return false; + } + }.performAsync(); + } + + private CloudNotifier getNotifier() { + if (myNotifier == null) { + myNotifier = new CloudNotifier(getCloudType().getPresentableName()); + } + return myNotifier; + } + + private void detectModuleStructure(Module module, final String contentPath) { + final Project project = module.getProject(); + + final CreateFromSourcesMode mode = new CreateFromSourcesMode() { + + @Override + public boolean isAvailable(WizardContext context) { + return true; + } + + @Override + public void addSteps(WizardContext context, ModulesProvider modulesProvider, StepSequence sequence, String specific) { + super.addSteps(context, modulesProvider, sequence, specific); + myProjectBuilder.setFileToImport(contentPath); + } + }; + + final WizardContext context = new WizardContext(project); + + final StepSequence stepSequence = mode.getSteps(context, DefaultModulesProvider.createForProject(context.getProject())); + if (stepSequence == null) { + return; + } + + Disposer.register(project, new Disposable() { + + @Override + public void dispose() { + for (ModuleWizardStep step : stepSequence.getAllSteps()) { + step.disposeUIResources(); + } + } + }); + + ProgressManager.getInstance() + .run(new Task.Backgroundable(project, CloudBundle.getText("detect.module.structure", getCloudType().getPresentableName()), false) { + + @Override + public void run(@NotNull ProgressIndicator indicator) { + for (ModuleWizardStep step = ContainerUtil.getFirstItem(stepSequence.getSelectedSteps()); + step != null; + step = stepSequence.getNextStep(step)) { + if (step instanceof AbstractStepWithProgress<?>) { + ((AbstractStepWithProgress)step).performStep(); + } + else { + step.updateDataModel(); + } + } + CloudAccountSelectionEditor.unsetAccountOnContext(context, getCloudType()); + } + + @Override + public boolean shouldStartInBackground() { + return false; + } + + @Override + public void onSuccess() { + ProjectBuilder moduleBuilder = mode.getModuleBuilder(); + if (moduleBuilder == null) { + return; + } + moduleBuilder.commit(project); + getNotifier().showMessage(CloudBundle.getText("cloud.support.added", getCloudType().getPresentableName()), MessageType.INFO); + } + }); + } + + @Override + protected abstract CloudSourceApplicationConfigurable<SC, DC, SR, AC> createApplicationConfigurable(@Nullable Project project, + Disposable parentDisposable); + + protected abstract DC createDeploymentConfiguration(); + + protected abstract void doConfigureModule(AC applicationConfiguration, + DeployToServerRunConfiguration<SC, DC> runConfiguration, + boolean firstAttempt, + SR serverRuntime) throws ServerRuntimeException; +} diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.java index cf0e283616b2..79b307b0658e 100644 --- a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.java +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.java @@ -22,13 +22,13 @@ import com.intellij.openapi.project.Project; import com.intellij.remoteServer.ServerType; import com.intellij.remoteServer.configuration.RemoteServer; import com.intellij.remoteServer.util.CloudAccountSelectionEditor; -import com.intellij.util.containers.hash.HashMap; +import com.intellij.util.containers.HashSet; import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.List; -import java.util.Map; +import java.util.Set; public class CloudModuleWizardStep extends ModuleWizardStep { @@ -43,17 +43,17 @@ public class CloudModuleWizardStep extends ModuleWizardStep { private CloudAccountSelectionEditor myAccountSelectionPanel; - private Map<ServerType<?>, CloudApplicationConfigurable> myCloudType2ApplicationConfigurable; + private Set<ServerType<?>> myApplicationConfigurableTypes; public CloudModuleWizardStep(CloudModuleBuilder moduleBuilder, Project project, Disposable parentDisposable) { myModuleBuilder = moduleBuilder; myProject = project; myParentDisposable = parentDisposable; - myCloudType2ApplicationConfigurable = new HashMap<ServerType<?>, CloudApplicationConfigurable>(); + myApplicationConfigurableTypes = new HashSet<ServerType<?>>(); List<ServerType<?>> cloudTypes = new ArrayList<ServerType<?>>(); - for (CloudModuleBuilderContribution contribution : CloudModuleBuilderContribution.EP_NAME.getExtensions()) { + for (CloudModuleBuilderContributionFactory contribution : CloudModuleBuilderContributionFactory.EP_NAME.getExtensions()) { cloudTypes.add(contribution.getCloudType()); } @@ -86,11 +86,8 @@ public class CloudModuleWizardStep extends ModuleWizardStep { ServerType<?> cloudType = account.getType(); String cardName = cloudType.getId(); - CloudApplicationConfigurable<?, ?, ?, ?> applicationConfigurable = getApplicationConfigurable(); - if (applicationConfigurable == null) { - applicationConfigurable - = CloudModuleBuilderContribution.getInstanceByType(cloudType).createApplicationConfigurable(myProject, myParentDisposable); - myCloudType2ApplicationConfigurable.put(cloudType, applicationConfigurable); + CloudApplicationConfigurable applicationConfigurable = getApplicationConfigurable(); + if (myApplicationConfigurableTypes.add(cloudType)) { myApplicationPanelPlaceHolder.add(applicationConfigurable.getComponent(), cardName); } applicationPlaceHolderLayout.show(myApplicationPanelPlaceHolder, cardName); @@ -103,25 +100,25 @@ public class CloudModuleWizardStep extends ModuleWizardStep { return myMainPanel; } - private CloudApplicationConfigurable<?, ?, ?, ?> getApplicationConfigurable() { + private CloudApplicationConfigurable getApplicationConfigurable() { RemoteServer<?> account = getSelectedAccount(); if (account == null) { return null; } - return myCloudType2ApplicationConfigurable.get(account.getType()); + return myModuleBuilder.getContribution(account.getType()).getApplicationConfigurable(myProject, myParentDisposable); } @Override public void updateDataModel() { myModuleBuilder.setAccount(myAccountSelectionPanel.getSelectedAccount()); - CloudApplicationConfigurable<?, ?, ?, ?> configurable = getApplicationConfigurable(); + CloudApplicationConfigurable configurable = getApplicationConfigurable(); myModuleBuilder.setApplicationConfiguration(configurable == null ? null : configurable.createConfiguration()); } @Override public boolean validate() throws ConfigurationException { myAccountSelectionPanel.validate(); - CloudApplicationConfigurable<?, ?, ?, ?> configurable = getApplicationConfigurable(); + CloudApplicationConfigurable configurable = getApplicationConfigurable(); if (configurable != null) { configurable.validate(); } diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudSourceApplicationConfigurable.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudSourceApplicationConfigurable.java new file mode 100644 index 000000000000..b6e0dfc857b0 --- /dev/null +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudSourceApplicationConfigurable.java @@ -0,0 +1,165 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.remoteServer.impl.module; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.runtime.Deployment; +import com.intellij.remoteServer.runtime.ServerConnection; +import com.intellij.remoteServer.runtime.ServerConnector; +import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance; +import com.intellij.remoteServer.util.*; +import com.intellij.util.concurrency.Semaphore; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.Collection; +import java.util.concurrent.atomic.AtomicReference; + + +public abstract class CloudSourceApplicationConfigurable< + SC extends CloudConfigurationBase, + DC extends CloudDeploymentNameConfiguration, + SR extends CloudMultiSourceServerRuntimeInstance<DC, ?, ?, ?>, + AC extends CloudApplicationConfiguration> extends CloudApplicationConfigurable { + + private final Project myProject; + private final Disposable myParentDisposable; + + private DelayedRunner myRunner; + + private RemoteServer<?> myAccount; + + public CloudSourceApplicationConfigurable(@Nullable Project project, Disposable parentDisposable) { + myProject = project; + myParentDisposable = parentDisposable; + } + + @Override + public void setAccount(RemoteServer<?> account) { + myAccount = account; + clearCloudData(); + } + + protected RemoteServer<SC> getAccount() { + return (RemoteServer<SC>)myAccount; + } + + @Override + public JComponent getComponent() { + JComponent result = getMainPanel(); + if (myRunner == null) { + myRunner = new DelayedRunner(result) { + + private RemoteServer<?> myPreviousAccount; + + @Override + protected boolean wasChanged() { + boolean result = myPreviousAccount != myAccount; + if (result) { + myPreviousAccount = myAccount; + } + return result; + } + + @Override + protected void run() { + loadCloudData(); + } + }; + Disposer.register(myParentDisposable, myRunner); + } + return result; + } + + protected void clearCloudData() { + getExistingComboBox().removeAllItems(); + } + + protected void loadCloudData() { + new ConnectionTask<Collection<Deployment>>("Loading existing applications list") { + + @Override + protected void run(final ServerConnection<DC> connection, + final Semaphore semaphore, + final AtomicReference<Collection<Deployment>> result) { + connection.connectIfNeeded(new ServerConnector.ConnectionCallback<DC>() { + + @Override + public void connected(@NotNull ServerRuntimeInstance<DC> serverRuntimeInstance) { + connection.computeDeployments(new Runnable() { + + @Override + public void run() { + result.set(connection.getDeployments()); + semaphore.up(); + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + if (!Disposer.isDisposed(myParentDisposable)) { + setupExistingApplications(result.get()); + } + } + }); + } + }); + } + + @Override + public void errorOccurred(@NotNull String errorMessage) { + runtimeErrorOccurred(errorMessage); + semaphore.up(); + } + }); + } + + @Override + protected Collection<Deployment> run(SR serverRuntimeInstance) throws ServerRuntimeException { + return null; + } + }.performAsync(); + } + + private void setupExistingApplications(Collection<Deployment> deployments) { + JComboBox existingComboBox = getExistingComboBox(); + existingComboBox.removeAllItems(); + for (Deployment deployment : deployments) { + existingComboBox.addItem(deployment.getName()); + } + } + + protected Project getProject() { + return myProject; + } + + protected abstract JComboBox getExistingComboBox(); + + protected abstract JComponent getMainPanel(); + + @Override + public abstract AC createConfiguration(); + + protected abstract class ConnectionTask<T> extends CloudConnectionTask<T, SC, DC, SR> { + + public ConnectionTask(String title) { + super(myProject, title, CloudSourceApplicationConfigurable.this.getAccount()); + } + } +} diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudSourceApplicationConfiguration.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudSourceApplicationConfiguration.java new file mode 100644 index 000000000000..b1a3df6099ab --- /dev/null +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudSourceApplicationConfiguration.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.remoteServer.impl.module; + + +public abstract class CloudSourceApplicationConfiguration extends CloudApplicationConfiguration { + + private boolean myExisting; + private final String myExistingAppName; + + protected CloudSourceApplicationConfiguration(boolean existing, String existingAppName) { + myExisting = existing; + myExistingAppName = existingAppName; + } + + public boolean isExisting() { + return myExisting; + } + + public String getExistingAppName() { + return myExistingAppName; + } +} |