From d005ff7dfc1e5b2b2152ca64bc528315792c7a01 Mon Sep 17 00:00:00 2001 From: "Bernhard J. Berger" <bernhard.berger@uni-bremen.de> Date: Tue, 7 Feb 2023 21:05:58 +0100 Subject: [PATCH] Using a custom qualifier instead of @Named for applications. fix #10 --- .../core/arff/cdi/ArffBlackboardEntries.java | 31 +++++++++++++++++++ .../core/arff/cdi/ArffBlackboardEntry.java | 21 ------------- .../de/evoal/core/arff/main/ConvertArff.java | 21 ++++++++----- .../core/arff/main/ExtractDataDefinition.java | 15 ++++++--- .../src/main/java/module-info.java | 1 + .../de/evoal/core/api/cdi/Application.java | 7 ++++- .../de/evoal/core/api/cdi/BeanFactory.java | 1 - .../de/evoal/core/api/cdi/Commandline.java | 2 +- .../main/java/de/evoal/core/main/Evoal.java | 25 +++++++++------ .../search/HeuristicSearchEvaluation.java | 8 +++-- .../core/main/search/HeuristicSearchMain.java | 5 +-- .../api/GeneratorBlackboardEntries.java | 22 +++++++++++++ .../api/GeneratorBlackboardEntry.java | 15 --------- .../evoal/generator/main/DataGenerator.java | 11 +++++-- .../cdi/GeneratorConfigurationProducer.java | 8 ++--- .../src/main/java/module-info.java | 1 + .../evoal/surrogate/main/SurrogateMain.java | 8 ++++- 17 files changed, 128 insertions(+), 74 deletions(-) create mode 100644 src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/cdi/ArffBlackboardEntries.java delete mode 100644 src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/cdi/ArffBlackboardEntry.java create mode 100644 src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/api/GeneratorBlackboardEntries.java delete mode 100644 src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/api/GeneratorBlackboardEntry.java diff --git a/src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/cdi/ArffBlackboardEntries.java b/src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/cdi/ArffBlackboardEntries.java new file mode 100644 index 00000000..9e24c492 --- /dev/null +++ b/src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/cdi/ArffBlackboardEntries.java @@ -0,0 +1,31 @@ +package de.evoal.core.arff.cdi; + +import de.evoal.core.api.board.BlackboardEntries; +import de.evoal.core.api.cdi.Commandline; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Named; + +@ApplicationScoped +@Named("arff-entries") +public class ArffBlackboardEntries implements BlackboardEntries { + /** + * The arff file to read. + */ + @Commandline(main = {"convert-arff-to-json", "extract-data-definition-from-arff"}, name="arff:input", doc = "The input file used by arff utility applications.") + public static final String ARFF_INPUT = "arff:input"; + + /** + * An DDL specification for converting an arff file into JSON. + */ + @Commandline(main = "convert-arff-to-json", name="arff:ddl-specification", doc = "The DDL specification of attributes to read from a arff file.") + public static final String DDL_SPECIFICATION = "arff:ddl-specification"; + + /** + * Output file for either a DDL or an JSON file (depending on the use case). + */ + @Commandline(main = {"convert-arff-to-json", "extract-data-definition-from-arff"} , name="arff:output", doc = "The output file used by arff utility applications.") + public static final String OUTPUT_FILE = "arff:output"; + + private ArffBlackboardEntries() {} +} diff --git a/src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/cdi/ArffBlackboardEntry.java b/src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/cdi/ArffBlackboardEntry.java deleted file mode 100644 index 848f3267..00000000 --- a/src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/cdi/ArffBlackboardEntry.java +++ /dev/null @@ -1,21 +0,0 @@ -package de.evoal.core.arff.cdi; - -public final class ArffBlackboardEntry { - /** - * The arff file to read. - */ - public static final String ARFF_INPUT = "arff:input"; - - - /** - * An DDL specification for converting an arff file into JSON. - */ - public static final String DDL_SPECIFICATION = "arff:ddl-specification"; - - /** - * Output file for either a DDL or an JSON file (depending on the use case). - */ - public static final String OUTPUT_FILE = "arff:output"; - - private ArffBlackboardEntry() {} -} diff --git a/src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/main/ConvertArff.java b/src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/main/ConvertArff.java index 2fbded41..142eab25 100644 --- a/src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/main/ConvertArff.java +++ b/src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/main/ConvertArff.java @@ -1,13 +1,14 @@ package de.evoal.core.arff.main; import com.google.inject.Injector; +import de.evoal.core.api.cdi.Application; import de.evoal.core.api.cdi.BlackboardValue; import de.evoal.core.api.cdi.MainClass; import de.evoal.core.api.properties.PropertiesSpecification; import de.evoal.core.api.properties.io.PropertiesIOFactory; import de.evoal.core.api.properties.io.PropertiesReader; import de.evoal.core.api.properties.io.PropertiesWriter; -import de.evoal.core.arff.cdi.ArffBlackboardEntry; +import de.evoal.core.arff.cdi.ArffBlackboardEntries; import de.evoal.languages.model.ddl.DataDescriptionModel; import de.evoal.languages.model.ddl.dsl.DataDescriptionLanguageStandaloneSetup; import de.evoal.languages.model.ddl.impl.DdlPackageImpl; @@ -16,28 +17,34 @@ import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.resource.XtextResourceSet; -import weka.Run; +import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.inject.Named; import java.io.File; @Slf4j -@Dependent -@Named("convert-arff-to-json") +@ApplicationScoped +@Application( + name = "convert-arff-to-json", + documentation = """ +Application to extract specific data (specified in a ddl file) from an arff +file (input) and store it in an output file (output). +""" +) public class ConvertArff implements MainClass { @Inject - @BlackboardValue(ArffBlackboardEntry.ARFF_INPUT) + @BlackboardValue(ArffBlackboardEntries.ARFF_INPUT) private File arffFile; @Inject - @BlackboardValue(ArffBlackboardEntry.DDL_SPECIFICATION) + @BlackboardValue(ArffBlackboardEntries.DDL_SPECIFICATION) private File ddlFile; @Inject - @BlackboardValue(ArffBlackboardEntry.OUTPUT_FILE) + @BlackboardValue(ArffBlackboardEntries.OUTPUT_FILE) private File jsonFile; @Override diff --git a/src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/main/ExtractDataDefinition.java b/src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/main/ExtractDataDefinition.java index 37c70a4d..48914b8b 100644 --- a/src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/main/ExtractDataDefinition.java +++ b/src/core/de.evoal.core.arff/src/main/java/de/evoal/core/arff/main/ExtractDataDefinition.java @@ -1,13 +1,15 @@ package de.evoal.core.arff.main; +import de.evoal.core.api.cdi.Application; import de.evoal.core.api.cdi.BlackboardValue; import de.evoal.core.api.cdi.MainClass; -import de.evoal.core.arff.cdi.ArffBlackboardEntry; +import de.evoal.core.arff.cdi.ArffBlackboardEntries; import lombok.extern.slf4j.Slf4j; import weka.core.Attribute; import weka.core.Instances; import weka.core.converters.ConverterUtils; +import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.inject.Named; @@ -15,16 +17,19 @@ import java.io.*; import java.util.Enumeration; @Slf4j -@Dependent -@Named("extract-data-definition-from-arff") +@ApplicationScoped +@Application( + name = "extract-data-definition-from-arff", + documentation = "Application to automatically create a data definition file (output) based on an arff file (input)." +) public class ExtractDataDefinition implements MainClass { @Inject - @BlackboardValue(ArffBlackboardEntry.ARFF_INPUT) + @BlackboardValue(ArffBlackboardEntries.ARFF_INPUT) private String arffFile; @Inject - @BlackboardValue(ArffBlackboardEntry.OUTPUT_FILE) + @BlackboardValue(ArffBlackboardEntries.OUTPUT_FILE) private File ddlFile; @Override diff --git a/src/core/de.evoal.core.arff/src/main/java/module-info.java b/src/core/de.evoal.core.arff/src/main/java/module-info.java index de1dfb5e..1b30e46c 100644 --- a/src/core/de.evoal.core.arff/src/main/java/module-info.java +++ b/src/core/de.evoal.core.arff/src/main/java/module-info.java @@ -17,4 +17,5 @@ module de.evoal.core.arff { opens de.evoal.core.arff.io to weld.core.impl; opens de.evoal.core.arff.main to weld.core.impl; + opens de.evoal.core.arff.cdi to weld.core.impl; } \ No newline at end of file diff --git a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/cdi/Application.java b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/cdi/Application.java index 72076d76..f23a2a70 100644 --- a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/cdi/Application.java +++ b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/cdi/Application.java @@ -12,8 +12,13 @@ import java.lang.annotation.*; @Qualifier @Target({ElementType.TYPE}) public @interface Application { + /** + * @return Name of the application. + */ + public String name(); + /** * @return The documentation. */ - public @Nonbinding String value(); + public @Nonbinding String documentation(); } diff --git a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/cdi/BeanFactory.java b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/cdi/BeanFactory.java index 61545d04..2a79edc8 100644 --- a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/cdi/BeanFactory.java +++ b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/cdi/BeanFactory.java @@ -1,6 +1,5 @@ package de.evoal.core.api.cdi; -import de.evoal.core.api.ea.initial.InitialPopulation; import de.evoal.core.api.utils.Requirements; import lombok.extern.slf4j.Slf4j; import org.apache.deltaspike.core.api.provider.BeanProvider; diff --git a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/cdi/Commandline.java b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/cdi/Commandline.java index c4840cd2..faf1d5f4 100644 --- a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/cdi/Commandline.java +++ b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/cdi/Commandline.java @@ -15,7 +15,7 @@ public @interface Commandline { /** * @return The application that accept this parameter. */ - public @Nonbinding String main(); + public @Nonbinding String [] main(); /** * @return Parameter name. diff --git a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/Evoal.java b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/Evoal.java index 3680d20b..4360f37e 100644 --- a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/Evoal.java +++ b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/Evoal.java @@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.CdiContainerLoader; import org.apache.deltaspike.core.api.provider.BeanProvider; +import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; import java.lang.reflect.Field; import java.util.*; @@ -44,7 +45,8 @@ public final class Evoal { MainClass main = null; try { - main = BeanProvider.getContextualReference(mainName, false, MainClass.class); + final Application annotation = AnnotationInstanceProvider.of(Application.class, Map.of("name", mainName)); + main = BeanProvider.getContextualReference(MainClass.class, annotation); } catch (final Throwable e) { logMainError(e); System.exit(1); @@ -83,9 +85,13 @@ public final class Evoal { final Commandline annotation = field.getAnnotation(Commandline.class); - parameters.putIfAbsent(annotation.main(), new LinkedList<>()); - final List<Commandline> annotations = parameters.get(annotation.main()); - annotations.add(annotation); + for(final String main : annotation.main()) { + parameters.putIfAbsent(main, new LinkedList<>()); + + final List<Commandline> annotations = parameters.get(main); + annotations.add(annotation); + + } } } @@ -93,12 +99,11 @@ public final class Evoal { for(final Bean<MainClass> bean : beans) { System.out.println(); System.out.println("--------------------------------------------------------------------------------"); - System.out.println(" -Bcore:main=" + bean.getName()); - if(bean.getBeanClass().isAnnotationPresent(Application.class)) { - printIntended(4, bean.getBeanClass().getAnnotation(Application.class).value()); - } + final Application app = bean.getBeanClass().getAnnotation(Application.class); + System.out.println(" -Bcore:main=" + app.name()); + printIntended(4, app.documentation()); - final List<Commandline> annotations = parameters.getOrDefault(bean.getName(), new LinkedList<>()); + final List<Commandline> annotations = parameters.getOrDefault(app.name(), new LinkedList<>()); for(final Commandline annotation : annotations) { System.out.println(); System.out.println(" -B" + annotation.name() + "="); @@ -132,7 +137,7 @@ public final class Evoal { log.error(" possible names are:"); for(final Bean<MainClass> bean : beans) { - log.error(" {}", bean.getName()); + log.error(" {}", bean.getBeanClass().getAnnotation(Application.class).name()); } } } diff --git a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/search/HeuristicSearchEvaluation.java b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/search/HeuristicSearchEvaluation.java index e83f4c02..a676ebfa 100644 --- a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/search/HeuristicSearchEvaluation.java +++ b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/search/HeuristicSearchEvaluation.java @@ -25,13 +25,15 @@ import java.util.stream.Collectors; import java.util.stream.Stream; @Slf4j -@Application(""" +@Application( + name = "heuristic-search-evaluation", +documentation = """ Evaluates a heuristic search using multiple targets. Each target is searched for 'core:evaluation-iterations' times to allow a proper empirical evaluation. -""") -@Named("heuristic-search-evaluation") +""" +) @ApplicationScoped public class HeuristicSearchEvaluation implements MainClass { @Inject diff --git a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/search/HeuristicSearchMain.java b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/search/HeuristicSearchMain.java index ff78cc18..42900dd8 100644 --- a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/search/HeuristicSearchMain.java +++ b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/search/HeuristicSearchMain.java @@ -20,11 +20,12 @@ import javax.inject.Named; import java.io.File; import java.util.stream.Stream; -@Application(""" +@Application( + name = "heuristic-search", + documentation = """ This application starts a heuristic search for an optimal solution based on a problem specification. """) -@Named("heuristic-search") @ApplicationScoped public class HeuristicSearchMain implements MainClass { @Inject diff --git a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/api/GeneratorBlackboardEntries.java b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/api/GeneratorBlackboardEntries.java new file mode 100644 index 00000000..7e5f6853 --- /dev/null +++ b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/api/GeneratorBlackboardEntries.java @@ -0,0 +1,22 @@ +package de.evoal.generator.api; + +import de.evoal.core.api.board.BlackboardEntries; +import de.evoal.core.api.cdi.Commandline; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Named; + +@ApplicationScoped +@Named("generator-entries") +public class GeneratorBlackboardEntries implements BlackboardEntries { + /** + * Loaded generator configuration. + */ + public static final String GENERATOR_CONFIGURATION = "generator:configuration"; + + /** + * Configuration file for the data generator. + */ + @Commandline(main = "data-generator", name = "generator:configuration-file", doc = "The generator file to use.") + public static final String GENERATOR_CONFIGURATION_FILE = "generator:configuration-file"; +} diff --git a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/api/GeneratorBlackboardEntry.java b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/api/GeneratorBlackboardEntry.java deleted file mode 100644 index 1430b374..00000000 --- a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/api/GeneratorBlackboardEntry.java +++ /dev/null @@ -1,15 +0,0 @@ -package de.evoal.generator.api; - -public final class GeneratorBlackboardEntry { - /** - * Loaded generator configuration. - */ - public static final String GENERATOR_CONFIGURATION = "generator:configuration"; - - /** - * Configuration file for the data generator. - */ - public static final String GENERATOR_CONFIGURATION_FILE = "generator:configuration-file"; - - private GeneratorBlackboardEntry() {} -} diff --git a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/DataGenerator.java b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/DataGenerator.java index 00cf8111..ae5b4bb1 100644 --- a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/DataGenerator.java +++ b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/DataGenerator.java @@ -1,8 +1,6 @@ package de.evoal.generator.main; -import java.io.*; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -10,6 +8,7 @@ import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.inject.Named; +import de.evoal.core.api.cdi.Application; import de.evoal.core.api.cdi.BlackboardValue; import de.evoal.core.api.cdi.MainClass; import de.evoal.core.api.utils.InitializationException; @@ -26,6 +25,12 @@ import org.slf4j.LoggerFactory; * Main class for EvoAl's data generator. */ @ApplicationScoped +@Application( + name = "data-generator", + documentation = """ +Application for generating benchmark data based on a generator file. +""" +) @Named("data-generator") public class DataGenerator implements MainClass { @@ -35,7 +40,7 @@ public class DataGenerator implements MainClass { private final static Logger log = LoggerFactory.getLogger(DataGenerator.class); @Inject - @BlackboardValue(GeneratorBlackboardEntry.GENERATOR_CONFIGURATION) + @BlackboardValue(GeneratorBlackboardEntries.GENERATOR_CONFIGURATION) private Configuration configuration; @Inject diff --git a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/cdi/GeneratorConfigurationProducer.java b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/cdi/GeneratorConfigurationProducer.java index e67d4dba..572e19f3 100644 --- a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/cdi/GeneratorConfigurationProducer.java +++ b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/cdi/GeneratorConfigurationProducer.java @@ -5,7 +5,7 @@ import com.google.inject.Injector; import de.evoal.core.api.board.Blackboard; import de.evoal.core.api.board.BlackboardEntry; import de.evoal.core.api.cdi.BlackboardValue; -import de.evoal.generator.api.GeneratorBlackboardEntry; +import de.evoal.generator.api.GeneratorBlackboardEntries; import de.evoal.languages.model.ddl.dsl.DataDescriptionLanguageStandaloneSetup; import de.evoal.languages.model.ddl.impl.DdlPackageImpl; import de.evoal.languages.model.dl.dsl.DefinitionLanguageStandaloneSetup; @@ -33,7 +33,7 @@ import org.eclipse.xtext.resource.XtextResourceSet; @Slf4j public class GeneratorConfigurationProducer { public void loadModel(final @Observes BlackboardEntry value, final Blackboard board) { - if(!value.isSame(GeneratorBlackboardEntry.GENERATOR_CONFIGURATION_FILE)) { + if(!value.isSame(GeneratorBlackboardEntries.GENERATOR_CONFIGURATION_FILE)) { return; } @@ -56,7 +56,7 @@ public class GeneratorConfigurationProducer { } final Configuration configuration = read(file).get(); - board.bind(GeneratorBlackboardEntry.GENERATOR_CONFIGURATION, configuration); + board.bind(GeneratorBlackboardEntries.GENERATOR_CONFIGURATION, configuration); } /** @@ -113,7 +113,7 @@ public class GeneratorConfigurationProducer { } @Produces - @BlackboardValue(GeneratorBlackboardEntry.GENERATOR_CONFIGURATION) + @BlackboardValue(GeneratorBlackboardEntries.GENERATOR_CONFIGURATION) public Configuration injectIntegerValue(final InjectionPoint ip, final Blackboard board) { final BlackboardValue value = ip.getAnnotated().getAnnotation(BlackboardValue.class); final Object result = board.get(value.value()); diff --git a/src/core/de.evoal.generator.main/src/main/java/module-info.java b/src/core/de.evoal.generator.main/src/main/java/module-info.java index edd3412c..52d4efeb 100644 --- a/src/core/de.evoal.generator.main/src/main/java/module-info.java +++ b/src/core/de.evoal.generator.main/src/main/java/module-info.java @@ -33,4 +33,5 @@ module de.evoal.generator.main { opens de.evoal.generator.main.generators; exports de.evoal.generator.api; + opens de.evoal.generator.api to weld.core.impl; } diff --git a/src/core/de.evoal.surrogate.api/src/main/java/de/evoal/surrogate/main/SurrogateMain.java b/src/core/de.evoal.surrogate.api/src/main/java/de/evoal/surrogate/main/SurrogateMain.java index 73a53066..3b2d031d 100644 --- a/src/core/de.evoal.surrogate.api/src/main/java/de/evoal/surrogate/main/SurrogateMain.java +++ b/src/core/de.evoal.surrogate.api/src/main/java/de/evoal/surrogate/main/SurrogateMain.java @@ -1,5 +1,6 @@ package de.evoal.surrogate.main; +import de.evoal.core.api.cdi.Application; import de.evoal.core.api.cdi.BeanFactory; import de.evoal.core.api.cdi.BlackboardValue; import de.evoal.core.api.cdi.MainClass; @@ -19,8 +20,13 @@ import lombok.extern.slf4j.Slf4j; * recalculating them. */ @Slf4j -@Named("surrogate-training") @ApplicationScoped +@Application( + name = "surrogate-training", + documentation = """ +Application for training a surrogate function based on a given MLL file. +""" +) public class SurrogateMain implements MainClass { @Inject -- GitLab