Как сохранить / прочитать параметры запуска Run Configuration в плагине Intellij - PullRequest
0 голосов
/ 23 апреля 2019

Я создаю основной плагин IntelliJ, который позволяет пользователю определить конфигурацию запуска (следуя учебному пособию в [1]), и использовать указанные конфигурации запуска для запуска файла, открытого в редакторе на удаленном сервере.

Моя конфигурация запуска проста (3 текстовых поля), и у меня все это работает, однако после редактирования конфигурации запуска и нажатия «Применить» или «ОК» после изменения значений введенные значения теряются.

Как правильно сохранять и считывать значения (как при повторном открытии конфигурации запуска, так и при запуске Runner конфигурации запуска)?Похоже, я мог бы попытаться создать пользовательское постоянство, используя [2], однако, похоже, что инфраструктура плагинов должна иметь способ обрабатывать это уже или, по крайней мере, перехватывать при нажатии Apply / OK.

[1] https://www.jetbrains.org/intellij/sdk/docs/tutorials/run_configurations.html

[2] https://www.jetbrains.org/intellij/sdk/docs/basics/persisting_state_of_components.html

Ответы [ 2 ]

1 голос
/ 23 апреля 2019

См. Com.intellij.execution.configurations.RunConfigurationBase # readExternal, а также com.intellij.execution.configurations.RunConfigurationBase # loadState и com.intellij.execution.configurations.RunConfigurationBase # writeExternal

0 голосов
/ 26 апреля 2019

Надеюсь, этот пост будет немного более понятен новичкам в разработке плагинов IntelliJ и демонстрирует, как можно добиться сохранения / загрузки конфигураций выполнения.Пожалуйста, прочитайте комментарии к коду, так как именно здесь происходит большая часть объяснения.

Также теперь, когда SettingsEditorImpl - моя пользовательская реализация абстрактного класса SettingsEditor, и, аналогично, RunConfigurationImpl - мой пользовательскийреализация абстрактного класса RunConfigiration.

Первое, что нужно сделать, - это открыть поля формы с помощью пользовательских методов получения в вашем SettingsEditorImpl (т. е. getHost())

public class SettingsEditorImpl extends SettingsEditor<RunConfigurationImpl> {
    private JPanel configurationPanel; // This is the outer-most JPanel
    private JTextField hostJTextField;

    public SettingsEditorImpl() {
        super();
    }

    @NotNull
    @Override
    protected JComponent createEditor() {
        return configurationPanel;
    }

    /* Gets the Form fields value */
    private String getHost() {
        return hostJTextField.getText();
    }

    /* Copy value FROM your custom runConfiguration back INTO the Form UI; This is to load previously saved values into the Form when it's opened. */
    @Override
    protected void resetEditorFrom(RunConfigurationImpl runConfiguration) {
        hostJTextField.setText(StringUtils.defaultIfBlank(runConfiguration.getHost(), RUN_CONFIGURATION_HOST_DEFAULT));
    }

    /* Sync the value from the Form UI INTO the RunConfiguration which is what the rest of your code will interact with. This requires a way to set this value on your custom RunConfiguration, ie. RunConfigurationImpl@#setHost(host)  */
    @Override
    protected void applyEditorTo(RunConfigurationImpl runConfiguration) throws ConfigurationException {
        runConfiguration.setHost(getHost());
    }
}

Так что теперьпользовательский SettingsEditor, который поддерживает пользовательский интерфейс формы, настроен на синхронизацию значений полей In и Out от себя.Помните, что пользовательская RunConfiguration фактически представляет эту конфигурацию;SettingsEditor реализация просто представляет ФОРМУ (небольшая разница, но важная).

Теперь нам нужна пользовательская RunConfiguration ...

/* Annotate the class with @State and @Storage, which is used to define how this RunConfiguration's data will be persisted/loaded. */
@State(
        name = Constants.PLUGIN_NAME,
        storages = {@Storage(Constants.PLUGIN_NAME + "__run-configuration.xml")}
)
public class RunConfigurationImpl extends RunConfigurationBase {
     // Its good to 'namespace' keys to your component;
    public static final String KEY_HOST = Constants.PLUGIN_NAME + ".host";


    private String host;

    public RunConfigurationImpl(Project project, ConfigurationFactory factory, String name) {
        super(project, factory, name);
    }

    /* Return an instances of the custom SettingsEditor ... see class defined above */
    @NotNull
    @Override
    public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
        return new SettingsEditorImpl();
    }

    /* Return null, else we'll get a Startup/Connection tab in our Run Configuration UI in IntelliJ */
    @Nullable
    @Override
    public SettingsEditor<ConfigurationPerRunnerSettings> getRunnerSettingsEditor(ProgramRunner runner) {
        return null;
    }

    /* This is a pretty cool method. Every time SettingsEditor#applyEditorTo() is changed the values in this class, this method is run and can check/validate any fields! If RuntimeConfigurationException is thrown, the exceptions message is shown at the bottom of the Run Configuration UI in IntelliJ! */
    @Override
    public void checkConfiguration() throws RuntimeConfigurationException {
        if (!StringUtils.startsWithAny(getHost(), "http://", "https://")) {
            throw new RuntimeConfigurationException("Invalid host");
        }
    }

    @Nullable
    @Override
    public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment executionEnvironment) throws ExecutionException {
        return null;
    }

    /* This READS any prior persisted configuration from the State/Storage defined by this classes annotations ... see above.
    You must manually read and populate the fields using JDOMExternalizerUtil.readField(..).
    This method is invoked at the "right time" by the plugin framework. You dont need to call this.
    */
    @Override
    public void readExternal(Element element) throws InvalidDataException {
        super.readExternal(element);
        host = JDOMExternalizerUtil.readField(element, KEY_HOST);
    }

    /* This WRITES/persists configurations TO the State/Storage defined by this classes annotations ... see above.
    You must manually read and populate the fields using JDOMExternalizerUtil.writeField(..).
    This method is invoked at the "right time" by the plugin framework. You dont need to call this.
    */
    @Override
    public void writeExternal(Element element) throws WriteExternalException {
        super.writeExternal(element);
        JDOMExternalizerUtil.writeField(element, KEY_HOST, host);

    }

    /* This method is what's used by the rest of the plugin code to access the configured 'host' value. The host field (variable) is written by
    1. when writeExternal(..) loads a value from a persisted config.
    2. when SettingsEditor#applyEditorTo(..) is called when the Form itself changes.
    */
    public String getHost() {
        return host;
    }

    /* This method sets the value, and is primarily used by the custom SettingEditor's SettingsEditor#applyEditorTo(..) method call */
    public void setHost(String host) {
        this.host = host;
    }

}

Toпрочитайте эти значения конфигурации в другом месте, скажем, например, пользовательский ProgramRunner, вы бы сделали что-то вроде:

final RunConfigurationImpl runConfiguration = (RunConfigurationImpl) executionEnvironment.getRunnerAndConfigurationSettings().getConfiguration();
runConfiguration.getHost(); // Returns the configured host value
...