Design - Global Settings from Consumer Module - java

I am attempting to make a library. Had some constants in my code which were some kind of different time delays and certain String values across the code. I could extract them to a separate constant class to get something like
Delays.LENGTH_SHORT (seems cleaner)
They are linked to many different classes inside the library code.
Now, the problem in hand is to make it configurable, from the calling consumer (i.e., if the consumer provides the values, then use those, otherwise use the preset values). From the consumer end, I decided to use Builder pattern for creating the config and passing it in the init of the library module (this only happens once in the lifecycle of it).
Is there a way to keep the above syntax and yet accept the config from consumer (the settings are only configured once during init, for all other times, it completely behaves as constant)?
Reading from a file, appeared to be costly.

For constants that can take a value from only a fixed set of values then it is always better to use Java enums instead of integers or strings or other raw data types. They are much better to understand and maintain over the period of time. Default values should ideally be read from a property file to initialize them. But as you have mentioned in your case, you want to avoid the cost of reading from a file for performance reasons. The design question is always open ended and can have multiple approaches. One approach that I recommend can be as below:
public interface Configuration {
public Continent getContinent(); //For fixed set of values use enum
public Integer getPoolSize(); //If the config can take any value then use the corresponding data type directly
public String getDefaultLabel();
}
public enum Continent {
ANTARTICA, AFRICA, ASIA, AUSTRALIA, EUROPE, NORTH_AMERICA, SOUTH_AMERICA;
}
public class ConfigurationBuilder {
private DefaultConfiguration configurationInstance;
private class DefaultConfiguration implements Configuration {
//Ideally the below values should be read from a property file, instead of hard coding it here.
private Integer poolSize = Integer.valueOf(50);
private String defaultLabel = "DEFAULT";
private Continent continent = Continent.ASIA;
#Override
public Continent getContinent() {
return continent;
}
#Override
public Integer getPoolSize() {
return poolSize;
}
#Override
public String getDefaultLabel() {
return defaultLabel;
}
}
public ConfigurationBuilder withContinent(Continent continent) {
this.configurationInstance.continent = continent;
return this;
}
public ConfigurationBuilder withPoolSize(Integer poolSize) {
this.configurationInstance.poolSize = poolSize;
return this;
}
public ConfigurationBuilder withDefaultLabel(String defaultLabel) {
this.configurationInstance.defaultLabel = defaultLabel;
return this;
}
public Configuration build() {
return this.configurationInstance;
}
public ConfigurationBuilder() {
this.configurationInstance = new DefaultConfiguration();
}
public static Configuration buildDefaultConfiguration() {
return new ConfigurationBuilder().build();
}
}
public class Library {
private Configuration configuration;
public void init(Configuration configuration) {
this.configuration = configuration;
}
public void init() {
this.configuration = ConfigurationBuilder.buildDefaultConfiguration();
}
private Library(Configuration config) {
this.init(config);
}
private Library() {
this.init();
}
/**
* Library is not singleton here.
*
*/
public static Library getInstance(Configuration configuration) {
return new Library(configuration);
}
public static Library getInstance() {
return new Library();
}
}
public class Client {
public static void main(String args[]) {
Configuration config = new ConfigurationBuilder()
.withContinent(Continent.AFRICA)
.withPoolSize(20)
.withDefaultLabel("Label")
.build();
Library lib = Library.getInstance();
lib.init(config);
}
}
Please check the Library and Client classes for usage.
- It uses the Builder pattern.
- It has init() and init(Configuration) methods to allow completely relying on Library defaults.
- ConfigurationBuilder supports supplying some or all configuration values to override
- Currently all three config options are overridable - continent, poolSize and defaultLabel. However if some configuration is private to Library then just remove the withXXX method for that property from the Builder.
Hope this fits your need. Good question!

Related

How to design a Java fluent DSL API without static methods

