package com.antfortune.freeline.idea.actions; import com.android.tools.idea.gradle.dsl.model.GradleBuildModel; import com.android.tools.idea.gradle.dsl.model.dependencies.ArtifactDependencyModel; import com.antfortune.freeline.idea.icons.PluginIcons; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.antfortune.freeline.idea.models.ArtifactDependencyModelWrapper; import com.antfortune.freeline.idea.models.GradleDependencyEntity; import com.antfortune.freeline.idea.models.GetServerCallback; import com.antfortune.freeline.idea.models.GradleSyncHandler; import org.jetbrains.annotations.NotNull; import com.antfortune.freeline.idea.utils.*; import com.antfortune.freeline.idea.views.CheckUpdateDialog; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.*; /** * Created by pengwei on 16/9/11. */ public class UpdateAction extends BaseAction implements GetServerCallback { public UpdateAction() { super(PluginIcons.GradleSync); } @Override public void actionPerformed() { if (FreelineUtil.checkInstall(currentProject)) { asyncTask(new GetServerVersion(this)); } } /** * 更新操作 * * @param newVersion * @param gradleBuildModels */ protected void updateAction(final String newVersion, final Map<GradleBuildModel, List<ArtifactDependencyModel>> gradleBuildModels) { CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() { @Override public void run() { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { for (GradleBuildModel file : gradleBuildModels.keySet()) { List<ArtifactDependencyModel> models = gradleBuildModels.get(file); for (ArtifactDependencyModel dependencyModel1 : models) { ArtifactDependencyModelWrapper dependencyModel = new ArtifactDependencyModelWrapper(dependencyModel1); if (isClasspathLibrary(dependencyModel)) { dependencyModel1.setVersion(newVersion); } if (isDependencyLibrary(dependencyModel)) { file.dependencies().remove(dependencyModel1); } } file.applyChanges(); } GradleUtil.executeTask(currentProject, "initFreeline", "-Pmirror", new ExternalSystemTaskNotificationListenerAdapter() { @Override public void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut) { super.onTaskOutput(id, text, stdOut); } }); } }); } }); } /** * 处理结果 * * @param entity * @param gradleBuildModels */ private void resultHandle(final GradleDependencyEntity entity, final Map<GradleBuildModel, List<ArtifactDependencyModel>> gradleBuildModels) { String localVersion = null; StringBuilder builder = new StringBuilder(); for (GradleBuildModel file : gradleBuildModels.keySet()) { List<ArtifactDependencyModel> models = gradleBuildModels.get(file); for (ArtifactDependencyModel dependencyModel1 : models) { ArtifactDependencyModelWrapper dependencyModel = new ArtifactDependencyModelWrapper(dependencyModel1); if (isClasspathLibrary(dependencyModel) || isDependencyLibrary(dependencyModel)) { if (isClasspathLibrary(dependencyModel)) { localVersion = dependencyModel.version(); } builder.append(dependencyModel.configurationName()).append(" '") .append(dependencyModel.group()).append(":") .append(dependencyModel.name()).append(":") .append(dependencyModel.version()).append("'") .append("<br/>"); } } } if (Utils.notEmpty(localVersion)) { int compare = localVersion.compareTo(entity.getVersion()); final CheckUpdateDialog dialog = new CheckUpdateDialog(); dialog.getButtonOK().setEnabled(compare < 0); dialog.setServerVersion(entity.getGroupId(), entity.getArtifactId(), entity.getVersion()); dialog.setServerUpdateTime(entity.getUpdateTime()); dialog.setLocalVersion(builder.toString()); dialog.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { updateAction(entity.getVersion(), gradleBuildModels); dialog.dispose(); } }); dialog.showDialog(); } else { NotificationUtils.infoNotification("please add freeline dependency first"); } } private boolean isClasspathLibrary(ArtifactDependencyModelWrapper model) { return model.configurationName().equals("classpath") && model.group().equals("com.antfortune.freeline") && model.name().equals("gradle"); } private boolean isDependencyLibrary(ArtifactDependencyModelWrapper model) { return model.configurationName().endsWith("ompile") && model.group().equals("com.antfortune.freeline") && model.name().startsWith("runtime"); } @Override public void onSuccess(final GradleDependencyEntity entity) { invokeLater(new Runnable() { @Override public void run() { Collection<VirtualFile> gradleFiles = GradleUtil.getAllGradleFile(currentProject); Map<GradleBuildModel, List<ArtifactDependencyModel>> fileListMap = new HashMap<GradleBuildModel, List<ArtifactDependencyModel>>(); for (VirtualFile file : gradleFiles) { GradleBuildModel model = GradleBuildModel.parseBuildFile(file, currentProject); if (model != null) { List<ArtifactDependencyModel> classPaths = model.buildscript().dependencies().artifacts(); List<ArtifactDependencyModel> depends = model.dependencies().artifacts(); classPaths.addAll(depends); fileListMap.put(model, classPaths); } } resultHandle(entity, fileListMap); } }); } @Override public void onFailure(String errMsg) { NotificationUtils.errorNotification("Update Freeline Failure: " + errMsg); } /** * 获取服务器最新版本 */ public static class GetServerVersion implements Runnable { private GetServerCallback callback; public GetServerVersion(GetServerCallback callback) { this.callback = callback; } @Override public void run() { if (this.callback == null) { return; } try { URL url = new URL("http://jcenter.bintray.com/com/antfortune/freeline/gradle/maven-metadata.xml"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5 * 1000); conn.setRequestMethod("GET"); InputStream inStream = conn.getInputStream(); String result = StreamUtil.inputStream2String(inStream); if (result != null && result.trim().length() != 0) { GradleDependencyEntity entity = GradleDependencyEntity.parse(result); if (entity != null && Utils.notEmpty(entity.getVersion()) && Utils.notEmpty(entity.getGroupId())) { this.callback.onSuccess(entity); } else { this.callback.onFailure("analytic failure"); } } else { this.callback.onFailure("response empty"); } } catch (IOException e) { this.callback.onFailure(e.getMessage()); } } } }