[英]How do I create multiple configurations for the same class with Configuration Admin?
我正在研究將利用OSGi框架的實體組件系統游戲引擎。 我希望用戶/開發人員能夠以模塊化方式創建自己的組件類型,類似於Bethesda Creation Kit。
我考慮過的方法是創建一個代表組件類型的類,然后使用Configuration Admin創建配置,但是我不確定我的理解是否正確。
我有一個要用作組件類型的類
@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);
}
}
但是所有發生的事情是它修改了配置,而不是創建一個新的配置。
使用Configuration Admin為同一類創建多個配置時,我需要做什么?
2018-06-19編輯:
進行由Peter Kriens的答案指定的更改:
@Designate
注釋添加到Species
類 @Component#name
設置為唯一的@Component#name
@Component#configurationPolicy
設置為ConfigurationPolicy.REQUIRE
@ObjectClassDefinition
添加到Species.Config
類 @Component#name
作為pid的ConfigurationAdmin#getConfiguration
( createConfiguration
不存在,僅此和createFactoryConfiguration
) 導致僅創建一個配置,該配置將通過后續調用進行更新。
OSGi Configuration Admin具有2種不同類型的配置:
因此,在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() );
}
}
現在,該命令(用list + delete函數擴展):
@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;
}
}
一些注意事項:
為了獲得每個呼叫的新配置,我需要更改以下內容:
Species
類的@Component#factory
值設置為唯一的值 ConfigurationAdmin#createFactoryConfiguration
方法而不是getConfiguration
方法 我嘗試應用Peter Kriens的答案指定的更改:
@Designate
注釋添加到Species
類 @Component#name
設置為唯一的@Component#name
@Component#configurationPolicy
設置為ConfigurationPolicy.REQUIRE
@ObjectClassDefinition
添加到Species.Config
類 @Component#name
作為pid的ConfigurationAdmin#getConfiguration
( createConfiguration
不存在,只有this和createFactoryConfiguration
); createFactoryConfiguration
使用@Component#factory
這不僅可以進行新的配置,還可以同時激活物種成分。 不知道為什么會這樣,但我正在調查中。
package net.zephyrion.hummingbird.module.species;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import java.util.Objects;
@Component(
factory = "Species",
configurationPolicy = ConfigurationPolicy.REQUIRE,
service = Species.class
)
public final class Species {
@interface Config {
String id() default "";
}
private Config config;
@Activate
public void configure(final Config config) {
this.config = Objects.requireNonNull(config);
}
private String getId() {
return config.id();
}
}
package net.zephyrion.hummingbird.module.species;
import org.apache.felix.service.command.CommandProcessor;
import org.apache.felix.service.command.Descriptor;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import java.io.IOException;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
@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 {
try {
final String factoryPid = Species.class.getSimpleName();
final String filter = String.format("(&(id=%s)(service.factoryPid=%s))", speciesId, factoryPid);
final boolean configurationExists = configurationAdmin.listConfigurations(filter) != null;
if (!configurationExists) {
final Configuration speciesConfiguration = configurationAdmin.createFactoryConfiguration(factoryPid, "?");
Dictionary<String, Object> configProperties = new Hashtable<>();
configProperties.put("id", speciesId);
speciesConfiguration.update(configProperties);
}
}
catch (InvalidSyntaxException e) {
e.printStackTrace();
}
}
/* L2 */
private void bindConfigurationAdmin(final ConfigurationAdmin configurationAdmin) {
// TODO Obj.rnn
this.configurationAdmin = configurationAdmin;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.