feat: add plugin finder for theme-side (#2683)

#### What type of PR is this?
/kind feature
/milestone 2.0
/area core
#### What this PR does / why we need it:
主题端提供判断插件是否已经启用的方法

#### Which issue(s) this PR fixes:
Fixes #2677

#### Special notes for your reviewer:
how to test it?
在主题端使用 `${pluginFinder.available(your-plugin-name)}`  来查看某个插件是否已经启用,如果是则得到 true ,否则 false,如果插件没有安装也得到 false

/cc @halo-dev/sig-halo 
#### Does this PR introduce a user-facing change?

```release-note
主题端支持获取插件启用状态
```
pull/2693/head
guqing 2022-11-11 10:26:11 +08:00 committed by GitHub
parent 3adf5b8a95
commit 7e592a3835
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 95 additions and 0 deletions

View File

@ -0,0 +1,12 @@
package run.halo.app.theme.finders;
/**
* A finder for {@link run.halo.app.core.extension.Plugin}.
*
* @author guqing
* @since 2.0.0
*/
public interface PluginFinder {
boolean available(String pluginName);
}

View File

@ -0,0 +1,33 @@
package run.halo.app.theme.finders.impl;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.pf4j.PluginState;
import org.pf4j.PluginWrapper;
import run.halo.app.plugin.HaloPluginManager;
import run.halo.app.theme.finders.Finder;
import run.halo.app.theme.finders.PluginFinder;
/**
* Plugin finder implementation.
*
* @author guqing
* @since 2.0.0
*/
@Finder("pluginFinder")
@AllArgsConstructor
public class PluginFinderImpl implements PluginFinder {
private final HaloPluginManager haloPluginManager;
@Override
public boolean available(String pluginName) {
if (StringUtils.isBlank(pluginName)) {
return false;
}
PluginWrapper pluginWrapper = haloPluginManager.getPlugin(pluginName);
if (pluginWrapper == null) {
return false;
}
return PluginState.STARTED.equals(pluginWrapper.getPluginState());
}
}

View File

@ -0,0 +1,50 @@
package run.halo.app.theme.finders.impl;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.pf4j.PluginState;
import org.pf4j.PluginWrapper;
import run.halo.app.plugin.HaloPluginManager;
/**
* Tests for {@link PluginFinderImpl}.
*
* @author guqing
* @since 2.0.0
*/
@ExtendWith(MockitoExtension.class)
class PluginFinderImplTest {
@Mock
private HaloPluginManager haloPluginManager;
@InjectMocks
private PluginFinderImpl pluginFinder;
@Test
void available() {
assertThat(pluginFinder.available(null)).isFalse();
boolean available = pluginFinder.available("fake-plugin");
assertThat(available).isFalse();
PluginWrapper mockPluginWrapper = Mockito.mock(PluginWrapper.class);
when(haloPluginManager.getPlugin(eq("fake-plugin")))
.thenReturn(mockPluginWrapper);
when(mockPluginWrapper.getPluginState()).thenReturn(PluginState.RESOLVED);
available = pluginFinder.available("fake-plugin");
assertThat(available).isFalse();
when(mockPluginWrapper.getPluginState()).thenReturn(PluginState.STARTED);
available = pluginFinder.available("fake-plugin");
assertThat(available).isTrue();
}
}