gpt4 book ai didi

java - 如何使用配置管理为同一类创建多个配置?

转载 作者:行者123 更新时间:2023-12-02 02:05:22 24 4
gpt4 key购买 nike

我正在开发一个将利用 OSGi 框架的实体组件系统游戏引擎。我希望用户/开发人员能够以模块化方式创建自己的组件类型,类似于 Bethesda Creation Kit。

Creation Kit Object Window

我考虑解决这个问题的方法是创建一个代表组件类型的类,然后使用配置管理来创建配置,但我不确定我的理解是否正确。

我有一个类想要用作组件类型

@Component(
configurationPid = "Species",
configurationPolicy = ConfigurationPolicy.REQUIRE,
service = Species.class
)
public final class Species {
// ...
}

为了测试这一点,我为 Apache Gogo 创建了一个命令来创建 Species 。我的想法是我应该能够使用此命令创建多个物种。

@Component(
property = {
CommandProcessor.COMMAND_SCOPE + "=species",
CommandProcessor.COMMAND_FUNCTION + "=create"
},
service = CreateSpeciesCommand.class
)
public class CreateSpeciesCommand {

/* L1 */

@Reference(bind = "bindConfigurationAdmin")
private ConfigurationAdmin configurationAdmin;

@Descriptor("creates a species")
public void create(@Descriptor("id of the species") final String speciesId) throws IOException, InvalidSyntaxException {
final String filter = String.format("(%s=%s)", Constants.OBJECTCLASS, Species.class.getSimpleName());
final Configuration[] existingConfigurations = configurationAdmin.listConfigurations(filter);
System.out.println(Arrays.toString(existingConfigurations));

final Configuration speciesConfiguration = configurationAdmin.getConfiguration(Species.class.getSimpleName(), "?");
Dictionary<String, Object> configProperties = new Hashtable<>();
configProperties.put(Constants.SERVICE_PID, "Species");

speciesConfiguration.update(configProperties);
}
}

但所发生的只是修改配置,而不是创建新配置。

我需要做什么才能使用配置管理器为同一类创建多个配置?

2018-06-19编辑:

进行 Peter Kriens' answer 指定的更改:

  • 添加@Designate注释 Species
  • 设置@Component#name独特的东西
  • 设置@Component#configurationPolicyConfigurationPolicy.REQUIRE
  • 添加@ObjectClassDefinitionSpecies.Config
  • 使用ConfigurationAdmin#getConfiguration ( createConfiguration 不存在,只有这个和 createFactoryConfiguration )与 @Component#name作为 pid

结果只创建一个配置,该配置会随着后续调用而更新。

最佳答案

OSGi 配置管理有 2 种不同类型的配置:

  • Singleton – 有一个 PID
  • 工厂 – 具有 PID(针对工厂实例)和针对实例“组”的工厂 PID。

在 OSGi >= 6 中,您可以这样做:

 @Designate( ocd= Species.Config.class, factory=true )
@Component( name = "species.pid", configurationPolicy=ConfigurationPolicy.REQUIRE )
public class Species {
@ObjectClassDefinition
@interface Config {
String id();
}

@Activate
void activate( Config config) {
System.out.println( config.id() );
}
}

现在的命令(用列表+删除功能扩展):

 @Component(
property = {
CommandProcessor.COMMAND_SCOPE + "=species",
CommandProcessor.COMMAND_FUNCTION + "=create",
CommandProcessor.COMMAND_FUNCTION + "=list",
CommandProcessor.COMMAND_FUNCTION + "=delete"
},
service = CreateSpeciesCommand.class
)
public class CreateSpeciesCommand {
@Reference
ConfigurationAdmin configurationAdmin;

public Configuration create(String speciesId) throws Exception {
Configuration c = configurationAdmin.createFactoryConfiguration( "species.pid", "?");
Hashtable<String,Object> d = new Hashtable();
d.put("id", speciesId);
c.update( d );
return c;
}

public Configuration[] list() throws Exception {
return configurationAdmin.
listConfigurations( "(service.factoryPid=species.pid)");
}

public boolean delete(String id) throws Exception {
Configuration[] list = configurationAdmin.
listConfigurations( "(&(service.factoryPid=species.pid)(id="+id+"))");
if ( list == null) {
return false;
}
for ( Configuration c : list ) {
c.delete();
}
return true;
}
}

一些注意事项:

  • 未编译编写,因此可能会出现一些编译错误
  • WebConsole 可以更好地创建和删除物种
  • 为了便于阅读,跳过了 Gogo 注释
  • 显然无法防御“过滤器”注入(inject)攻击

关于java - 如何使用配置管理为同一类创建多个配置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50892563/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com