From 54aeaeb28c941bd2e4902ddb1c813f365edac75e Mon Sep 17 00:00:00 2001 From: pengwei Date: Thu, 3 Nov 2016 10:12:49 +0800 Subject: [PATCH] add : install freeline automatic --- .../resources/META-INF/plugin.xml | 6 +- .../src/actions/BaseAction.java | 23 +- .../src/actions/FreelineRunAction.java | 3 +- .../src/actions/UpdateAction.java | 26 +- .../FreeConfigurationFactory.java | 4 +- .../configuration/FreeRunConfiguration.java | 6 +- .../{resources => src}/icons/OpenTerminal.png | Bin .../icons/OpenTerminal@2x.png | Bin .../src/icons/PluginIcons.java | 6 +- .../{resources => src}/icons/bg_update.png | Bin .../{resources => src}/icons/debug.png | Bin .../{resources => src}/icons/debug@2x.png | Bin .../{resources => src}/icons/gradlesync.png | Bin .../icons/gradlesync@2x.png | Bin .../{resources => src}/icons/icon.png | Bin .../{resources => src}/icons/icon@2x.png | Bin .../{resources => src}/icons/play2.png | Bin .../{resources => src}/icons/play2@2x.png | Bin .../ArtifactDependencyModelWrapper.java | 2 + .../src/models/Constant.java | 24 ++ .../src/models/FreelineStatus.java | 82 +++++ .../src/utils/DialogUtil.java | 30 ++ .../src/utils/DocumentUtil.java | 18 + android-studio-plugin/src/utils/FreeUtil.java | 138 ------- .../src/utils/FreelineUtil.java | 342 ++++++++++++++++++ .../src/utils/GradleUtil.java | 61 ++++ .../src/utils/GroovyFileUil.java | 53 +++ android-studio-plugin/src/utils/LogUtil.java | 31 ++ .../src/utils/NotificationUtils.java | 13 +- .../src/utils/SystemUtil.java | 30 -- android-studio-plugin/src/utils/Utils.java | 6 +- .../src/views/FreelineTerminal.java | 28 +- .../src/views/ImageJPanel.java | 4 +- 33 files changed, 698 insertions(+), 238 deletions(-) rename android-studio-plugin/{resources => src}/icons/OpenTerminal.png (100%) rename android-studio-plugin/{resources => src}/icons/OpenTerminal@2x.png (100%) rename android-studio-plugin/{resources => src}/icons/bg_update.png (100%) rename android-studio-plugin/{resources => src}/icons/debug.png (100%) rename android-studio-plugin/{resources => src}/icons/debug@2x.png (100%) rename android-studio-plugin/{resources => src}/icons/gradlesync.png (100%) rename android-studio-plugin/{resources => src}/icons/gradlesync@2x.png (100%) rename android-studio-plugin/{resources => src}/icons/icon.png (100%) rename android-studio-plugin/{resources => src}/icons/icon@2x.png (100%) rename android-studio-plugin/{resources => src}/icons/play2.png (100%) rename android-studio-plugin/{resources => src}/icons/play2@2x.png (100%) create mode 100644 android-studio-plugin/src/models/Constant.java create mode 100644 android-studio-plugin/src/models/FreelineStatus.java create mode 100644 android-studio-plugin/src/utils/DialogUtil.java create mode 100644 android-studio-plugin/src/utils/DocumentUtil.java delete mode 100644 android-studio-plugin/src/utils/FreeUtil.java create mode 100644 android-studio-plugin/src/utils/FreelineUtil.java create mode 100644 android-studio-plugin/src/utils/GroovyFileUil.java create mode 100644 android-studio-plugin/src/utils/LogUtil.java delete mode 100644 android-studio-plugin/src/utils/SystemUtil.java diff --git a/android-studio-plugin/resources/META-INF/plugin.xml b/android-studio-plugin/resources/META-INF/plugin.xml index 8ceb7c0..89bed33 100644 --- a/android-studio-plugin/resources/META-INF/plugin.xml +++ b/android-studio-plugin/resources/META-INF/plugin.xml @@ -1,7 +1,7 @@ com.apkfuns.plugin.freeline Freeline Plugin - 1.0.9.1 + 1.1.0 act262、舞影凌风 +
  • + 1.1.0
    + add Automatic integration +
  • 1.0.9
    add default run action shortcut、support jdk 1.7+ diff --git a/android-studio-plugin/src/actions/BaseAction.java b/android-studio-plugin/src/actions/BaseAction.java index d657a4f..b562349 100644 --- a/android-studio-plugin/src/actions/BaseAction.java +++ b/android-studio-plugin/src/actions/BaseAction.java @@ -4,9 +4,8 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataKeys; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; -import utils.NotificationUtils; +import utils.DocumentUtil; import java.io.File; @@ -21,33 +20,15 @@ public abstract class BaseAction extends AnAction { @Override public final void actionPerformed(AnActionEvent anActionEvent) { - saveDocument(); + DocumentUtil.saveDocument(); this.anActionEvent = anActionEvent; this.currentProject = DataKeys.PROJECT.getData(anActionEvent.getDataContext()); this.projectDir = new File(currentProject.getBasePath()); actionPerformed(); } - private void saveDocument() { - FileDocumentManager.getInstance().saveAllDocuments(); - ApplicationManager.getApplication().saveSettings(); - } - public abstract void actionPerformed(); - /** - * 检查Freeline是否存在 - * - * @return - */ - protected boolean checkFreelineExist() { - File pyFile = new File(projectDir, "freeline.py"); - if (pyFile.exists()) { - return true; - } - NotificationUtils.errorNotification("please install Freeline first"); - return false; - } /** * 异步执行 diff --git a/android-studio-plugin/src/actions/FreelineRunAction.java b/android-studio-plugin/src/actions/FreelineRunAction.java index 782fe9b..cf9800a 100644 --- a/android-studio-plugin/src/actions/FreelineRunAction.java +++ b/android-studio-plugin/src/actions/FreelineRunAction.java @@ -1,5 +1,6 @@ package actions; +import utils.FreelineUtil; import utils.NotificationUtils; import utils.Utils; import views.FreelineTerminal; @@ -10,7 +11,7 @@ public class FreelineRunAction extends BaseAction { @Override public void actionPerformed() { - if (checkFreelineExist()) { + if (FreelineUtil.checkInstall(currentProject)) { String python = Utils.getPythonLocation(); if (python == null) { NotificationUtils.errorNotification("command 'python' not found"); diff --git a/android-studio-plugin/src/actions/UpdateAction.java b/android-studio-plugin/src/actions/UpdateAction.java index 6e48e6e..bb44084 100644 --- a/android-studio-plugin/src/actions/UpdateAction.java +++ b/android-studio-plugin/src/actions/UpdateAction.java @@ -9,25 +9,16 @@ import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.search.FilenameIndex; -import com.intellij.psi.search.GlobalSearchScope; import models.ArtifactDependencyModelWrapper; import models.GradleDependencyEntity; import models.GetServerCallback; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.gradle.util.GradleConstants; -import utils.GradleUtil; -import utils.NotificationUtils; -import utils.StreamUtil; -import utils.Utils; +import utils.*; import views.CheckUpdateDialog; 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.*; /** @@ -37,10 +28,9 @@ public class UpdateAction extends BaseAction implements GetServerCallback { @Override public void actionPerformed() { - if (checkFreelineExist()) { + FreelineUtil.hasInitFreeline(currentProject); + if (FreelineUtil.checkInstall(currentProject)) { asyncTask(new GetServerVersion(this)); - } else { - GradleUtil.executeTask(currentProject, "initFreeline", "-Pmirror", null); } } @@ -160,8 +150,7 @@ public void onSuccess(final GradleDependencyEntity entity) { invokeLater(new Runnable() { @Override public void run() { - Collection gradleFiles = FilenameIndex.getVirtualFilesByName(currentProject, - GradleConstants.DEFAULT_SCRIPT_NAME, GlobalSearchScope.allScope(currentProject)); + Collection gradleFiles = GradleUtil.getAllGradleFile(currentProject); Map> fileListMap = new HashMap<>(); for (VirtualFile file : gradleFiles) { GradleBuildModel model = GradleBuildModel.parseBuildFile(file, currentProject); @@ -198,12 +187,7 @@ public void run() { 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); + String result = FreelineUtil.syncGetFreelineVersion(); if (result != null && result.trim().length() != 0) { GradleDependencyEntity entity = GradleDependencyEntity.parse(result); if (entity != null && Utils.notEmpty(entity.getVersion()) diff --git a/android-studio-plugin/src/configuration/FreeConfigurationFactory.java b/android-studio-plugin/src/configuration/FreeConfigurationFactory.java index f122fd0..7159486 100644 --- a/android-studio-plugin/src/configuration/FreeConfigurationFactory.java +++ b/android-studio-plugin/src/configuration/FreeConfigurationFactory.java @@ -5,7 +5,7 @@ import com.intellij.execution.configurations.RunConfiguration; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; -import utils.FreeUtil; +import utils.FreelineUtil; /** * Freeline Configuration Factory @@ -27,7 +27,7 @@ public RunConfiguration createTemplateConfiguration(@NotNull Project project) { @Override public boolean isApplicable(@NotNull Project project) { // enabled only had init project - return FreeUtil.hadInitFreeline(project); + return FreelineUtil.hadInitFreeline(project); } @Override diff --git a/android-studio-plugin/src/configuration/FreeRunConfiguration.java b/android-studio-plugin/src/configuration/FreeRunConfiguration.java index 5c94e77..0d52292 100644 --- a/android-studio-plugin/src/configuration/FreeRunConfiguration.java +++ b/android-studio-plugin/src/configuration/FreeRunConfiguration.java @@ -12,7 +12,7 @@ import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import utils.FreeUtil; +import utils.FreelineUtil; /** * Freeline run configuration implementation @@ -34,7 +34,7 @@ public SettingsEditor getConfigurationEditor() { @Override public void checkConfiguration() throws RuntimeConfigurationException { - if (!FreeUtil.hadInitFreeline(getProject())) { + if (!FreelineUtil.hadInitFreeline(getProject())) { throw new RuntimeConfigurationException("Not yet initialize freeline code", "Warning"); } } @@ -58,7 +58,7 @@ private class FreeRunState extends CommandLineState { @NotNull @Override protected ProcessHandler startProcess() throws ExecutionException { - if (!FreeUtil.hadInitFreeline(getProject())) { + if (!FreelineUtil.hadInitFreeline(getProject())) { throw new CantRunException("Not yet initialized freeline code"); } // here just run one command: python freeline.py diff --git a/android-studio-plugin/resources/icons/OpenTerminal.png b/android-studio-plugin/src/icons/OpenTerminal.png similarity index 100% rename from android-studio-plugin/resources/icons/OpenTerminal.png rename to android-studio-plugin/src/icons/OpenTerminal.png diff --git a/android-studio-plugin/resources/icons/OpenTerminal@2x.png b/android-studio-plugin/src/icons/OpenTerminal@2x.png similarity index 100% rename from android-studio-plugin/resources/icons/OpenTerminal@2x.png rename to android-studio-plugin/src/icons/OpenTerminal@2x.png diff --git a/android-studio-plugin/src/icons/PluginIcons.java b/android-studio-plugin/src/icons/PluginIcons.java index a2122ff..61195b9 100644 --- a/android-studio-plugin/src/icons/PluginIcons.java +++ b/android-studio-plugin/src/icons/PluginIcons.java @@ -25,7 +25,11 @@ public class PluginIcons { public static final Icon ICON_TOOL_WINDOW = OpenTerminal; private static Icon load(String path) { - return IconLoader.getIcon(path, PluginIcons.class); + try { + return IconLoader.getIcon(path, PluginIcons.class); + } catch (IllegalStateException e) { + return null; + } } private static Icon androidLoad(String path) { diff --git a/android-studio-plugin/resources/icons/bg_update.png b/android-studio-plugin/src/icons/bg_update.png similarity index 100% rename from android-studio-plugin/resources/icons/bg_update.png rename to android-studio-plugin/src/icons/bg_update.png diff --git a/android-studio-plugin/resources/icons/debug.png b/android-studio-plugin/src/icons/debug.png similarity index 100% rename from android-studio-plugin/resources/icons/debug.png rename to android-studio-plugin/src/icons/debug.png diff --git a/android-studio-plugin/resources/icons/debug@2x.png b/android-studio-plugin/src/icons/debug@2x.png similarity index 100% rename from android-studio-plugin/resources/icons/debug@2x.png rename to android-studio-plugin/src/icons/debug@2x.png diff --git a/android-studio-plugin/resources/icons/gradlesync.png b/android-studio-plugin/src/icons/gradlesync.png similarity index 100% rename from android-studio-plugin/resources/icons/gradlesync.png rename to android-studio-plugin/src/icons/gradlesync.png diff --git a/android-studio-plugin/resources/icons/gradlesync@2x.png b/android-studio-plugin/src/icons/gradlesync@2x.png similarity index 100% rename from android-studio-plugin/resources/icons/gradlesync@2x.png rename to android-studio-plugin/src/icons/gradlesync@2x.png diff --git a/android-studio-plugin/resources/icons/icon.png b/android-studio-plugin/src/icons/icon.png similarity index 100% rename from android-studio-plugin/resources/icons/icon.png rename to android-studio-plugin/src/icons/icon.png diff --git a/android-studio-plugin/resources/icons/icon@2x.png b/android-studio-plugin/src/icons/icon@2x.png similarity index 100% rename from android-studio-plugin/resources/icons/icon@2x.png rename to android-studio-plugin/src/icons/icon@2x.png diff --git a/android-studio-plugin/resources/icons/play2.png b/android-studio-plugin/src/icons/play2.png similarity index 100% rename from android-studio-plugin/resources/icons/play2.png rename to android-studio-plugin/src/icons/play2.png diff --git a/android-studio-plugin/resources/icons/play2@2x.png b/android-studio-plugin/src/icons/play2@2x.png similarity index 100% rename from android-studio-plugin/resources/icons/play2@2x.png rename to android-studio-plugin/src/icons/play2@2x.png diff --git a/android-studio-plugin/src/models/ArtifactDependencyModelWrapper.java b/android-studio-plugin/src/models/ArtifactDependencyModelWrapper.java index b3f1c27..ec82deb 100644 --- a/android-studio-plugin/src/models/ArtifactDependencyModelWrapper.java +++ b/android-studio-plugin/src/models/ArtifactDependencyModelWrapper.java @@ -8,6 +8,8 @@ /** * Created by pengwei on 16/9/14. + * 兼容android studio不同版本 + * 2.1.2之前版本name()方法返回string, 之后返回GradleNullableValue */ public class ArtifactDependencyModelWrapper { diff --git a/android-studio-plugin/src/models/Constant.java b/android-studio-plugin/src/models/Constant.java new file mode 100644 index 0000000..3011e7d --- /dev/null +++ b/android-studio-plugin/src/models/Constant.java @@ -0,0 +1,24 @@ +package models; + +/** + * Created by pengwei on 2016/10/22. + */ +public interface Constant { + + boolean DEBUG_MODE = true; + + // groupId + String FREELINE_CLASSPATH_GROUP = "com.antfortune.freeline"; + // artifactId + String FREELINE_CLASSPATH_ARTIFACT = "gradle"; + // plugin name + String FREELINE_PLUGIN_ID = "com.antfortune.freeline"; + + // root folder + String FREELINE_ROOT_FOLDER = "freeline"; + String FREELINE_ROOT_FOLDER_CORE = "freeline_core"; + String FREELINE_PYTHON = "freeline.py"; + + // gradle tool + String ANDROID_GRADLE_TOOL_GROUP_NAME = "com.android.tools.build"; +} diff --git a/android-studio-plugin/src/models/FreelineStatus.java b/android-studio-plugin/src/models/FreelineStatus.java new file mode 100644 index 0000000..75bedce --- /dev/null +++ b/android-studio-plugin/src/models/FreelineStatus.java @@ -0,0 +1,82 @@ +package models; + +import com.intellij.openapi.vfs.VirtualFile; +import utils.LogUtil; + +import java.util.Collection; + +/** + * Created by pengwei on 2016/10/31. + */ +public class FreelineStatus { + Collection gradleBuildFiles; + boolean existClasspath = false; + private VirtualFile classpathFile; + boolean existPlugin = false; + private VirtualFile pluginFile; + // mac下只有freeline文件夹 + freeline.py , win下有freeline.py + freeline/ + freeline_core/ + boolean existFreelineCore = false; + + public FreelineStatus setClasspathFile(VirtualFile classpathFile) { + this.classpathFile = classpathFile; + if (classpathFile != null) { + existClasspath = true; + } + return this; + } + + public FreelineStatus setPluginFile(VirtualFile pluginFile) { + this.pluginFile = pluginFile; + if (pluginFile != null) { + existPlugin = true; + } + return this; + } + + public FreelineStatus setExistFreelineCore(boolean existFreelineCore) { + this.existFreelineCore = existFreelineCore; + return this; + } + + public boolean isExistClasspath() { + return existClasspath; + } + + public VirtualFile getClasspathFile() { + return classpathFile; + } + + public boolean isExistPlugin() { + return existPlugin; + } + + public VirtualFile getPluginFile() { + return pluginFile; + } + + public boolean isExistFreelineCore() { + return existFreelineCore; + } + + /** + * 是否初始化Freeline + * 满足一下三个条件 + * 1. 存在classpath 'com.antfortune.freeline:gradle:*' + * 2. 存在apply plugin: 'com.antfortune.freeline' + * 3. 存在freeline_core、release_tools、freeline.py + * @return + */ + public boolean hasInitFreeline() { + LogUtil.d("existClasspath=%s,existPlugin=%s,existFreelineCore=%s", existClasspath, existPlugin, existFreelineCore); + return existClasspath && existPlugin && existFreelineCore; + } + + public Collection getGradleBuildFiles() { + return gradleBuildFiles; + } + + public FreelineStatus setGradleBuildFiles(Collection gradleBuildFiles) { + this.gradleBuildFiles = gradleBuildFiles; + return this; + } +} diff --git a/android-studio-plugin/src/utils/DialogUtil.java b/android-studio-plugin/src/utils/DialogUtil.java new file mode 100644 index 0000000..cfdd849 --- /dev/null +++ b/android-studio-plugin/src/utils/DialogUtil.java @@ -0,0 +1,30 @@ +package utils; + +import com.intellij.openapi.ui.DialogBuilder; +import com.intellij.openapi.ui.Messages; + +import javax.swing.*; + +/** + * Created by pengwei on 2016/11/2. + */ +public final class DialogUtil { + + /** + * 创建普通对话框 + * @param message + * @param okText + * @param cancelText + * @return + */ + public static boolean createDialog(String message, String okText, String cancelText) { + DialogBuilder builder = new DialogBuilder(); + builder.setTitle("Dialog Message"); + builder.resizable(false); + builder.setCenterPanel(new JLabel(message, Messages.getInformationIcon(), SwingConstants.CENTER)); + builder.addOkAction().setText(okText); + builder.addCancelAction().setText(cancelText); + builder.setButtonsAlignment(SwingConstants.CENTER); + return builder.show() == 0; + } +} diff --git a/android-studio-plugin/src/utils/DocumentUtil.java b/android-studio-plugin/src/utils/DocumentUtil.java new file mode 100644 index 0000000..81565de --- /dev/null +++ b/android-studio-plugin/src/utils/DocumentUtil.java @@ -0,0 +1,18 @@ +package utils; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileEditor.FileDocumentManager; + +/** + * Created by pengwei on 2016/11/1. + */ +public class DocumentUtil { + + /** + * 保存文档和设置 + */ + public static void saveDocument() { + FileDocumentManager.getInstance().saveAllDocuments(); + ApplicationManager.getApplication().saveSettings(); + } +} diff --git a/android-studio-plugin/src/utils/FreeUtil.java b/android-studio-plugin/src/utils/FreeUtil.java deleted file mode 100644 index 24135c6..0000000 --- a/android-studio-plugin/src/utils/FreeUtil.java +++ /dev/null @@ -1,138 +0,0 @@ -package utils; - -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.GeneralCommandLine; -import com.intellij.execution.process.OSProcessHandler; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.process.ProcessTerminatedListener; -import com.intellij.execution.ui.ConsoleView; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.wm.ToolWindow; -import com.intellij.openapi.wm.ToolWindowAnchor; -import com.intellij.openapi.wm.ToolWindowManager; -import com.intellij.ui.content.impl.ContentImpl; -import icons.PluginIcons; - -import java.io.File; - -/** - * Freeline Utility - * - * @author act262@gmail.com - */ -public class FreeUtil { - - // TODO: 2016/9/13 0013 need refactor tool window - private final static String TOOL_ID = "Freeline Console"; - - /** - * auto select init or run freeline project - */ - public static void initOrBuild(Project project) { - // TODO: 2016/9/14 0014 need to handle timeout or frequently operation - // execute freeline script - if (hadInitFreeline(project)) { - build(project); - } else { - initFree(project); - } - } - - public static void build(Project project) { - GeneralCommandLine commandLine = new GeneralCommandLine(); - commandLine.setWorkDirectory(project.getBasePath()); - commandLine.setExePath("python"); - commandLine.addParameter("freeline.py"); - // debug - commandLine.addParameter("-d"); - - // commands process - try { - processCommandline(project, commandLine); - } catch (ExecutionException e) { - e.printStackTrace(); - } - } - - public static void initFree(Project project) { - GeneralCommandLine commandLine = new GeneralCommandLine(); - commandLine.setWorkDirectory(project.getBasePath()); - - // init freeline core file - if (SystemUtil.isWindows()) { - commandLine.setExePath("cmd"); - commandLine.addParameter("/c"); - commandLine.addParameter("gradlew.bat"); - } else { - commandLine.setExePath("/bin/sh"); - commandLine.addParameter("-c"); - commandLine.addParameter("./gradlew"); - } - commandLine.addParameters("initFreeline", "-Pmirror"); - - // commands process - try { - processCommandline(project, commandLine); - } catch (ExecutionException e) { - e.printStackTrace(); - } - } - - /* process command line */ - private static void processCommandline(final Project project, GeneralCommandLine commandLine) throws ExecutionException { - final OSProcessHandler processHandler = new OSProcessHandler(commandLine); - ProcessTerminatedListener.attach(processHandler); - processHandler.startNotify(); - - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - processConsole(project, processHandler); - } - }); - } - - /* process attach to console,show the log */ - // TODO: 2016/9/14 0014 need refactor console method - private static void processConsole(Project project, ProcessHandler processHandler) { - ConsoleView consoleView = FreeUIManager.getInstance(project).getConsoleView(project); - consoleView.clear(); - consoleView.attachToProcess(processHandler); - - ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project); - ToolWindow toolWindow; - toolWindow = toolWindowManager.getToolWindow(TOOL_ID); - - // if already exist tool window then show it - if (toolWindow != null) { - toolWindow.show(null); - return; - } - - toolWindow = toolWindowManager.registerToolWindow(TOOL_ID, true, ToolWindowAnchor.BOTTOM); - toolWindow.setTitle("free...."); - toolWindow.setStripeTitle("Free Console"); - toolWindow.setShowStripeButton(true); - toolWindow.setIcon(PluginIcons.ICON_TOOL_WINDOW); - toolWindow.getContentManager().addContent(new ContentImpl(consoleView.getComponent(), "Build", true)); - toolWindow.show(null); - } - - /** - * if had init freeline return true - */ - public static boolean hadInitFreeline(Project project) { - if (project != null) { - String projectPath = project.getBasePath(); - // freeline directory - File freelineDir = new File(projectPath, "freeline"); - // freeline.py file - File freeline_py = new File(projectPath, "freeline.py"); - if (freelineDir.exists() && freeline_py.exists()) { - return true; - } - } - return false; - } -} diff --git a/android-studio-plugin/src/utils/FreelineUtil.java b/android-studio-plugin/src/utils/FreelineUtil.java new file mode 100644 index 0000000..ddeba56 --- /dev/null +++ b/android-studio-plugin/src/utils/FreelineUtil.java @@ -0,0 +1,342 @@ +package utils; + +import com.android.tools.idea.gradle.AndroidGradleModel; +import com.android.tools.idea.gradle.dsl.model.GradleBuildModel; +import com.android.tools.idea.gradle.dsl.model.dependencies.ArtifactDependencyModel; +import com.android.tools.idea.gradle.dsl.model.dependencies.ArtifactDependencySpec; +import com.android.tools.idea.gradle.parser.GradleBuildFile; +import com.android.tools.idea.gradle.project.GradleSyncListener; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.GeneralCommandLine; +import com.intellij.execution.process.OSProcessHandler; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.process.ProcessTerminatedListener; +import com.intellij.execution.ui.ConsoleView; +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.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogBuilder; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.psi.PsiFile; +import com.intellij.ui.content.impl.ContentImpl; +import icons.PluginIcons; +import models.ArtifactDependencyModelWrapper; +import models.Constant; +import models.FreelineStatus; +import models.GradleDependencyEntity; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Freeline Utility + * + * @author act262@gmail.com + */ +public class FreelineUtil { + + // TODO: 2016/9/13 0013 need refactor tool window + private final static String TOOL_ID = "Freeline Console"; + + public static void build(Project project) { + GeneralCommandLine commandLine = new GeneralCommandLine(); + commandLine.setWorkDirectory(project.getBasePath()); + commandLine.setExePath("python"); + commandLine.addParameter("freeline.py"); + // debug + commandLine.addParameter("-d"); + + // commands process + try { + processCommandline(project, commandLine); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } + + /* process command line */ + private static void processCommandline(final Project project, GeneralCommandLine commandLine) throws ExecutionException { + final OSProcessHandler processHandler = new OSProcessHandler(commandLine); + ProcessTerminatedListener.attach(processHandler); + processHandler.startNotify(); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + processConsole(project, processHandler); + } + }); + } + + /* process attach to console,show the log */ + // TODO: 2016/9/14 0014 need refactor console method + private static void processConsole(Project project, ProcessHandler processHandler) { + ConsoleView consoleView = FreeUIManager.getInstance(project).getConsoleView(project); + consoleView.clear(); + consoleView.attachToProcess(processHandler); + + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project); + ToolWindow toolWindow; + toolWindow = toolWindowManager.getToolWindow(TOOL_ID); + + // if already exist tool window then show it + if (toolWindow != null) { + toolWindow.show(null); + return; + } + + toolWindow = toolWindowManager.registerToolWindow(TOOL_ID, true, ToolWindowAnchor.BOTTOM); + toolWindow.setTitle("free...."); + toolWindow.setStripeTitle("Free Console"); + toolWindow.setShowStripeButton(true); + toolWindow.setIcon(PluginIcons.ICON_TOOL_WINDOW); + toolWindow.getContentManager().addContent(new ContentImpl(consoleView.getComponent(), "Build", true)); + toolWindow.show(null); + } + + /** + * if had init freeline return true + */ + public static boolean hadInitFreeline(Project project) { + if (project != null) { + String projectPath = project.getBasePath(); + // freeline directory + File freelineDir = new File(projectPath, "freeline"); + // freeline.py file + File freeline_py = new File(projectPath, "freeline.py"); + if (freelineDir.exists() && freeline_py.exists()) { + return true; + } + } + return false; + } + + /** + * 是否载入freeline + * + * @param project + * @return + */ + public static boolean hasInitFreeline(@NotNull Project project) { + return getFreelineStatus(project).hasInitFreeline(); + } + + /** + * 获取freeline安装状态 + * + * @param project + * @return + */ + public static FreelineStatus getFreelineStatus(@NotNull Project project) { + FreelineStatus status = new FreelineStatus(); + Collection gradleFiles = GradleUtil.getAllGradleFile(project); + status.setGradleBuildFiles(gradleFiles); + for (VirtualFile file : gradleFiles) { + GradleBuildModel model = GradleBuildModel.parseBuildFile(file, project); + if (model != null) { + List classPaths = model.buildscript().dependencies().artifacts(); + for (ArtifactDependencyModel classpath : classPaths) { + ArtifactDependencyModelWrapper wrapper = new ArtifactDependencyModelWrapper(classpath); + if (wrapper.group().equals(Constant.FREELINE_CLASSPATH_GROUP) + && wrapper.name().equals(Constant.FREELINE_CLASSPATH_ARTIFACT)) { + status.setClasspathFile(file); + } + } + } + GradleBuildFile gradleBuildFile = new GradleBuildFile(file, project); + if (gradleBuildFile != null) { + List plugins = gradleBuildFile.getPlugins(); + if (plugins.contains(Constant.FREELINE_PLUGIN_ID)) { + status.setPluginFile(file); + } + } + if (status.isExistClasspath() && status.isExistPlugin()) { + break; + } + } + File baseFile = new File(project.getBasePath()); + if (new File(baseFile, Constant.FREELINE_ROOT_FOLDER).exists() + && new File(baseFile, Constant.FREELINE_PYTHON).exists()) { + if (SystemInfo.isWindows) { + if (new File(baseFile, Constant.FREELINE_ROOT_FOLDER_CORE).exists()) { + status.setExistFreelineCore(true); + } + } else { + status.setExistFreelineCore(true); + } + } + return status; + } + + /** + * 检查是否需要载入Freeline + * + * @param project + * @return + */ + public static boolean checkInstall(@NotNull Project project) { + FreelineStatus status = getFreelineStatus(project); + if (status.hasInitFreeline()) { + return true; + } + if (status.getGradleBuildFiles().size() < 1) { + NotificationUtils.errorMsgDialog("It's not an Android Gradle project Currently?"); + return false; + } + if (DialogUtil.createDialog("Detected that you did not install Freeline, Whether install Automatically?", + "Install Freeline Automatically", "Cancel")) { + Module[] modules = ModuleManager.getInstance(project).getModules(); + List> selectModulesList = new ArrayList<>(); + for (Module module : modules) { + AndroidGradleModel model = AndroidGradleModel.get(module); + GradleBuildFile file = GradleBuildFile.get(module); + if (file != null && model != null) { + if (!model.isLibrary()) { + selectModulesList.add(Pair.create(module, file.getPsiFile())); + } + } + } + // 多个app模块的情况 + if (selectModulesList.size() > 1) { + DialogBuilder builder = new DialogBuilder(); + builder.setTitle("Install Freeline"); + builder.resizable(false); + builder.setCenterPanel(new JLabel("There are multiple application modules, Please select the module to be installed Freeline.", + Messages.getInformationIcon(), SwingConstants.CENTER)); + builder.addOkAction().setText("Cancel"); + for (Pair pair : selectModulesList) { + builder.addAction(new AbstractAction(":" + pair.first.getName()) { + @Override + public void actionPerformed(ActionEvent e) { + builder.getDialogWrapper().close(DialogWrapper.CANCEL_EXIT_CODE); + install(project, status, pair.getSecond()); + } + }); + } + if (builder.show() > -1) { + return false; + } + } else if (selectModulesList.size() == 1) { + install(project, status, selectModulesList.get(0).getSecond()); + } else { + NotificationUtils.errorMsgDialog("Can not found Application Module! Please Sync Project."); + return false; + } + } + return false; + } + + /** + * 载入Freeline + * + * @param project + * @param status + * @param psiFile + */ + private static void install(Project project, FreelineStatus status, PsiFile psiFile) { + CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + if (!status.isExistClasspath()) { + Collection collection = status.getGradleBuildFiles(); + GradleDependencyEntity dependencyEntity = syncGetFreelineVersionEntity(); + if (dependencyEntity != null) { + for (VirtualFile file : collection) { + GradleBuildModel model = GradleBuildModel.parseBuildFile(file, project); + List artifactDependencyModels = model.buildscript().dependencies().artifacts(); + boolean hadFind = false; + for (ArtifactDependencyModel model1 : artifactDependencyModels) { + ArtifactDependencyModelWrapper wrapper = new ArtifactDependencyModelWrapper(model1); + System.out.println(wrapper.group() + "&" + wrapper.name()); + if (wrapper.group().equals(Constant.ANDROID_GRADLE_TOOL_GROUP_NAME)) { + ArtifactDependencySpec spec = new ArtifactDependencySpec(dependencyEntity.getArtifactId(), + dependencyEntity.getGroupId(), dependencyEntity.getVersion()); + model.buildscript().dependencies().addArtifact("classpath", spec); + model.applyChanges(); + hadFind = true; + break; + } + } + if (hadFind) { + break; + } + } + } + } + if (!status.isExistPlugin()) { + if (psiFile != null && psiFile instanceof GroovyFile) { + GradleUtil.applyPlugin(project, (GroovyFile) psiFile, Constant.FREELINE_PLUGIN_ID); + } + } + GradleUtil.startSync(project, new GradleSyncListener.Adapter() { + @Override + public void syncSucceeded(@NotNull Project project) { + super.syncSucceeded(project); + GradleUtil.executeTask(project, "initFreeline", "-Pmirror", new ExternalSystemTaskNotificationListenerAdapter() { + @Override + public void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut) { + super.onTaskOutput(id, text, stdOut); + } + }); + } + }); + } + }); + } + }); + } + + /** + * 同步获取Freeline版本 + * @return + */ + public static String syncGetFreelineVersion() throws IOException { + 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); + return result; + } + + public static GradleDependencyEntity syncGetFreelineVersionEntity() { + try { + String result = syncGetFreelineVersion(); + if (result != null && result.trim().length() != 0) { + GradleDependencyEntity entity = GradleDependencyEntity.parse(result); + if (entity.getGroupId() != null && entity.getArtifactId() != null) { + return entity; + } + } + } catch (IOException e) { + + } + NotificationUtils.errorNotification("Get Freeline Version Failure."); + return null; + } +} diff --git a/android-studio-plugin/src/utils/GradleUtil.java b/android-studio-plugin/src/utils/GradleUtil.java index 10a5db8..ddded40 100644 --- a/android-studio-plugin/src/utils/GradleUtil.java +++ b/android-studio-plugin/src/utils/GradleUtil.java @@ -1,14 +1,28 @@ package utils; +import com.android.tools.idea.gradle.parser.GradleBuildFile; import com.android.tools.idea.gradle.project.GradleProjectImporter; import com.android.tools.idea.gradle.project.GradleSyncListener; import com.android.tools.idea.gradle.task.AndroidGradleTaskManager; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.plugins.gradle.util.GradleConstants; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrBlockStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import java.util.*; @@ -54,4 +68,51 @@ public static void executeTask(Project project, String taskName, String args, Ex ExternalSystemTaskId.create(GradleConstants.SYSTEM_ID, ExternalSystemTaskType.EXECUTE_TASK, project), taskNames, project.getBasePath(), null, vmOptions, params, null, listener); } + + /** + * 查找所有的build.gradle文件 + * + * @param project + * @return + */ + public static Collection getAllGradleFile(Project project) { + Collection collection = FilenameIndex.getVirtualFilesByName(project, + GradleConstants.DEFAULT_SCRIPT_NAME, GlobalSearchScope.allScope(project)); + return collection == null ? Collections.EMPTY_LIST : collection; + } + + /** + * 插入插件的表达式 + * apply plugin: 'com.antfortune.freeline' + * + * @param project + * @param psiFile + * @param pluginId + */ + public static void applyPlugin(Project project, GroovyFile psiFile, String pluginId) { + GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project); + GrStatement grStatement = factory.createExpressionFromText(String.format("apply plugin: \'%s\'", + new Object[]{pluginId}), null); + GrExpression expression = GroovyFileUil.getLastPlugin(psiFile); + if (expression != null && expression.getParent() != null) { + psiFile.addAfter(grStatement, expression.getParent()); + // 换行 + psiFile.addAfter(factory.createLineTerminator("\n"), expression.getParent()); + } + PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); + Document document = documentManager.getDocument(psiFile); + if (document != null) { + documentManager.commitDocument(document); + } + } + + public static void applyPlugin(Project project, VirtualFile file, String pluginId) { + GradleBuildFile gradleBuildFile = new GradleBuildFile(file, project); + if (gradleBuildFile != null) { + PsiFile psiFile = gradleBuildFile.getPsiFile(); + if (psiFile != null && psiFile instanceof GroovyFile) { + applyPlugin(project, (GroovyFile) psiFile, pluginId); + } + } + } } diff --git a/android-studio-plugin/src/utils/GroovyFileUil.java b/android-studio-plugin/src/utils/GroovyFileUil.java new file mode 100644 index 0000000..ebd08cf --- /dev/null +++ b/android-studio-plugin/src/utils/GroovyFileUil.java @@ -0,0 +1,53 @@ +package utils; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; +import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner; + +import java.util.Arrays; +import java.util.Iterator; + +/** + * Created by pengwei on 2016/10/31. + */ +public class GroovyFileUil { + + /** + * 获取最后一个插件的表达式 + * + * @param buildScript + * @return + */ + public static GrExpression getLastPlugin(GroovyFile buildScript) { + Iterator var2 = getMethodCalls(buildScript, "apply").iterator(); + GrExpression expression = null; + while (var2.hasNext()) { + GrMethodCall methodCall = (GrMethodCall) var2.next(); + expression = methodCall.getInvokedExpression(); + } + return expression; + } + + public static Iterable getMethodCalls(@NotNull GrStatementOwner parent) { + return Iterables.filter(Arrays.asList(parent.getStatements()), GrMethodCall.class); + } + + public static Iterable getMethodCalls(@NotNull GrStatementOwner parent, @NotNull final String methodName) { + return Iterables.filter(getMethodCalls(parent), new Predicate() { + public boolean apply(@Nullable GrMethodCall input) { + return input != null && methodName.equals(getMethodCallName(input)); + } + }); + } + + public static String getMethodCallName(@NotNull GrMethodCall gmc) { + GrExpression expression = gmc.getInvokedExpression(); + return expression.getText() != null ? expression.getText() : ""; + } + +} diff --git a/android-studio-plugin/src/utils/LogUtil.java b/android-studio-plugin/src/utils/LogUtil.java new file mode 100644 index 0000000..8e4ca65 --- /dev/null +++ b/android-studio-plugin/src/utils/LogUtil.java @@ -0,0 +1,31 @@ +package utils; + +import models.Constant; + +/** + * Created by pengwei on 2016/11/2. + */ +public class LogUtil { + + public static void d(String info) { + if (!Constant.DEBUG_MODE) { + return; + } + System.out.println(info); + } + + public static void d(String info, Object...args) { + if (!Constant.DEBUG_MODE) { + return; + } + System.out.println(String.format(info, args)); + } + + public static void d(Object info) { + if (!Constant.DEBUG_MODE) { + return; + } + System.out.println(info); + } + +} diff --git a/android-studio-plugin/src/utils/NotificationUtils.java b/android-studio-plugin/src/utils/NotificationUtils.java index b8ef5f0..2abb7c1 100644 --- a/android-studio-plugin/src/utils/NotificationUtils.java +++ b/android-studio-plugin/src/utils/NotificationUtils.java @@ -5,6 +5,7 @@ import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.ui.Messages; public class NotificationUtils { @@ -31,6 +32,7 @@ public void run() { /** * show a error Notification + * * @param message */ public static void errorNotification(final String message) { @@ -38,7 +40,16 @@ public static void errorNotification(final String message) { } /** - * show a info Notification + * error message dialog + * @param message + */ + public static void errorMsgDialog(String message) { + Messages.showMessageDialog(message, "Error", Messages.getInformationIcon()); + } + + /** + * show a info Notification + * * @param message */ public static void infoNotification(final String message) { diff --git a/android-studio-plugin/src/utils/SystemUtil.java b/android-studio-plugin/src/utils/SystemUtil.java deleted file mode 100644 index 9f24cb3..0000000 --- a/android-studio-plugin/src/utils/SystemUtil.java +++ /dev/null @@ -1,30 +0,0 @@ -package utils; - -import com.intellij.openapi.util.SystemInfo; - -/** - * System Utility Wrapper - * - * @author act262@gmail.com - */ -public class SystemUtil { - - /** - * os system is windows or other - */ - public static boolean isWindows() { -// String os = System.getenv("os"); -// return os.equalsIgnoreCase("Windows_NT"); - - return SystemInfo.isWindows; - } - - public static boolean hasPython() { - return !System.getenv("python").isEmpty(); - } - - public static boolean hasAndroidSDK() { - return !System.getenv("ANDROID_HOME").isEmpty(); - } - -} diff --git a/android-studio-plugin/src/utils/Utils.java b/android-studio-plugin/src/utils/Utils.java index a76a646..ae0138d 100644 --- a/android-studio-plugin/src/utils/Utils.java +++ b/android-studio-plugin/src/utils/Utils.java @@ -1,6 +1,6 @@ package utils; -import com.jediterm.terminal.ui.UIUtil; +import com.intellij.openapi.util.SystemInfo; import java.awt.*; import java.awt.event.KeyEvent; @@ -30,7 +30,7 @@ public static String getPythonLocation() { } catch (IOException | InterruptedException e) { } try { - if (!UIUtil.isWindows) { + if (!SystemInfo.isWindows) { process = Runtime.getRuntime().exec(new String[]{"whereis", "python"}); if (process != null && process.getInputStream() != null) { String result = StreamUtil.inputStream2String(process.getInputStream()); @@ -54,7 +54,7 @@ public static boolean notEmpty(String text) { * @param url */ public static void openUrl(String url) { - if (UIUtil.isWindows) { + if (SystemInfo.isWindows) { try { Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url); } catch (IOException e) { diff --git a/android-studio-plugin/src/views/FreelineTerminal.java b/android-studio-plugin/src/views/FreelineTerminal.java index ef970dc..2f64276 100644 --- a/android-studio-plugin/src/views/FreelineTerminal.java +++ b/android-studio-plugin/src/views/FreelineTerminal.java @@ -16,6 +16,7 @@ import com.intellij.openapi.wm.ex.ToolWindowManagerListener; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; +import com.jediterm.terminal.TerminalMode; import com.jediterm.terminal.model.TerminalTextBuffer; import com.jediterm.terminal.ui.JediTermWidget; import icons.PluginIcons; @@ -23,9 +24,9 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.terminal.AbstractTerminalRunner; import org.jetbrains.plugins.terminal.JBTabbedTerminalWidget; +import org.jetbrains.plugins.terminal.JBTerminalPanel; import org.jetbrains.plugins.terminal.LocalTerminalDirectRunner; -import utils.NotificationUtils; -import utils.Utils; +import utils.*; import javax.swing.*; import java.awt.*; @@ -121,15 +122,15 @@ public void executeShell(String shell) { public void executeShell(String[] shell) { StringBuilder build = new StringBuilder(); if (shell != null && shell.length > 0) { - for (String s : shell) { - if (s == null) { - continue; - } - build.append(s + " "); + for (String s : shell) { + if (s == null) { + continue; } + build.append(s + " "); } - executeShell(build.toString()); } + executeShell(build.toString()); +} public void initTerminal(final ToolWindow toolWindow) { toolWindow.setToHideOnEmptyContent(true); @@ -327,13 +328,10 @@ public BaseTerminalAction(FreelineTerminal terminal, String text, String descrip @Override public void actionPerformed(AnActionEvent anActionEvent) { - saveDocuments(); - doAction(anActionEvent); - } - - private void saveDocuments() { - FileDocumentManager.getInstance().saveAllDocuments(); - ApplicationManager.getApplication().saveSettings(); + DocumentUtil.saveDocument(); + if (FreelineUtil.checkInstall(anActionEvent.getProject())) { + doAction(anActionEvent); + } } public abstract void doAction(AnActionEvent anActionEvent); diff --git a/android-studio-plugin/src/views/ImageJPanel.java b/android-studio-plugin/src/views/ImageJPanel.java index 6715d80..ab11e37 100644 --- a/android-studio-plugin/src/views/ImageJPanel.java +++ b/android-studio-plugin/src/views/ImageJPanel.java @@ -18,7 +18,9 @@ public class ImageJPanel extends JPanel { public void setImagePath(String path) { try { InputStream is = this.getClass().getClassLoader().getResourceAsStream(path); - image = ImageIO.read(is); + if (is != null) { + image = ImageIO.read(is); + } } catch (IOException e) { }