diff options
Diffstat (limited to 'src/com/google/gct/idea/appengine/deploy/AppEngineUpdater.java')
-rw-r--r-- | src/com/google/gct/idea/appengine/deploy/AppEngineUpdater.java | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/src/com/google/gct/idea/appengine/deploy/AppEngineUpdater.java b/src/com/google/gct/idea/appengine/deploy/AppEngineUpdater.java new file mode 100644 index 0000000..aa48dd4 --- /dev/null +++ b/src/com/google/gct/idea/appengine/deploy/AppEngineUpdater.java @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * 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.google.gct.idea.appengine.deploy; + +import com.android.tools.idea.gradle.invoker.GradleInvoker; +import com.google.common.base.Strings; +import com.google.gct.idea.appengine.sdk.AppEngineSdk; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionManager; +import com.intellij.execution.Executor; +import com.intellij.execution.configurations.CommandLineBuilder; +import com.intellij.execution.configurations.GeneralCommandLine; +import com.intellij.execution.configurations.JavaParameters; +import com.intellij.execution.configurations.ParametersList; +import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.filters.TextConsoleBuilderFactory; +import com.intellij.execution.process.*; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.execution.ui.RunnerLayoutUi; +import com.intellij.execution.ui.actions.CloseAction; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileDocumentManager; +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.ui.Messages; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.KeyValue; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.net.HttpConfigurable; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.util.List; + +/** + * Compiles and deploys a module to AppEngine using AppCfg. + * + * @author benwu + */ +class AppEngineUpdater { + private static final Logger LOG = Logger.getInstance("#com.google.gct.idea.appengine.deploy.AppEngineUpdater"); + private final Project myProject; + private final Module myModule; + private final String myExplodedWarPath; + private final String mySdkPath; + private final String myClientSecret; + private final String myClientId; + private final String myRefreshToken; + private final String myVersion; + private final String myAppEngineProject; + + AppEngineUpdater(Project project, + Module module, + String sdkPath, + String explodedWarPath, + String appEngineProject, + String version, + String clientSecret, + String clientId, + String refreshToken) { + myProject = project; + myModule = module; + mySdkPath = sdkPath; + myExplodedWarPath = explodedWarPath; + myClientSecret = clientSecret; + myClientId = clientId; + myRefreshToken = refreshToken; + myVersion = version; + myAppEngineProject = appEngineProject; + } + + /** + * Starts the compile and upload async process. + */ + void startUploading() { + FileDocumentManager.getInstance().saveAllDocuments(); + ProgressManager.getInstance().run(new Task.Backgroundable(myModule.getProject(), "Deploying application", true, null) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + compileAndUpload(); + } + }); + } + + private void compileAndUpload() { + final Runnable startUploading = new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + startUploadingProcess(); + } + }); + } + }; + + GradleInvoker.getInstance(myProject).compileJava(new Module[]{myModule}); + startUploading.run(); + } + + private void startUploadingProcess() { + final Process process; + final GeneralCommandLine commandLine; + + try { + JavaParameters parameters = new JavaParameters(); + parameters.configureByModule(myModule, JavaParameters.JDK_ONLY); + parameters.setMainClass("com.google.appengine.tools.admin.AppCfg"); + AppEngineSdk mySdk = new AppEngineSdk(mySdkPath); + parameters.getClassPath().add(mySdk.getToolsApiJarFile().getAbsolutePath()); + + final List<KeyValue<String, String>> list = HttpConfigurable.getJvmPropertiesList(false, null); + if (!list.isEmpty()) { + final ParametersList parametersList = parameters.getVMParametersList(); + for (KeyValue<String, String> value : list) { + parametersList.defineProperty(value.getKey(), value.getValue()); + } + } + + final ParametersList programParameters = parameters.getProgramParametersList(); + programParameters.add("--application=" + myAppEngineProject); + if (!Strings.isNullOrEmpty(myVersion)) { + programParameters.add("--version=" + myVersion); + } + programParameters.add("--oauth2"); + programParameters.add("--oauth2_client_secret=" + myClientSecret); + programParameters.add("--oauth2_client_id=" + myClientId); + programParameters.add("--oauth2_refresh_token=" + myRefreshToken); + programParameters.add("update"); + programParameters.add(FileUtil.toSystemDependentName(myExplodedWarPath)); + + commandLine = CommandLineBuilder.createFromJavaParameters(parameters); + + process = commandLine.createProcess(); + } + catch (ExecutionException e) { + final String message = e.getMessage(); + LOG.error("Cannot start uploading: " + message); + + if (!EventQueue.isDispatchThread()) { + EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + Messages.showErrorDialog("Cannot start uploading: " + message, "Error"); + } + }); + } + else { + Messages.showErrorDialog("Cannot start uploading: " + message, "Error"); + } + + return; + } + + final ProcessHandler processHandler = new FilteredOSProcessHandler(process, commandLine.getCommandLineString(), + new String[]{myRefreshToken, myClientSecret, myClientId}); + final Executor executor = DefaultRunExecutor.getRunExecutorInstance(); + final ConsoleView console = TextConsoleBuilderFactory.getInstance().createBuilder(myModule.getProject()).getConsole(); + final RunnerLayoutUi ui = RunnerLayoutUi.Factory.getInstance(myModule.getProject()) + .create("Deploy", "Deploy to AppEngine", "Deploy Application", myModule.getProject()); + final DefaultActionGroup group = new DefaultActionGroup(); + ui.getOptions().setLeftToolbar(group, ActionPlaces.UNKNOWN); + ui.addContent(ui.createContent("upload", console.getComponent(), "Deploy Application", null, console.getPreferredFocusableComponent())); + + console.attachToProcess(processHandler); + final RunContentDescriptor contentDescriptor = + new RunContentDescriptor(console, processHandler, ui.getComponent(), "Deploy to AppEngine"); + group.add(ActionManager.getInstance().getAction(IdeActions.ACTION_STOP_PROGRAM)); + group.add(new CloseAction(executor, contentDescriptor, myModule.getProject())); + + ExecutionManager.getInstance(myModule.getProject()).getContentManager().showRunContent(executor, contentDescriptor); + processHandler.startNotify(); + } + + private class FilteredOSProcessHandler extends OSProcessHandler { + String[] tokensToFilter; + + FilteredOSProcessHandler(@NotNull final Process process, @Nullable final String commandLine, String[] filteredTokens) { + super(process, commandLine); + tokensToFilter = filteredTokens; + } + + @Override + public void notifyTextAvailable(final String text, final Key outputType) { + String newText = text; + if (tokensToFilter != null) { + for (String token : tokensToFilter) { + newText = newText.replace(token, "*****"); + } + } + super.notifyTextAvailable(newText, outputType); + } + } +} |