There are several ways how to define a Java fluent API:
Use static classes/methods + an internal ThreadLocal to get the DSL instance
Use setter/getter based methods to chain the API. Personally I don't like the readability of it, e.g. see some Spring Security code examples.
Is there a way to create a Java DSL that is more readable, like fluent methods in Kotlin? For exmaple a Computer class with Attributes like cpu/gpu and nested DSL classes like drives (Note: I want to nest ssd and hdd even further, e.g. define partitions?
public class Main {
public static void main(String[] arguments) {
Computer computer = Computer.build("Gaming PC").cpu("AMD 5950X").gpu("Lol rly?");
computer.drives(() {
ssd("1TB", "m2");
hdd("10TB", "SATA");
});
computer.print();
}
public static class Computer {
private final Map<String, String> attributes;
private Computer() {
this.attributes = new LinkedHashMap<>();
}
public static Computer build(String name) {
Computer computer = new Computer();
computer.attributes.put("name", name);
return computer;
}
public Computer cpu(String modelName) {
attributes.put("cpu", modelName);
return this;
}
public Computer gpu(String modelName) {
attributes.put("gpu", modelName);
return this;
}
// TODO: Add ssd and hdd. How?
public void print() {
for (Map.Entry<String, String> entry : attributes.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
}
}
The example above won't compile. But is there a way to achieve it with regular classes/abstract classes or even interfaces [with default methods?]. Like this:
public class Main {
public static void main(String[] arguments) {
Computer computer = Computer.build("Gaming PC").cpu("AMD 5950X").gpu("Lol rly?");
computer.drives((new DriveManager() {
ssd("1TB", "m2");
hdd("10TB", "SATA");
});
computer.print();
}
public static class DriveManager {
private Computer computer;
public void setComputer(Computer computer) {
this.computer = computer;
}
public void ssd(String size, String interfaceType) {
computer.ssd(size, interfaceType);
}
public void hdd(String size, String interfaceType) {
computer.ssd(size, interfaceType);
}
}
}
But how does one call setComputer?
Using reflection and an anonymous instance can be used.
You only need it for the drives
Computer computer = new Computer("Gaming PC") {
MainboardComponent cpu = new CPU("AMD 5950X");
MainboardComponent gpu = new GPU("Lol rly?");
Drive ssd = new SSD("1TB", "m2");
Drive hdd = new HDD("10TB", "SATA") {
Partition hdd1 = ...;
Partition hdd2 = ...;
};
}
This hides those fields however.
This however is useful for things like grammars where you may use inheritance on several levels (protected fields, predefined rules, I/O ports). It has the advantage that the container base class may provide component classes and protected members.
A pure fluent interface is possible too, by letting the ComputerBuilder have a nested DriveBuilder.
Computer computer = Computer.build("Gaming PC")
.cpu("AMD 5950X")
.gpu("Lol rly?")
.drives()
.ssd("1TB", "m2")
.hdd("10TB", "SATA")
.endDrives()
.end();
The third alternative would be to use a vararg method ComputerBuilder drives(DriveBuilder... dds); (Drive or DriveBuilder).
Computer computer = Computer.build("Gaming PC")
.cpu("AMD 5950X")
.gpu("Lol rly?")
.drives(Drive.ssd("1TB", "m2"), Drive.hdd("10TB", "SATA"));

Is it appropriate to use reflection to create a list of objects of all subclasses?

In my program, different features are divided into different modules, potentially hundreds of modules,
each module is a subclass of an abstract Module class
which look something like this
public abstract class Module {
public final String name;
public Module(String name){
this.name = name;
}
public abstract void execute();
}
with subclasses that look like this
public class Mod1 extends Module{
public Mod1() {
super("Mod1");
}
#Override
public void execute() {
//Do something
}
}
and I need to make a list of instances of all modules but doing it like this is kinda tedious since my program might have hundreds of modules and it might be hard to debug(I might miss a few lol)
private static final List<Module> MODULES = new ArrayList<>();
public void init(){
MODULES.add(new Mod1());
MODULES.add(new Mod2());
MODULES.add(new Mod3());
MODULES.add(new Mod4());
MODULES.add(new Mod5());
}
so I think using reflection might be the way to go but after a quick google search, I see many people don't like reflection in production code, so I come here to ask if this is an appropriate case to use reflection or is there any reason or design change to avoid using reflection in this particular case
edit: the list will be used stuff like rendering modules in gui or calling execute method of the module from other user interface like command(simply find the module with matching name and execute it)
note: this is not how my code actually look like but a highly simplified version that give a similar idea
For a minimal-effort approach, java provides the built-in class java.util.ServiceLoader.
With this class you can obtain all available implementations of a service class (in this case Module) like
ServiceLoader moduleLoader = ServiceLoader.load(Module.class);
for (Module mod : moduleLoader) {
System.out.println(mod.name);
}
Note that I highlighted the term available in the previous sentence. In fact, the ServiceLoader implementation does not perform any advanced class-hierarchy lookup, instead it relies on a specific resource file named equal to the canonical name of the Module class.
META-INF/services/com.example.project.Module
com.example.project.impl1.Module1
com.example.project.impl2.Module2
Where each line of the file references an available implementation of Module.
Now, ServiceLoader is an implementation of the java SPI specification, which does not necessarily have to qualify perfectly for your use case. However, since its idea of service loading and providing is rather simple, you can easily build your own variant.
public class JsonServiceLoader<S> {
private Class<S> service;
private Map<String, String> serviceIdentifiers;
public static <T> JsonServiceLoader load(Class<T> service, ClassLoader cl) {
Map<String, String> serviceIdentifiers = new HashMap<>();
String name = "META-INF/json-services/" + service.getCanonicalName();
// TODO check for null references where necessary
for (Enumeration<URL> resources = cl.getResources(name); resources.hasMoreElements();) {
try (InputStream resource = resources.next().openStream()) {
for (Map.Entry<String, String> identifier : parseJson(resource).entrySet()) {
serviceIdentifers.merge(
identifer.getKey(),
identifer.getValue(),
(value1, value2) -> throw new ServiceConfigurationError(
"duplicate service identifier '" + identifier.getKey() + "'"
);
);
}
}
}
return new JsonServiceLoader<>(service, serviceIdentifiers);
}
private static Map<String, String> parseJson(InputStream resource) {
// TODO parse JSON data from the given stream using your favourite JSON facility
/*
* If you want to use a different style of resources, e.g. XML, this is the only
* location you have to change (you might want to rename 'json-services' though).
*/
return new HashMap<>();
}
private JsonServiceLoader(Class<S> service, Map<String, String> serviceIdentifiers) {
this.service = service;
this.serviceIdentifiers = serviceIdentifiers;
}
public Set<String> getServiceIdentifiers() {
return Collections.unmodifiableSet(serviceIdentifiers.keySet());
}
public S getService(String name) {
String className = serviceIdenfiers.get(name);
if (null == className) {
throw new IllegalArgumentException("invalid service identifier '" + name + "'");
}
// TODO improve error handling
try {
return service.cast(Class.forName(className).newInstance());
} catch(Exception exc) {
throw new ServiceConfigurationError("could not load service '" + name + "'", exc);
}
}
}
Your JSON resources could look like
META-INF/json-services/com.example.project.Module
{
"Mod1" : {
"class" : "com.example.project.impl1.Module1"
},
"Mod2" : {
"class" : "com.example.project.impl2.Module2"
}
}
allowing future extensions.
At this point, the Module class also does not need to know its name (the class member name) anymore, since you can always ask the service loader for an appropriate instance. (If you do so at some place in your code, you will already know for which name you just asked.) If so desired, you can also add more logic to this JsonServiceLoader, such as caching.
Ultimately, it all depends on how much information you want to process around your Module and how much of this information you want the Module implementations to handle and how much of it you want the service framework to handle.
Perhaps you can pass the list into the constructor of the parent class and add subclass itself to the list in the constructor method.
Just like this
public abstract class Module {
public final String name;
public Module(String name, List<Module> list) {
this.name = name;
list.add(this);
}
public abstract void execute();
}
private static final List<Module> MODULES = new ArrayList<>();
public void init(){
new Mod1(MODULES);
}

Java Simple Factory with constructors using different parameters

I have two ways of saving data in my application: save to database and save to file. Since I don't want client code dealing with construction of objects I created a class that (to my understanding) is simple factory with a factory method. Code below:
public static DataPersister createDataPersister(Boolean saveToDb, Session session, String filename) {
if (saveToDb) {
return new DatabaseDataPersister(session);
} else {
return new FileDataPersister(filename);
}
}
With this setup client code doesn't have to deal with constructing anything or deciding whether to save to DB or file - it can just call a save() method on an object returned by the factory like so:
DataPersister dataPersister = DataPersisterSimpleFactory.createDataPersister(this.savetoDb, this.session, this.filename);
dataPersister.save(this.data);
My question is - is this solution breaking SOLID principles? In order to create e.g. a DatabaseDataPersister client code needs to pass on a filename parameter, and this implementation of DataPersister won't have any use of it. I feel like it doesn't sit right with something similar to Interface-segregation principle but not quite that.
And if the solution is indeed a code smell - how do I go about cleaning it?
The SOLID principle I think is in violation is DIP.
Your client classes, by having to depend on the static factory directly, have a compile-time dependency on actual implementations, DatabaseDataPersister and FileDataPersister, rather than just the abstraction DataPersister.
To solve, supply to the client the DataPersister you want them to use. The constructor is usually a good place for this:
public class ExampleClient {
private final DataPersister dataPersister;
public ExampleClient(DataPersister dataPersister) {
this.dataPersister = dataPersister;
}
public void methodThatUsesSave(){
dataPersister.save(data);
}
}
This code compiles without the concrete implementations, i.e. it has no dependency on them. The client also doesn't need to know the filename or session so it solves that code smell too.
We can decide which concrete implementation to give it at construction time, here I use your existing method:
DataPersister dataPersister = DataPersisterSimpleFactory.createDataPersister(this.savetoDb, this.session, this.filename);
ExampleClient example = new ExampleClient(dataPersister);
This is a perfect opportunity to use the factory pattern
interface DataPersister {
void persist(String s);
}
private class DatabasePersister implements DataPersister {
final Session session;
public DatabasePersister(Session session) {
this.session = session;
}
#Override
public void persist(String s) {
System.out.println("Persist to database: " + s);
}
}
private class FilePersister implements DataPersister {
final String filename;
public FilePersister(String filename) {
this.filename = filename;
}
#Override
public void persist(String s) {
System.out.println("Persist to file: " + s);
}
}
class PersisterFactory {
public DataPersister createDatabasePersister(Session session) {
return new DatabasePersister(session);
}
public DataPersister createFilePersister(String filename) {
return new FilePersister(filename);
}
}
public void test(String[] args) {
DataPersister databasePersister = new PersisterFactory().createDatabasePersister(new Session());
databasePersister.persist("Hello");
DataPersister filePersister = new PersisterFactory().createFilePersister("Hello");
filePersister.persist("Hello");
}
You already pass a bunch of stuff irrelevant to various persisters.
As it stands you need a method that takes a Session and one that takes a String and you're done. No need for a boolean, no need for useless params. That handles your decision making with no cruft.
Whether or not that's a good idea... I'm ambivalent. You're not saving much; might as well just have a static factory in each type so it's explicit in the code what type you're creating.
Consider what happens when you add a new persister, like a REST endpoint, that would take a URL (could be a string, could be an actual URL). You now need even more useless parameters etc. Or you could pass in a URI from the beginning, e.g., file:// or http:// and get around that problem.
There are any number of ways this could be done–I'm not convinced there's a "clearly correct" answer, and it may boil down to opinion.
Well the right solution here is combining the dependency injection from weston and the factory pattern from OldCurmudgeon.
public class ExampleClient {
private final DataPersister dataPersister;
public ExampleClient(DataPersister dataPersister) {
this.dataPersister = dataPersister;
}
public void methodThatUsesSave(){
dataPersister.save(data);
}
}
class PersisterFactory {
public DataPersister createDatabasePersister(Session session) {
return new DatabasePersister(session);
}
public DataPersister createFilePersister(String filename) {
return new FilePersister(filename);
}
}
The upper level code:
PersisterFactory = new PersisterFactory();
DataPersister dataPersister;
if (saveToDb)
dataPersister = PersisterFactory.createDatabasePersister(new Session());
else
dataPersister = PersisterFactory.createFilePersister("Hello");
ExampleClient example = new ExampleClient(dataPersister);
Usually the dataPersister comes from the DI container and the saveToDb comes from the config, but of course testing can be an exception.

Schema Generator for ApacheCayenne classes

I'm trying to use SPQR to generate GraphQL schema from a Cayenne generated class.
Cayenne class looks like this
public class MyCayenneClass {
public static final Property<Integer> A_PROPERTY = Property.create("aProperty", Integer.class);
public static final Property<Integer> ANOTHER_PROPERTY = Property.create("anotherProperty", String.class);
public void setAProperty(Integer aProperty) {
writeProperty("aProperty", aProperty);
}
public Integer getAProperty() {
return (Integer)readProperty("aProperty");
}
public void setAnotherProperty(String anotherProperty) {
writeProperty("anotherProperty", anotherProperty);
}
public String getAnotherProperty() {
return (String)readProperty("anotherProperty");
}
}
As the class isn't a simple POJO, SPQR throws an exception and the schema isn't generated.
Error: QUERY_ROOT fields must be an object with field names as keys or a function which returns such an object.
What's the best approach here (without modifying the cayenne class (i.e. annotating a method)?
GraphQLEndPoing.java
#WebServlet(urlPatterns = "/graphql")
public class GraphQLEndpoint extends SimpleGraphQLServlet {
public GraphQLEndpoint() {
super(buildSchema());
}
//This method used SPQR
private static GraphQLSchema buildSchema() {
GraphQLSchema schemaGenerator = new GraphQLSchemaGenerator()
.withOperationsFromSingletons(myRepository) //register the beans
.generate();
return schemaGenerator;
}
private static final MyRepository myRepository;
static {
myRepository= new MyRepository ();
}
}
MyRepository.java
public class MyRepository{
private MyLibService libService;
#GraphQLQuery
public MyCayenneClass find(Integer id) {
List<MyCayenneClass> myList= libService.fetchById(new Integer[] {id});
return myList.get(0);
}
}
*FYI. If I declare the schema. Code will work just fine
schema {
query: Query
}
type Query {
find(id: Int): MyCayenneClass
}
type ConcContract {
id: ID
aProperty: Int
anotherProperty: String
}
From SPQR's perspective, this isn't really different from a POJO, as SPQR cares only about the types.
By default, for all nested classes (MyCayenneClass in your case), everything that looks like a getter will be exposed. For top-level classes (MyRepository in your case), only annotated methods are exposed by default. And at least one top-level method must be exposed, otherwise you have an invalid schema.
The error, as it stands, just means not a single top-level query was discovered. I see the #GraphQLQuery annotation is commented out. Is that intentional? With the default config, this would not expose any query.
You can register a different ResolverBuilder, e.g. PublicResolverBuilder (or your own implementation/extension) if you want to expose un-annotated methods.
E.g.
generator.withOperationsFromSingleton(new MyRepository(), new PublicResolverBuilder())
This would expose all public methods from that class.
Here's a slightly simplified example I tried with v0.9.6 and seems to work as expected (I know you're using a rather old version from the error text).
public class MyRepository {
#GraphQLQuery //not commented out
public MyCayenneClass find(Integer in) {
return new MyCayenneClass();
}
}
// extends CayenneDataObject because I don't know where to get the
// writeProperty and readProperty from
// but shouldn't change anything from SPQR's perspective
public class MyCayenneClass extends CayenneDataObject {
public static final Property<Integer> A_PROPERTY = Property.create("aProperty", Integer.class);
public static final Property<String> ANOTHER_PROPERTY = Property.create("anotherProperty", String.class);
public void setAProperty(Integer aProperty) {
writeProperty("aProperty", aProperty);
}
public Integer getAProperty() {
return (Integer)readProperty("aProperty");
}
public void setAnotherProperty(String anotherProperty) {
writeProperty("anotherProperty", anotherProperty);
}
public String getAnotherProperty() {
return (String)readProperty("anotherProperty");
}
}
There's many more customizations you can apply, depending on what you end up needing, but from the question as it stands, it doesn't seem you need anything extra...
To override the ResolverBuilder used for nested classes, you have 2 options.
1) Register it globally, so all nested types use it:
generator.withNestedResolverBuilders(customBuilder)
2) Or per type:
.withNestedResolverBuildersForType(MyCayenneClass.class, new BeanResolverBuilder())
But this is very rarely needed...

Using custom built-ins in external Java Project

I have created new custom built-ins inside my Java program. They work fine and if I execute them into a ".txt" file making a rule I get the result I expect to .
The problem is that I can use this built-ins only where I have implemented them (in the same file).
For example, I have a java class file which is called "RulesOntology_DiffYear.java" where I have created a built-in called "myDiffDate" which does the difference between two dates and it return the number of years of difference.
If I try to write the rule (using the built-in "myDiffDate") and I try to execute it inside the file "RulesOntology_DiffYear.java", the rule recognises the new built-in and it runs it without problems.
If I try to write the same rule in another file ".java", the built-in I have created in "RulesOntology_DiffYear.java", it is not recognised, of course.
How can I use my custom built-ins in another files ? Like the default built-ins ? Need I to create a library or there is something else to do ?
I have found this Create a library for new built-ins Jena but I do not really know how it works (even if I tried it) and I do not know if it is the easiest solution for my purpose.
In my file "DiffDateLib.java" I have defined my custom built-in "myDiffDateYear".
I have created another file named "MyReasonerFactory.java" with the following code :
public class MyReasonerFactory implements ReasonerFactory {
/** The single global static registry */
public static BuiltinRegistry theRegistry;
private static final String RULE_LOC = "????";
static {
BuiltinRegistry.theRegistry.register(new DiffDateLib());
}
#Override
public Reasoner create(Resource r) {
final GenericRuleReasoner reasoner = new GenericRuleReasoner(this, r);
reasoner.setRules(FBRuleReasoner.loadRules(RULE_LOC));
return reasoner;
}
#Override
public Model getCapabilities() {
return GenericRuleReasonerFactory.theInstance().getCapabilities();
}
#Override
public String getURI() {
return RULE_LOC;
}
}
What can I write into the variable "RULE_LOC" ? Which filepath ?
I have made also another class called "tryNoBuiltin.java" which contains the main of the program :
public class tryNoBuiltin {
public static void main(String[] args) throws OWLOntologyStorageException,
OWLOntologyCreationException, IOException {
String percorsoFile ="./prova_rules_M_rdf.owl";
String ruleFile= "./prova_rules_M_rdf_7_diffDate.txt";
Model rawModel = ModelFactory.createDefaultModel();
MyReasonerFactory MyReas = new MyReasonerFactory();
//create a resource (empty model)
Resource configuration = rawModel.createResource();
// set engine mode
configuration.addProperty(ReasonerVocabulary.PROPruleMode, "hybrid");
// set the rules file
configuration.addProperty(ReasonerVocabulary.PROPruleSet, ruleFile);
List<Rule> rules = Rule.rulesFromURL(ruleFile);
GenericRuleReasoner reasonerRULE = (GenericRuleReasoner) GenericRuleReasonerFactory.theInstance().create(configuration);
reasonerRULE.setRules(rules);
Model modelRULE= FileManager.get().loadModel(percorsoFile);
//create the inference model
InfModel infModelRULE = ModelFactory.createInfModel(reasonerRULE, modelRULE);
//force starting the rule execution
infModelRULE.prepare();
//write down the result in RDFXML form
infModelRULE.write(System.out);
}
}
In the main I can see the output so, the new built-in (which I have used into the rule file "prova_rules_M_rdf_7_diffDate.txt") is recognised .
But I think I did not use correctly the class "MyReasonerFactory". Can you provide me an example ? Where can I use its methods ?
Thank you all!
This should probably work for you. The idea is that the MyReasonerFactory is acting as a way to retrieve a reasoner for your domain. Not only does it register the builtins, but it also gets/sets the rules.
public class MyReasonerFactory implements ReasonerFactory {
private static final String RULE_LOC = "./prova_rules_M_rdf_7_diffDate.txt";
static {
BuiltinRegistry.theRegistry.register(new DiffDateLib());
}
#Override
public Reasoner create(Resource r) {
final GenericRuleReasoner reasoner = new GenericRuleReasoner(this, r);
reasoner.setRules(Rule.rulesFromURL(RULE_LOC));
return reasoner;
}
#Override
public Model getCapabilities() {
return GenericRuleReasonerFactory.theInstance().getCapabilities();
}
#Override
public String getURI() {
// TODO NOTE this is just a suggestion
return "urn:ex:provaRuleReasoner";
}
}
You did a few redundant things while loading the rules. ie: you set it in the config as well as manually retrieved them and parsed them. I removed the extra stuff.
public class tryNoBuiltin {
public static void main(String[] args) throws OWLOntologyStorageException,
OWLOntologyCreationException, IOException {
//Create a configuration model
Resource configuration = ModelFactory.createDefaultModel().createResource();
configuration.addProperty(ReasonerVocabulary.PROPruleMode, "hybrid");
MyReasonerFactory MyReas = new MyReasonerFactory();
GenericRuleReasoner reasonerRULE = (GenericRuleReasoner)MyReas.create(configuration);
Model modelRULE= FileManager.get().loadModel("./prova_rules_M_rdf.owl");
InfModel infModelRULE = ModelFactory.createInfModel(reasonerRULE, modelRULE);
infModelRULE.prepare();
//write down the result in RDFXML form
infModelRULE.write(System.out);
}
}

Categories

Resources