release version 1.10.0
This commit is contained in:
@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
|
||||
<artifactId>object-producing</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<version>1.10.0</version>
|
||||
</parent>
|
||||
<groupId>ru.entaxy.esb.platform.runtime.core.object-producing</groupId>
|
||||
<artifactId>object-producer-api</artifactId>
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-api
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -25,67 +25,114 @@
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.api;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.osgi.framework.Filter;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.InvalidSyntaxException;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
|
||||
import ru.entaxy.platform.base.support.CommonUtils;
|
||||
|
||||
public interface EntaxyProducerService {
|
||||
|
||||
public static interface DIRECTIVES {
|
||||
|
||||
String LIFECYCLE = "@LIFECYCLE";
|
||||
|
||||
/*
|
||||
* usage: {"@SKIP": ['command1', 'command2-', 'command3+']}
|
||||
* where
|
||||
* 'command1' - skip command1
|
||||
* 'command2-' - skip ALL BEFORE command2
|
||||
* 'command3+' - skip ALL AFTER command3
|
||||
*/
|
||||
String SKIP = "@SKIP";
|
||||
public static interface DIRECTIVES {
|
||||
|
||||
/*
|
||||
* usage: {"@CONTINUE_ON_EXCEPTION": ['command1', 'command2-', 'command3+']}
|
||||
* where
|
||||
* 'command1' - continue after exception in command1
|
||||
* 'command2-' - continue after exception in ANY command BEFORE command2
|
||||
* 'command3+' - continue after exception in ANY command AFTER command3
|
||||
*/
|
||||
String CONTINUE_ON_EXCEPTION = "@CONTINUE_ON_EXCEPTION";
|
||||
|
||||
};
|
||||
|
||||
public static interface INSTRUCTIONS {
|
||||
|
||||
String PRINT_OUTPUT = "printOutput";
|
||||
String SKIP = "skip";
|
||||
String CONTINUE_ON_EXCEPTION = "continueOnException";
|
||||
String MAX_COUNT = "maxCount";
|
||||
String CURRENT_ITERATION = "currentCount";
|
||||
|
||||
public static interface ARTIFACT {
|
||||
String LIFECYCLE = "@LIFECYCLE";
|
||||
|
||||
public static final String VERSION = "artifact.version";
|
||||
public static final String TIMESTAMP = "artifact.timestamp";
|
||||
public static final String VERSION_POLICY = "artifact.version.policy";
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public ProducerResult produce(String configuration);
|
||||
public ProducerResult produce(JsonObject configuration);
|
||||
/*
|
||||
* usage: {"@SKIP": ['command1', 'command2-', 'command3+']}
|
||||
* where
|
||||
* 'command1' - skip command1
|
||||
* 'command2-' - skip ALL BEFORE command2
|
||||
* 'command3+' - skip ALL AFTER command3
|
||||
*/
|
||||
String SKIP = "@SKIP";
|
||||
|
||||
public ProducerResult produce(String configuration, String instructions);
|
||||
public ProducerResult produce(JsonObject configuration, String instructions);
|
||||
|
||||
public List<EntaxyProducer> getAllProducers();
|
||||
public EntaxyProducer getProducerForType(String type);
|
||||
public EntaxyFactory findFactoryById(String factoryId);
|
||||
|
||||
public List<ProducingCommandExecutor> getAvailableCommands();
|
||||
public void registerCommand(ProducingCommandExecutor commandExecutor);
|
||||
public ProducingCommandExecutor getCommandById(String id);
|
||||
/*
|
||||
* usage: {"@CONTINUE_ON_EXCEPTION": ['command1', 'command2-', 'command3+']}
|
||||
* where
|
||||
* 'command1' - continue after exception in command1
|
||||
* 'command2-' - continue after exception in ANY command BEFORE command2
|
||||
* 'command3+' - continue after exception in ANY command AFTER command3
|
||||
*/
|
||||
String CONTINUE_ON_EXCEPTION = "@CONTINUE_ON_EXCEPTION";
|
||||
|
||||
};
|
||||
|
||||
public static interface INSTRUCTIONS {
|
||||
|
||||
String PRINT_OUTPUT = "printOutput";
|
||||
String SKIP = "skip";
|
||||
String CONTINUE_ON_EXCEPTION = "continueOnException";
|
||||
String MAX_COUNT = "maxCount";
|
||||
String CURRENT_ITERATION = "currentCount";
|
||||
|
||||
public static interface ARTIFACT {
|
||||
|
||||
public static final String VERSION = "artifact.version";
|
||||
public static final String TIMESTAMP = "artifact.timestamp";
|
||||
public static final String VERSION_POLICY = "artifact.version.policy";
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public ProducerResult produce(String configuration);
|
||||
|
||||
public ProducerResult produce(JsonObject configuration);
|
||||
|
||||
public ProducerResult produce(String configuration, String instructions);
|
||||
|
||||
public ProducerResult produce(JsonObject configuration, String instructions);
|
||||
|
||||
public List<EntaxyProducer> getAllProducers();
|
||||
|
||||
public EntaxyProducer getProducerForType(String type);
|
||||
|
||||
public EntaxyFactory findFactoryById(String factoryId);
|
||||
|
||||
default public boolean isFactoryOfType(String factoryId, String type) {
|
||||
EntaxyFactory f = findFactoryById(factoryId);
|
||||
while (f != null) {
|
||||
if (f.getType().equals(type))
|
||||
return true;
|
||||
if (!CommonUtils.isValid(f.getParent()))
|
||||
return false;
|
||||
f = findFactoryById(f.getParent());
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
default public List<EntaxyFactory> findFactories(String filter) {
|
||||
try {
|
||||
Filter osgiFilter = FrameworkUtil.createFilter(filter);
|
||||
return findFactories(osgiFilter);
|
||||
} catch (InvalidSyntaxException e) {
|
||||
LoggerFactory.getLogger(EntaxyProducerService.class).error(String.format("Invalid filter [%s]", filter));
|
||||
return new ArrayList<>();
|
||||
}
|
||||
};
|
||||
|
||||
default public List<EntaxyFactory> findFactories(Filter filter) {
|
||||
List<EntaxyFactory> allFactories = new ArrayList<>();
|
||||
for (EntaxyProducer producer : getAllProducers())
|
||||
allFactories.addAll(producer.getAllFactories());
|
||||
return EntaxyProducerUtils.filterFactories(filter, allFactories);
|
||||
};
|
||||
|
||||
public List<ProducingCommandExecutor> getAvailableCommands();
|
||||
|
||||
public void registerCommand(ProducingCommandExecutor commandExecutor);
|
||||
|
||||
public void extendLifecycle(String lifecycle, ProducingCommandExecutor commandExecutor,
|
||||
Map<String, Object> parameters);
|
||||
|
||||
public ProducingCommandExecutor getCommandById(String id);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-api
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -25,123 +25,203 @@
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.api;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.osgi.framework.Filter;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.InvalidSyntaxException;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ru.entaxy.platform.base.objects.EntaxyObjectService;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
|
||||
import ru.entaxy.platform.base.support.JSONUtils;
|
||||
|
||||
public class EntaxyProducerUtils {
|
||||
|
||||
protected static Gson sharedGson = new Gson();
|
||||
|
||||
//INSTRUCTIONS BUILDER
|
||||
|
||||
protected static class InstructionsItemBuilder {
|
||||
|
||||
protected JsonObject instructionsJson;
|
||||
|
||||
protected InstructionsItemBuilder(JsonObject jsonObject) {
|
||||
this.instructionsJson = jsonObject;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class InstructionsBuilder extends InstructionsItemBuilder {
|
||||
protected static Gson sharedGson = new Gson();
|
||||
|
||||
protected InstructionsBuilder(JsonObject jsonObject) {
|
||||
super(jsonObject);
|
||||
}
|
||||
// INSTRUCTIONS BUILDER
|
||||
|
||||
public InstructionsBuilder lifecycle(String lifecycle) {
|
||||
if (!instructionsJson.has(EntaxyProducerService.DIRECTIVES.LIFECYCLE))
|
||||
instructionsJson.add(EntaxyProducerService.DIRECTIVES.LIFECYCLE, new JsonArray());
|
||||
JsonArray lc = instructionsJson.get(EntaxyProducerService.DIRECTIVES.LIFECYCLE).getAsJsonArray();
|
||||
lc.add(lifecycle);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandBuilder command(String commandName) {
|
||||
if (!instructionsJson.has(commandName))
|
||||
instructionsJson.add(commandName, new JsonObject());
|
||||
if ("*".equals(commandName))
|
||||
return new AnyCommandBuilder(instructionsJson, instructionsJson.get(commandName).getAsJsonObject());
|
||||
else
|
||||
return new CommandBuilder(instructionsJson, instructionsJson.get(commandName).getAsJsonObject());
|
||||
protected static class InstructionsItemBuilder {
|
||||
|
||||
}
|
||||
protected JsonObject instructionsJson;
|
||||
|
||||
public AnyCommandBuilder any() {
|
||||
return (AnyCommandBuilder)this.command("*");
|
||||
}
|
||||
|
||||
public JsonObject getInstructions() {
|
||||
return this.instructionsJson;
|
||||
}
|
||||
|
||||
public String getInstructionsString() {
|
||||
return getInstructions().toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class CommandBuilder extends InstructionsBuilder {
|
||||
protected InstructionsItemBuilder(JsonObject jsonObject) {
|
||||
this.instructionsJson = jsonObject;
|
||||
}
|
||||
|
||||
protected JsonObject commandJson;
|
||||
|
||||
protected CommandBuilder(JsonObject instructionsObject, JsonObject commandObject) {
|
||||
super(instructionsObject);
|
||||
commandJson = commandObject;
|
||||
}
|
||||
|
||||
public CommandBuilder set(String name, Object value) {
|
||||
this.commandJson.remove(name);
|
||||
this.commandJson.add(name, sharedGson.toJsonTree(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class AnyCommandBuilder extends CommandBuilder {
|
||||
}
|
||||
|
||||
protected AnyCommandBuilder(JsonObject instructionsObject, JsonObject commandObject) {
|
||||
super(instructionsObject, commandObject);
|
||||
}
|
||||
public static class InstructionsBuilder extends InstructionsItemBuilder {
|
||||
|
||||
public AnyCommandBuilder skip(String commandExprssion) {
|
||||
if (!this.commandJson.has(EntaxyProducerService.DIRECTIVES.SKIP))
|
||||
this.commandJson.add(EntaxyProducerService.DIRECTIVES.SKIP, new JsonArray());
|
||||
this.commandJson.get(EntaxyProducerService.DIRECTIVES.SKIP).getAsJsonArray().add(commandExprssion);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static InstructionsBuilder instructions() {
|
||||
return instructions(new JsonObject());
|
||||
}
|
||||
protected InstructionsBuilder(JsonObject jsonObject) {
|
||||
super(jsonObject);
|
||||
}
|
||||
|
||||
public static InstructionsBuilder instructions(JsonObject jsonObject) {
|
||||
return new InstructionsBuilder(jsonObject);
|
||||
}
|
||||
|
||||
//CONFIGURATION BUILDER
|
||||
public InstructionsBuilder lifecycle(String lifecycle) {
|
||||
if (!instructionsJson.has(EntaxyProducerService.DIRECTIVES.LIFECYCLE))
|
||||
instructionsJson.add(EntaxyProducerService.DIRECTIVES.LIFECYCLE, new JsonArray());
|
||||
JsonArray lc = instructionsJson.get(EntaxyProducerService.DIRECTIVES.LIFECYCLE).getAsJsonArray();
|
||||
lc.add(lifecycle);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// UTILS
|
||||
|
||||
public static boolean isPattern(String type) {
|
||||
return type.contains(EntaxyProducer.PATTERN_CHAR_ANY);
|
||||
}
|
||||
public CommandBuilder command(String commandName) {
|
||||
if (!instructionsJson.has(commandName))
|
||||
instructionsJson.add(commandName, new JsonObject());
|
||||
if ("*".equals(commandName))
|
||||
return new AnyCommandBuilder(instructionsJson, instructionsJson.get(commandName).getAsJsonObject());
|
||||
else
|
||||
return new CommandBuilder(instructionsJson, instructionsJson.get(commandName).getAsJsonObject());
|
||||
|
||||
public static String toRegexPattern(String type) {
|
||||
return type.replaceAll("\\.", "\\\\.")
|
||||
.replaceAll("\\" + EntaxyProducer.PATTERN_CHAR_ANY, "\\.*");
|
||||
}
|
||||
|
||||
public static boolean isMatched(String typePattern, String type) {
|
||||
return Pattern.matches(toRegexPattern(typePattern), type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public AnyCommandBuilder any() {
|
||||
return (AnyCommandBuilder) this.command("*");
|
||||
}
|
||||
|
||||
public JsonObject getInstructions() {
|
||||
return this.instructionsJson;
|
||||
}
|
||||
|
||||
public String getInstructionsString() {
|
||||
return getInstructions().toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class CommandBuilder extends InstructionsBuilder {
|
||||
|
||||
protected JsonObject commandJson;
|
||||
|
||||
protected CommandBuilder(JsonObject instructionsObject, JsonObject commandObject) {
|
||||
super(instructionsObject);
|
||||
commandJson = commandObject;
|
||||
}
|
||||
|
||||
public CommandBuilder set(String name, Object value) {
|
||||
this.commandJson.remove(name);
|
||||
this.commandJson.add(name, sharedGson.toJsonTree(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class AnyCommandBuilder extends CommandBuilder {
|
||||
|
||||
protected AnyCommandBuilder(JsonObject instructionsObject, JsonObject commandObject) {
|
||||
super(instructionsObject, commandObject);
|
||||
}
|
||||
|
||||
public AnyCommandBuilder skip(String commandExprssion) {
|
||||
if (!this.commandJson.has(EntaxyProducerService.DIRECTIVES.SKIP))
|
||||
this.commandJson.add(EntaxyProducerService.DIRECTIVES.SKIP, new JsonArray());
|
||||
this.commandJson.get(EntaxyProducerService.DIRECTIVES.SKIP).getAsJsonArray().add(commandExprssion);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static InstructionsBuilder instructions() {
|
||||
return instructions(new JsonObject());
|
||||
}
|
||||
|
||||
public static InstructionsBuilder instructions(JsonObject jsonObject) {
|
||||
return new InstructionsBuilder(jsonObject);
|
||||
}
|
||||
|
||||
// CONFIGURATION BUILDER
|
||||
|
||||
|
||||
// UTILS
|
||||
|
||||
public static boolean isPattern(String type) {
|
||||
return type.contains(EntaxyProducer.PATTERN_CHAR_ANY);
|
||||
}
|
||||
|
||||
public static String toRegexPattern(String type) {
|
||||
return type.replaceAll("\\.", "\\\\.")
|
||||
.replaceAll("\\" + EntaxyProducer.PATTERN_CHAR_ANY, "\\.*");
|
||||
}
|
||||
|
||||
public static boolean isMatched(String typePattern, String type) {
|
||||
return Pattern.matches(toRegexPattern(typePattern), type);
|
||||
}
|
||||
|
||||
public static Map<String, Object> getFactoryEssence(EntaxyFactory factory) {
|
||||
return getFactoryEssence(factory, "");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Object> getFactoryEssence(EntaxyFactory factory, String prefix) {
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
JsonObject config = JSONUtils.getJsonRootObject(factory.getJsonConfiguration());
|
||||
|
||||
if (config == null)
|
||||
return result;
|
||||
|
||||
if (!config.has(EntaxyFactory.CONFIGURATION.FACTORY_SECTION_NAME))
|
||||
return result;
|
||||
|
||||
Object obj = JSONUtils.element2object(config.get(EntaxyFactory.CONFIGURATION.FACTORY_SECTION_NAME));
|
||||
|
||||
if (!(obj instanceof Map))
|
||||
return result;
|
||||
|
||||
result.putAll((Map<String, Object>) ((Map<String, Object>) obj).entrySet().stream()
|
||||
.collect(() -> new LinkedHashMap<String, Object>(),
|
||||
(m, e) -> m.put(String.format("%s%s", prefix, e.getKey()), e.getValue()), HashMap::putAll));
|
||||
|
||||
result.putAll(factory.getTypeInfo().entrySet().stream()
|
||||
.collect(() -> new LinkedHashMap<String, Object>(),
|
||||
(m, e) -> m.put(String.format("%stypeinfo.%s", prefix, e.getKey()), e.getValue()),
|
||||
HashMap::putAll)
|
||||
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean factoryMatches(String filter, EntaxyFactory factory) {
|
||||
try {
|
||||
return factoryMatchesUnsafe(filter, factory);
|
||||
} catch (InvalidSyntaxException ignore) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean factoryMatchesUnsafe(String filter, EntaxyFactory factory) throws InvalidSyntaxException {
|
||||
return factoryMatches(FrameworkUtil.createFilter(filter), factory);
|
||||
}
|
||||
|
||||
public static boolean factoryMatches(Filter filter, EntaxyFactory factory) {
|
||||
return filter.matches(getFactoryEssence(factory));
|
||||
}
|
||||
|
||||
public static List<EntaxyFactory> filterFactories(String filter, List<EntaxyFactory> factories) {
|
||||
try {
|
||||
return filterFactoriesUnsafe(filter, factories);
|
||||
} catch (InvalidSyntaxException ignore) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<EntaxyFactory> filterFactoriesUnsafe(String filter, List<EntaxyFactory> factories)
|
||||
throws InvalidSyntaxException {
|
||||
Filter osgiFilter = FrameworkUtil.createFilter(filter);
|
||||
|
||||
return filterFactories(osgiFilter, factories);
|
||||
|
||||
}
|
||||
|
||||
public static List<EntaxyFactory> filterFactories(Filter filter, List<EntaxyFactory> factories) {
|
||||
return factories.stream().filter(f -> factoryMatches(filter, f)).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
|
||||
<artifactId>object-producing</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<version>1.10.0</version>
|
||||
</parent>
|
||||
<groupId>ru.entaxy.esb.platform.runtime.core.object-producing</groupId>
|
||||
<artifactId>object-producer-core</artifactId>
|
||||
@ -12,7 +12,13 @@
|
||||
<description>ENTAXY :: PLATFORM :: CORE :: OBJECT PRODUCING :: PRODUCER CORE</description>
|
||||
|
||||
<properties>
|
||||
<bundle.osgi.export.pkg>ru.entaxy.platform.core.producer.*</bundle.osgi.export.pkg>
|
||||
<bundle.osgi.export.pkg>
|
||||
ru.entaxy.platform.core.producer.executor*,
|
||||
ru.entaxy.platform.core.producer.audit,
|
||||
ru.entaxy.platform.core.producer.impl,
|
||||
ru.entaxy.platform.core.producer.support,
|
||||
ru.entaxy.platform.core.producer.wrapper
|
||||
</bundle.osgi.export.pkg>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -32,6 +38,24 @@
|
||||
<groupId>org.apache.camel</groupId>
|
||||
<artifactId>camel-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.entaxy.esb.platform.runtime.base</groupId>
|
||||
<artifactId>base-extensions-support</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ru.entaxy.platform.logging</groupId>
|
||||
<artifactId>cef-logger-layout</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ru.entaxy.platform.logging</groupId>
|
||||
<artifactId>entaxy-audit</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -6,7 +6,7 @@
|
||||
"validate":{},
|
||||
"generate":{},
|
||||
"build":{"artifact.version.policy":"dated-embedded"},
|
||||
"install":{"installLocal":false, "update":""},
|
||||
"install":{"installLocal":false, "update":"", "startLevel": 120},
|
||||
"deploy":{"deployLocal":false},
|
||||
"store": {}
|
||||
},
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -26,7 +26,6 @@
|
||||
package ru.entaxy.platform.core.producer.executor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
@ -41,6 +40,9 @@ import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ru.entaxy.esb.platform.runtime.base.extensions.api.EntaxyExtendable;
|
||||
import ru.entaxy.esb.platform.runtime.base.extensions.api.EntaxyExtension;
|
||||
import ru.entaxy.esb.platform.runtime.base.extensions.api.EntaxyExtensionsProvider;
|
||||
import ru.entaxy.platform.base.support.CommonUtils;
|
||||
import ru.entaxy.platform.base.support.DependencySorter;
|
||||
import ru.entaxy.platform.base.support.JSONUtils;
|
||||
@ -72,6 +74,26 @@ public class ProducingExecutor {
|
||||
|
||||
protected ExecutionPlan executionPlan = null;
|
||||
|
||||
protected final List<EntaxyExtension> extensions = new ArrayList<>();
|
||||
|
||||
public static class EntaxyExtensionsProviderImpl implements EntaxyExtensionsProvider {
|
||||
|
||||
List<EntaxyExtension> entaxyExtensions;
|
||||
|
||||
public EntaxyExtensionsProviderImpl(List<EntaxyExtension> entaxyExtensions) {
|
||||
if (entaxyExtensions == null)
|
||||
this.entaxyExtensions = new ArrayList<>();
|
||||
else
|
||||
this.entaxyExtensions = entaxyExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EntaxyExtension> getExtensions() {
|
||||
return this.entaxyExtensions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ProducingExecutor(JsonObject configuration, String buildInstructions
|
||||
, EntaxyProducerService producerService) throws Exception {
|
||||
this.configuration = configuration;
|
||||
@ -198,6 +220,7 @@ public class ProducingExecutor {
|
||||
});
|
||||
executionPlan.tasks = sorted;
|
||||
applyDirectives(directives);
|
||||
|
||||
}
|
||||
|
||||
protected void applyDirectives(JsonObject directives) {
|
||||
@ -261,6 +284,18 @@ public class ProducingExecutor {
|
||||
producerResult.commandResult("#plan").result(true).resultObject(executionPlan);
|
||||
producerResult.commandResult("#init").result(true).resultObject(configuration);
|
||||
|
||||
// add all awailable extensions to task executors
|
||||
if (producerService instanceof EntaxyExtendable) {
|
||||
producerResult.commandResult("#extensions").result(true).resultObject(
|
||||
(EntaxyExtensionsProvider)new EntaxyExtensionsProviderImpl(((EntaxyExtendable)producerService).getExtensions())
|
||||
);
|
||||
} else {
|
||||
producerResult.commandResult("#extensions").result(true).resultObject(
|
||||
(EntaxyExtensionsProvider)new EntaxyExtensionsProviderImpl(null)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return execute(producerResult);
|
||||
|
||||
}
|
||||
@ -295,4 +330,5 @@ public class ProducingExecutor {
|
||||
|
||||
return producerResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -36,60 +36,68 @@ import ru.entaxy.platform.core.producer.api.ProducerResult.CommandResult;
|
||||
|
||||
public abstract class AbstractTask {
|
||||
|
||||
protected boolean isPrintOutput = false;
|
||||
|
||||
protected List<Generated> oldResults = new LinkedList<>();
|
||||
|
||||
protected Generated generatedResult = null;
|
||||
|
||||
protected AbstractTask mergeTo = null;
|
||||
|
||||
protected boolean isFinal = true;
|
||||
|
||||
public abstract String getInfo();
|
||||
protected boolean isPrintOutput = false;
|
||||
|
||||
public abstract boolean execute(
|
||||
ProducerResult currentResult
|
||||
, CommandResult currentCommand
|
||||
, EntaxyProducerService producerService
|
||||
, Map<String, Object> instructions) throws Exception;
|
||||
|
||||
protected void printOutput(String message) {
|
||||
if (this.isPrintOutput)
|
||||
// OUTPUT TO CONSOLE
|
||||
System.out.println(message);
|
||||
}
|
||||
|
||||
public boolean isPrintOutput() {
|
||||
return isPrintOutput;
|
||||
}
|
||||
protected List<Generated> oldResults = new LinkedList<>();
|
||||
|
||||
public void setPrintOutput(boolean isPrintOutput) {
|
||||
this.isPrintOutput = isPrintOutput;
|
||||
}
|
||||
protected GenerationModel generationModel;
|
||||
|
||||
public Generated getGeneratedResult() {
|
||||
return generatedResult;
|
||||
}
|
||||
protected Generated generatedResult = null;
|
||||
|
||||
public void mergeTo(AbstractTask abstractTask) {
|
||||
this.mergeTo = abstractTask;
|
||||
}
|
||||
|
||||
public boolean isToMerge() {
|
||||
return this.mergeTo != null;
|
||||
}
|
||||
protected AbstractTask mergeTo = null;
|
||||
|
||||
public boolean isFinal() {
|
||||
return isFinal;
|
||||
}
|
||||
protected boolean isFinal = true;
|
||||
|
||||
public void setFinal(boolean isFinal) {
|
||||
this.isFinal = isFinal;
|
||||
}
|
||||
|
||||
public void updateGenerated(Generated generated) {
|
||||
oldResults.add(generatedResult);
|
||||
this.generatedResult = generated;
|
||||
}
|
||||
public abstract String getInfo();
|
||||
|
||||
public abstract boolean execute(
|
||||
ProducerResult currentResult, CommandResult currentCommand, EntaxyProducerService producerService,
|
||||
Map<String, Object> instructions) throws Exception;
|
||||
|
||||
public GenerationModel getGenerationModel() {
|
||||
return generationModel;
|
||||
}
|
||||
|
||||
public void setGenerationModel(GenerationModel generationModel) {
|
||||
this.generationModel = generationModel;
|
||||
}
|
||||
|
||||
protected void printOutput(String message) {
|
||||
if (this.isPrintOutput)
|
||||
// OUTPUT TO CONSOLE
|
||||
System.out.println(message);
|
||||
}
|
||||
|
||||
public boolean isPrintOutput() {
|
||||
return isPrintOutput;
|
||||
}
|
||||
|
||||
public void setPrintOutput(boolean isPrintOutput) {
|
||||
this.isPrintOutput = isPrintOutput;
|
||||
}
|
||||
|
||||
public Generated getGeneratedResult() {
|
||||
return generatedResult;
|
||||
}
|
||||
|
||||
public void mergeTo(AbstractTask abstractTask) {
|
||||
this.mergeTo = abstractTask;
|
||||
}
|
||||
|
||||
public boolean isToMerge() {
|
||||
return this.mergeTo != null;
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return isFinal;
|
||||
}
|
||||
|
||||
public void setFinal(boolean isFinal) {
|
||||
this.isFinal = isFinal;
|
||||
}
|
||||
|
||||
public void updateGenerated(Generated generated) {
|
||||
oldResults.add(generatedResult);
|
||||
this.generatedResult = generated;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -44,54 +44,57 @@ import ru.entaxy.platform.core.producer.executor.objectmodel.ObjectModel;
|
||||
|
||||
public class CalculateTask extends AbstractObjectTask {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(CalculateTask.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(CalculateTask.class);
|
||||
|
||||
private static Gson GSON = new Gson();
|
||||
|
||||
public static boolean hasCalculations(FactoredObject factoredObject) {
|
||||
return factoredObject.getInternals().stream().filter(obj -> (obj instanceof Calculation))
|
||||
.count() > 0;
|
||||
}
|
||||
|
||||
public CalculateTask(FactoredObject factoredObject) {
|
||||
super(factoredObject);
|
||||
}
|
||||
private static Gson GSON = JSONUtils.GSON;
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "CALCULATE FOR " + "[" + origin.getObjectId() + "]";
|
||||
}
|
||||
public static boolean hasCalculations(FactoredObject factoredObject) {
|
||||
return factoredObject.getInternals().stream().filter(obj -> (obj instanceof Calculation))
|
||||
.count() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(ProducerResult currentResult, CommandResult currentCommand,
|
||||
EntaxyProducerService producerService, Map<String, Object> instructions) throws Exception {
|
||||
|
||||
ObjectModel objectModel = currentResult.findResultObject(ObjectModel.class);
|
||||
|
||||
List<Calculation> calculations = this.origin.getInternals().stream()
|
||||
.filter(obj -> (obj instanceof Calculation))
|
||||
.map(obj -> (Calculation)obj)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (Calculation calculation: calculations) {
|
||||
Object result = calculation.calculate(objectModel, origin);
|
||||
printOutput("CALCULATION RESOLVED TO :: " + result);
|
||||
printOutput("\n REPLACE"
|
||||
+ "\n\t" + calculation.origin
|
||||
+ "\n\tWITH :: " + GSON.toJsonTree(result)
|
||||
+ "\n\tAT :: " + calculation.relativePath);
|
||||
String currentPath = calculation.relativePath;
|
||||
String targetPath = calculation.getTargetPath();
|
||||
boolean remove = (!currentPath.equals(targetPath) && calculation.isRemoveResolved());
|
||||
targetPath = targetPath.replace("$.", "");
|
||||
JSONUtils.replaceValue(origin.origin, targetPath, GSON.toJsonTree(result));
|
||||
if (remove) {
|
||||
JSONUtils.replaceValue(origin.origin, currentPath, GSON.toJsonTree("TO_REMOVE"));
|
||||
}
|
||||
public CalculateTask(FactoredObject factoredObject) {
|
||||
super(factoredObject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "CALCULATE FOR " + "[" + origin.getObjectId() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(ProducerResult currentResult, CommandResult currentCommand,
|
||||
EntaxyProducerService producerService, Map<String, Object> instructions) throws Exception {
|
||||
|
||||
ObjectModel objectModel = currentResult.findResultObject(ObjectModel.class);
|
||||
|
||||
List<Calculation> calculations = this.origin.getInternals().stream()
|
||||
.filter(obj -> (obj instanceof Calculation))
|
||||
.map(obj -> (Calculation) obj)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (Calculation calculation : calculations) {
|
||||
Object result = calculation.calculate(objectModel, origin, producerService);
|
||||
if (!Calculation.isValidResult(result))
|
||||
if (calculation.hasFallbackObject())
|
||||
result = calculation.getFallbackObject();
|
||||
printOutput("CALCULATION RESOLVED TO :: " + result);
|
||||
printOutput("\n REPLACE"
|
||||
+ "\n\t" + calculation.origin
|
||||
+ "\n\tWITH :: " + GSON.toJsonTree(result)
|
||||
+ "\n\tAT :: " + calculation.relativePath);
|
||||
String currentPath = calculation.relativePath;
|
||||
String targetPath = calculation.getTargetPath();
|
||||
boolean remove = (!currentPath.equals(targetPath) && calculation.isRemoveResolved());
|
||||
targetPath = targetPath.replace("$.", "");
|
||||
JSONUtils.replaceValue(origin.origin, targetPath, GSON.toJsonTree(result));
|
||||
if (remove) {
|
||||
JSONUtils.replaceValue(origin.origin, currentPath, GSON.toJsonTree("TO_REMOVE"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -30,6 +30,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -37,202 +38,337 @@ import org.slf4j.LoggerFactory;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ru.entaxy.platform.base.support.CommonUtils;
|
||||
import ru.entaxy.platform.base.support.JSONUtils;
|
||||
import ru.entaxy.platform.base.objects.EntaxyObject.FIELDS;
|
||||
import ru.entaxy.platform.base.objects.EntaxyObject.HEADERS;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory.OutputInfo;
|
||||
import ru.entaxy.platform.base.support.CommonUtils;
|
||||
import ru.entaxy.platform.base.support.JSONUtils;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
|
||||
import ru.entaxy.platform.core.producer.api.ProducerResult;
|
||||
import ru.entaxy.platform.core.producer.api.ProducerResult.CommandResult;
|
||||
import ru.entaxy.platform.core.producer.executor.objectmodel.FactoredObject;
|
||||
import ru.entaxy.platform.core.producer.executor.objectmodel.FactoredObjectRef;
|
||||
|
||||
public class GenerateTask extends AbstractObjectTask {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(GenerateTask.class);
|
||||
|
||||
public static final String CONTENT_FIELD = "##_CONTENT";
|
||||
|
||||
public static final String INSTRUCTIONS_FIELD = "##instructions";
|
||||
public static final String GENERATION_PROPERTIES_FIELD = "##generation";
|
||||
public static final String SKIP_OBJECT_PUBLISHING_FIELD = "##SKIP_OBJECT_PUBLISHING";
|
||||
public static final String DIRECTIVE_SKIP_PUBLISH = "@SKIP_PUBLISH";
|
||||
|
||||
public String factoryId;
|
||||
public String factoryType;
|
||||
//public String objectId;
|
||||
public JsonElement properties;
|
||||
private static final Logger log = LoggerFactory.getLogger(GenerateTask.class);
|
||||
|
||||
public String outputType = "init";
|
||||
public String scope = "public";
|
||||
|
||||
public Map<String, Object> generationProperties = new HashMap<>();
|
||||
|
||||
public GenerateTask(FactoredObject factoredObject) {
|
||||
super(factoredObject);
|
||||
fillFromOrigin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(ProducerResult currentResult, CommandResult currentCommand,
|
||||
EntaxyProducerService producerService, Map<String, Object> instructions) throws Exception {
|
||||
if (!CommonUtils.isValid(factoryId))
|
||||
throw new IllegalArgumentException("Factory ID is null");
|
||||
if (!CommonUtils.isValid(factoryType))
|
||||
try {
|
||||
EntaxyFactory f = producerService.findFactoryById(factoryId);
|
||||
if (f != null) {
|
||||
log.debug("Factory found by id [{}] with type [{}]", f.getId(), f.getType());
|
||||
factoryType = f.getType();
|
||||
} else
|
||||
throw new IllegalArgumentException("Factory not found: " + factoryId);
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
log.debug("Execute for type [{}] with factoryId [{}]", factoryType, factoryId);
|
||||
Map<String, Object> effectiveProperties = createEffectiveProperties(instructions);
|
||||
EntaxyFactory factory = producerService.getProducerForType(factoryType).getFactoryById(factoryId);
|
||||
this.generatedResult = factory.generate(outputType, scope, effectiveProperties);
|
||||
// objectId could be changed by pre/post processor, so we update it
|
||||
// TODO move string to const
|
||||
String objectId = this.generatedResult.getProperties()
|
||||
.getOrDefault(FIELDS.OBJECT_ID, origin.getObjectId()).toString();
|
||||
if (!origin.getObjectId().equals(objectId)) {
|
||||
log.debug("Changing objectId from [{}] to [{}]", origin.getObjectId(), objectId);
|
||||
origin.setObjectId(objectId);
|
||||
}
|
||||
|
||||
boolean publishObject = !isSkipPublish(factory, this.outputType, this.scope);
|
||||
|
||||
// check for old-style configuration
|
||||
// TODO remove in next releases
|
||||
if (publishObject)
|
||||
if (effectiveProperties.containsKey(SKIP_OBJECT_PUBLISHING_FIELD)) {
|
||||
try {
|
||||
publishObject = !((Boolean)effectiveProperties.get(SKIP_OBJECT_PUBLISHING_FIELD));
|
||||
} catch (Exception e) {
|
||||
// NOOP
|
||||
}
|
||||
}
|
||||
|
||||
GeneratedHeaders headers = GeneratedHeaders.getHeaders(this.generatedResult.getProperties());
|
||||
headers.set(HEADERS.ENTAXY_GENERATED, "true");
|
||||
if (publishObject) {
|
||||
headers.set(HEADERS.MAIN_OBJECT, origin.getObjectId() + ":" + factoryType + ":" + scope);
|
||||
headers.append(HEADERS.GENERATED_OBJECTS, origin.getObjectId() + ":" + factoryType + ":" + scope);
|
||||
// headers.set(GeneratedHeaders.HEADER_MAIN_OBJECT_TYPE, factoryType);
|
||||
// headers.set(GeneratedHeaders.HEADER_MAIN_OBJECT_FACTORY_ID, factoryId);
|
||||
// headers.append(GeneratedHeaders.HEADER_OBJECT_ID, origin.getObjectId());
|
||||
// headers.append(GeneratedHeaders.HEADER_OBJECT_TYPE, factoryType);
|
||||
headers.append(HEADERS.GENERATED_OBJECTS_CONFIG
|
||||
, Base64.getEncoder().encodeToString(
|
||||
getFilteredObjectData(origin.origin, factory)
|
||||
.toString().getBytes()));
|
||||
}
|
||||
this.generationProperties.clear();
|
||||
this.generationProperties.putAll(effectiveProperties);
|
||||
this.generatedResult.getProperties().put(GENERATION_PROPERTIES_FIELD, new HashMap<String, Object>(this.generationProperties));
|
||||
return true;
|
||||
}
|
||||
|
||||
protected JsonObject getFilteredObjectData(JsonObject originData, EntaxyFactory factory) {
|
||||
JsonObject result = getFilteredObject(originData, factory);
|
||||
if (result == null)
|
||||
result = new JsonObject();
|
||||
return result;
|
||||
}
|
||||
public static final String CONTENT_FIELD = "##_CONTENT";
|
||||
|
||||
protected JsonObject getFilteredObject(JsonObject originObject, EntaxyFactory factory) {
|
||||
JsonObject result = new JsonObject();
|
||||
for (Entry<String, JsonElement> entry: originObject.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
if (FactoredObject.EMBEDDED_FIELD.equals(name) || FactoredObject.IGNORE_SECTION.equals(name))
|
||||
continue;
|
||||
JsonElement je = entry.getValue();
|
||||
if (je.isJsonObject()) {
|
||||
JsonObject jo = je.getAsJsonObject();
|
||||
if (jo.has(EntaxyFactory.CONFIGURATION.DIRECTIVES.INTERNAL)) {
|
||||
boolean skip = true;
|
||||
try {
|
||||
skip = jo.get(EntaxyFactory.CONFIGURATION.DIRECTIVES.INTERNAL).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
// NOOP
|
||||
}
|
||||
if (skip)
|
||||
continue;
|
||||
}
|
||||
JsonObject filtered = getFilteredObject(jo, factory);
|
||||
if (filtered != null)
|
||||
result.add(name, filtered);
|
||||
} else {
|
||||
result.add(name, je);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public static final String INSTRUCTIONS_FIELD = "##instructions";
|
||||
public static final String GENERATION_PROPERTIES_FIELD = "##generation";
|
||||
public static final String SKIP_OBJECT_PUBLISHING_FIELD = "##SKIP_OBJECT_PUBLISHING";
|
||||
|
||||
protected boolean isSkipPublish(EntaxyFactory factory, String outputType, String scope) {
|
||||
OutputInfo info = factory.getOutputByType(outputType);
|
||||
if (info == null)
|
||||
return false;
|
||||
Map<String, Object> config = info.getConfig();
|
||||
if (config == null)
|
||||
return false;
|
||||
if (config.containsKey(DIRECTIVE_SKIP_PUBLISH)) {
|
||||
try {
|
||||
// check scopes
|
||||
Map<String, Object> data = (Map<String, Object>)config.get(DIRECTIVE_SKIP_PUBLISH);
|
||||
if (data.containsKey(EntaxyFactory.CONFIGURATION.OUTPUTS.ATTRIBUTES.SCOPES)) {
|
||||
List<String> scopes = (List<String>)data.get(EntaxyFactory.CONFIGURATION.OUTPUTS.ATTRIBUTES.SCOPES);
|
||||
return scopes.contains(scope);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Map<String, Object> createEffectiveProperties(Map<String, Object> instructions){
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put(INSTRUCTIONS_FIELD, instructions);
|
||||
JsonElement effectiveProperties = this.properties.deepCopy();
|
||||
if (effectiveProperties.isJsonObject()) {
|
||||
JsonObject jobj = effectiveProperties.getAsJsonObject();
|
||||
for (Entry<String, JsonElement> entry: origin.origin.entrySet()) {
|
||||
/*if (entry.getKey().equals(FIELDS.PROPERTIES))
|
||||
continue;*/
|
||||
if (jobj.has(entry.getKey()))
|
||||
continue;
|
||||
jobj.add(entry.getKey(), entry.getValue());
|
||||
}
|
||||
result.putAll(JSONUtils.element2map(effectiveProperties));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void fillFromOrigin() {
|
||||
this.factoryId = origin.factoryId;
|
||||
// this.objectId = origin.getObjectId();
|
||||
this.factoryType = origin.getObjectType();
|
||||
this.scope = origin.scope;
|
||||
this.properties = origin.origin.get(FIELDS.PROPERTIES);
|
||||
|
||||
if (CommonUtils.isValid(origin.getOutputType()))
|
||||
this.outputType = origin.getOutputType();
|
||||
|
||||
}
|
||||
|
||||
public void updateObjectId(String objectId) {
|
||||
// this.objectId = objectId;
|
||||
this.origin.setObjectId(objectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "GENERATE " + "[" + origin.getObjectId() + "] :: " + factoryId + "/" + outputType;
|
||||
}
|
||||
// TODO move to EntaxyFactory
|
||||
public static final String HEADER_OBJECT_MAP = "@OBJECT-MAP";
|
||||
|
||||
// TODO move to EntaxyFactory
|
||||
public static final String DIRECTIVE_SKIP_PUBLISH = "@SKIP_PUBLISH";
|
||||
|
||||
// TODO move to EntaxyFactory
|
||||
public static final String DIRECTIVE_PUBLISH_AS = "@PUBLISH_AS";
|
||||
|
||||
// TODO move to EntaxyFactory
|
||||
public static final String DIRECTIVE_SKIP_PROVIDE = "@SKIP_PROVIDE";
|
||||
|
||||
public String factoryId;
|
||||
public String factoryType;
|
||||
// public String objectId;
|
||||
public JsonElement properties;
|
||||
|
||||
public String outputType = "init";
|
||||
public String scope = "public";
|
||||
|
||||
public Map<String, Object> generationProperties = new HashMap<>();
|
||||
|
||||
public FactoredObjectRef originRef = null;
|
||||
|
||||
public FactoredObject originObject = null;
|
||||
|
||||
public GenerateTask(FactoredObject factoredObject) {
|
||||
super(factoredObject);
|
||||
fillFromOrigin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(ProducerResult currentResult, CommandResult currentCommand,
|
||||
EntaxyProducerService producerService, Map<String, Object> instructions) throws Exception {
|
||||
if (!CommonUtils.isValid(factoryId))
|
||||
throw new IllegalArgumentException("Factory ID is null");
|
||||
if (!CommonUtils.isValid(factoryType))
|
||||
try {
|
||||
EntaxyFactory f = producerService.findFactoryById(factoryId);
|
||||
if (f != null) {
|
||||
log.debug("Factory found by id [{}] with type [{}]", f.getId(), f.getType());
|
||||
factoryType = f.getType();
|
||||
} else
|
||||
throw new IllegalArgumentException("Factory not found: " + factoryId);
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
log.debug("Execute for type [{}] with factoryId [{}]/[{}]", factoryType, factoryId, outputType);
|
||||
Map<String, Object> effectiveProperties = createEffectiveProperties(instructions);
|
||||
EntaxyFactory factory = producerService.getProducerForType(factoryType).getFactoryById(factoryId);
|
||||
|
||||
// check hierarchy
|
||||
if (factory == null) {
|
||||
factory = producerService.findFactoryById(factoryId);
|
||||
boolean typeChecked = false;
|
||||
EntaxyFactory current = factory;
|
||||
while (!typeChecked && current != null) {
|
||||
typeChecked = current.getType().equals(factoryType);
|
||||
if (typeChecked)
|
||||
break;
|
||||
current = producerService.findFactoryById(current.getParent());
|
||||
}
|
||||
if (!typeChecked) {
|
||||
log.error("FAILED producing for output [{}]: factory [{}] is not of type [{}]", outputType, factoryId,
|
||||
factoryType);
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Factory [%s] is not of type [%s]", factoryId, factoryType));
|
||||
}
|
||||
}
|
||||
|
||||
this.generatedResult = factory.generate(outputType, scope, effectiveProperties);
|
||||
// objectId could be changed by pre/post processor, so we update it
|
||||
// TODO move string to const
|
||||
String objectId = this.generatedResult.getProperties()
|
||||
.getOrDefault(FIELDS.OBJECT_ID, origin.getObjectId()).toString();
|
||||
if (!origin.getObjectId().equals(objectId)) {
|
||||
log.debug("Changing objectId from [{}] to [{}]", origin.getObjectId(), objectId);
|
||||
origin.setObjectId(objectId);
|
||||
}
|
||||
|
||||
boolean publishObject = !isSkipPublish(factory, this.outputType, this.scope);
|
||||
|
||||
// check for old-style configuration
|
||||
// TODO remove in next releases
|
||||
if (publishObject)
|
||||
if (effectiveProperties.containsKey(SKIP_OBJECT_PUBLISHING_FIELD)) {
|
||||
try {
|
||||
publishObject = !((Boolean) effectiveProperties.get(SKIP_OBJECT_PUBLISHING_FIELD));
|
||||
} catch (Exception e) {
|
||||
// NOOP
|
||||
}
|
||||
}
|
||||
|
||||
// we prepare publish data for all objects
|
||||
JsonObject publishData = generationModel.publishDataStorage.generatePublishData(origin, factory, outputType);
|
||||
|
||||
|
||||
GeneratedHeaders headers = GeneratedHeaders.getHeaders(this.generatedResult.getProperties());
|
||||
headers.set(HEADERS.ENTAXY_GENERATED, "true");
|
||||
|
||||
if (publishObject) {
|
||||
|
||||
String publishedObjectId = origin.getObjectId();
|
||||
|
||||
String publishAsField = getPublishAs(factory, this.outputType, this.scope);
|
||||
if (CommonUtils.isValid(publishAsField)) {
|
||||
if (effectiveProperties.containsKey(publishAsField))
|
||||
publishedObjectId = effectiveProperties.getOrDefault(publishAsField, publishedObjectId).toString();
|
||||
}
|
||||
|
||||
if (!publishedObjectId.equals(origin.getObjectId()))
|
||||
headers.append(HEADER_OBJECT_MAP,
|
||||
origin.getObjectId() + ":" + factoryType + "::" + publishedObjectId + ":" + factoryType);
|
||||
|
||||
// set @SKIP_PROVIDE property
|
||||
if (isSkipProvide(factory, this.outputType, this.scope)) {
|
||||
this.generatedResult.getProperties().put(DIRECTIVE_SKIP_PROVIDE, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
headers.set(HEADERS.MAIN_OBJECT, publishedObjectId + ":" + factoryType + ":" + scope);
|
||||
headers.append(HEADERS.GENERATED_OBJECTS, publishedObjectId + ":" + factoryType + ":" + scope);
|
||||
// headers.set(GeneratedHeaders.HEADER_MAIN_OBJECT_TYPE, factoryType);
|
||||
// headers.set(GeneratedHeaders.HEADER_MAIN_OBJECT_FACTORY_ID, factoryId);
|
||||
// headers.append(GeneratedHeaders.HEADER_OBJECT_ID, origin.getObjectId());
|
||||
// headers.append(GeneratedHeaders.HEADER_OBJECT_TYPE, factoryType);
|
||||
headers.append(HEADERS.GENERATED_OBJECTS_CONFIG, Base64.getEncoder().encodeToString(
|
||||
publishData.toString().getBytes()));
|
||||
}
|
||||
this.generationProperties.clear();
|
||||
this.generationProperties.putAll(effectiveProperties);
|
||||
this.generatedResult.getProperties().put(GENERATION_PROPERTIES_FIELD,
|
||||
new HashMap<String, Object>(this.generationProperties));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected JsonObject getFilteredObjectData(JsonObject originData, EntaxyFactory factory, String outputType) {
|
||||
JsonObject result = getFilteredObject(originData, factory, outputType);
|
||||
if (result == null)
|
||||
result = new JsonObject();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected JsonObject getFilteredObject(JsonObject originObject, EntaxyFactory factory, String outputType) {
|
||||
JsonObject result = new JsonObject();
|
||||
|
||||
Map<String, JsonObject> factoryFields = factory.getOutputByType(outputType).getFields().stream()
|
||||
.collect(Collectors.toMap(fi -> fi.getName(), fi -> fi.getJsonOrigin()));
|
||||
|
||||
for (Entry<String, JsonElement> entry : originObject.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
if (FactoredObject.EMBEDDED_FIELD.equals(name) || FactoredObject.IGNORE_SECTION.equals(name))
|
||||
continue;
|
||||
|
||||
boolean skip = false;
|
||||
|
||||
// check @INTERNAL directive via factory data
|
||||
JsonObject joField = factoryFields.getOrDefault(name, new JsonObject());
|
||||
if (joField.has(EntaxyFactory.CONFIGURATION.DIRECTIVES.INTERNAL)) {
|
||||
try {
|
||||
skip = joField.get(EntaxyFactory.CONFIGURATION.DIRECTIVES.INTERNAL).getAsBoolean();
|
||||
} catch (Exception ignore) {
|
||||
// NOOP
|
||||
}
|
||||
}
|
||||
if (skip)
|
||||
continue;
|
||||
|
||||
JsonElement je = entry.getValue();
|
||||
if (je.isJsonObject()) {
|
||||
JsonObject jo = je.getAsJsonObject();
|
||||
|
||||
// check @INTERNAL directive via object data
|
||||
|
||||
if (jo.has(EntaxyFactory.CONFIGURATION.DIRECTIVES.INTERNAL)) {
|
||||
try {
|
||||
skip = jo.get(EntaxyFactory.CONFIGURATION.DIRECTIVES.INTERNAL).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
// NOOP
|
||||
}
|
||||
if (skip)
|
||||
continue;
|
||||
}
|
||||
JsonObject filtered = getFilteredObject(jo, factory, outputType);
|
||||
if (filtered != null)
|
||||
result.add(name, filtered);
|
||||
} else {
|
||||
result.add(name, je);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected String getPublishAs(EntaxyFactory factory, String outputType, String scope) {
|
||||
OutputInfo info = factory.getOutputByType(outputType);
|
||||
if (info == null)
|
||||
return null;
|
||||
Map<String, Object> config = info.getConfig();
|
||||
if (config == null)
|
||||
return null;
|
||||
if (config.containsKey(DIRECTIVE_PUBLISH_AS)) {
|
||||
try {
|
||||
// check scopes
|
||||
Map<String, Object> data = (Map<String, Object>) config.get(DIRECTIVE_PUBLISH_AS);
|
||||
if (data.containsKey(scope)) {
|
||||
return data.get(scope).toString();
|
||||
} else {
|
||||
if (data.containsKey("*")) {
|
||||
return data.get("*").toString();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean isSkipPublish(EntaxyFactory factory, String outputType, String scope) {
|
||||
OutputInfo info = factory.getOutputByType(outputType);
|
||||
if (info == null)
|
||||
return false;
|
||||
Map<String, Object> config = info.getConfig();
|
||||
if (config == null)
|
||||
return false;
|
||||
if (config.containsKey(DIRECTIVE_SKIP_PUBLISH)) {
|
||||
try {
|
||||
// check scopes
|
||||
Map<String, Object> data = (Map<String, Object>) config.get(DIRECTIVE_SKIP_PUBLISH);
|
||||
if (data.containsKey(EntaxyFactory.CONFIGURATION.OUTPUTS.ATTRIBUTES.SCOPES)) {
|
||||
List<String> scopes =
|
||||
(List<String>) data.get(EntaxyFactory.CONFIGURATION.OUTPUTS.ATTRIBUTES.SCOPES);
|
||||
return scopes.contains(scope);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isSkipProvide(EntaxyFactory factory, String outputType, String scope) {
|
||||
OutputInfo info = factory.getOutputByType(outputType);
|
||||
if (info == null)
|
||||
return false;
|
||||
Map<String, Object> config = info.getConfig();
|
||||
if (config == null)
|
||||
return false;
|
||||
if (config.containsKey(DIRECTIVE_SKIP_PROVIDE)) {
|
||||
try {
|
||||
// check scopes
|
||||
Map<String, Object> data = (Map<String, Object>) config.get(DIRECTIVE_SKIP_PROVIDE);
|
||||
if (data.containsKey(EntaxyFactory.CONFIGURATION.OUTPUTS.ATTRIBUTES.SCOPES)) {
|
||||
List<String> scopes =
|
||||
(List<String>) data.get(EntaxyFactory.CONFIGURATION.OUTPUTS.ATTRIBUTES.SCOPES);
|
||||
return scopes.contains(scope);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Map<String, Object> createEffectiveProperties(Map<String, Object> instructions) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put(INSTRUCTIONS_FIELD, instructions);
|
||||
JsonElement effectiveProperties = this.properties.deepCopy();
|
||||
if (effectiveProperties.isJsonObject()) {
|
||||
JsonObject jobj = effectiveProperties.getAsJsonObject();
|
||||
for (Entry<String, JsonElement> entry : origin.origin.entrySet()) {
|
||||
/*
|
||||
* if (entry.getKey().equals(FIELDS.PROPERTIES)) continue;
|
||||
*/
|
||||
if (jobj.has(entry.getKey()))
|
||||
continue;
|
||||
jobj.add(entry.getKey(), entry.getValue());
|
||||
}
|
||||
result.putAll(JSONUtils.element2map(effectiveProperties));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void fillFromOrigin() {
|
||||
this.factoryId = origin.factoryId;
|
||||
// this.objectId = origin.getObjectId();
|
||||
this.factoryType = origin.getObjectType();
|
||||
this.scope = origin.scope;
|
||||
this.properties = origin.origin.get(FIELDS.PROPERTIES);
|
||||
|
||||
if (CommonUtils.isValid(origin.getOutputType()))
|
||||
this.outputType = origin.getOutputType();
|
||||
|
||||
}
|
||||
|
||||
public void updateObjectId(String objectId) {
|
||||
// this.objectId = objectId;
|
||||
this.origin.setObjectId(objectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "GENERATE " + "[" + origin.getObjectId() + "] :: " + factoryId + "/" + outputType;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -33,6 +33,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ru.entaxy.platform.core.producer.executor.objectmodel.FactoredObject;
|
||||
import ru.entaxy.platform.core.producer.executor.objectmodel.FactoredObjectProxy;
|
||||
import ru.entaxy.platform.core.producer.executor.objectmodel.FactoredObjectRef;
|
||||
@ -40,106 +42,144 @@ import ru.entaxy.platform.core.producer.executor.objectmodel.ObjectModel;
|
||||
|
||||
public class GenerationModel {
|
||||
|
||||
protected ObjectModel objectModel;
|
||||
|
||||
protected List<AbstractTask> tasks = new LinkedList<>();
|
||||
|
||||
public Map<Object, List<AbstractTask>> objectToTasksMap = new HashMap<>();
|
||||
|
||||
public GenerationModel(ObjectModel objectModel) {
|
||||
this.objectModel = objectModel;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
for (FactoredObject fo: objectModel.objects)
|
||||
if (!fo.isEmbedded())
|
||||
tasks.addAll(generateTasksForObject(fo));
|
||||
}
|
||||
|
||||
protected List<AbstractTask> generateTasksForObject(FactoredObject fo) {
|
||||
public static final String DIRECTIVE_SKIP_MERGE = "@SKIP_MERGE";
|
||||
|
||||
if (fo instanceof FactoredObjectProxy)
|
||||
return Collections.singletonList(new ResolveObjectTask((FactoredObjectProxy)fo));
|
||||
|
||||
List<AbstractTask> localPreTasks = new LinkedList<>();
|
||||
List<AbstractTask> localPostTasks = new LinkedList<>();
|
||||
public static final String DIRECTIVE_PUBLISH_URESOLVED = "@PUBLISH_UNRESOLVED";
|
||||
|
||||
// first process embedded objects
|
||||
public static final String PUBLISH_UNRESOLVED_REF = "ref";
|
||||
public static final String PUBLISH_UNRESOLVED_OBJECT = "object";
|
||||
|
||||
List<FactoredObject> embedded = fo.embedded.stream().filter(f->(f instanceof FactoredObject))
|
||||
.map(f -> (FactoredObject)f)
|
||||
.collect(Collectors.toList());
|
||||
for (FactoredObject embeddedObject: embedded) {
|
||||
List<AbstractTask> tasksForEmbedded = generateTasksForObject(embeddedObject);
|
||||
localPreTasks.addAll(tasksForEmbedded);
|
||||
}
|
||||
public static final String UNRESOLVED_CONTAINER_NAME = "##_UNRESOLVED";
|
||||
|
||||
// process links to externalized embedded objects
|
||||
protected ObjectModel objectModel;
|
||||
|
||||
List<FactoredObjectRef> embeddedLinks = fo.embedded.stream().filter(f->(f instanceof FactoredObjectRef))
|
||||
.map(f -> (FactoredObjectRef)f)
|
||||
.filter(f -> !f.isBackRef())
|
||||
.filter(f -> f.isLink())
|
||||
.collect(Collectors.toList());
|
||||
for (FactoredObjectRef embeddedRef: embeddedLinks) {
|
||||
FactoredObject embeddedObject = embeddedRef.getTargetObject();
|
||||
List<AbstractTask> tasksForEmbedded = generateTasksForObject(embeddedObject);
|
||||
|
||||
// check the dependencies:
|
||||
// if embedded depends on main
|
||||
// then it must be generates after the main
|
||||
|
||||
List<FactoredObjectRef> refs = objectModel.refs.stream()
|
||||
.filter(r -> r.isDefinedIn(embeddedObject))
|
||||
.filter(r -> fo.equals(r.getTargetObject()))
|
||||
.collect(Collectors.toList());
|
||||
if (refs.isEmpty())
|
||||
localPreTasks.addAll(tasksForEmbedded);
|
||||
else
|
||||
localPostTasks.addAll(tasksForEmbedded);
|
||||
}
|
||||
protected List<AbstractTask> tasks = new LinkedList<>();
|
||||
|
||||
// process embedded refs
|
||||
|
||||
List<FactoredObjectRef> embeddedRefs = fo.embedded.stream().filter(f->(f instanceof FactoredObjectRef))
|
||||
.map(f -> (FactoredObjectRef)f)
|
||||
.filter(f -> !f.isBackRef())
|
||||
.filter(f -> !f.isLink() || f.isResolveAlways())
|
||||
.collect(Collectors.toList());
|
||||
for (FactoredObjectRef embeddedRef: embeddedRefs) {
|
||||
|
||||
if (!embeddedRef.isLink() || embeddedRef.isResolveAlways()) {
|
||||
localPreTasks.add(new ResolveRefTask(embeddedRef));
|
||||
if (!embeddedRef.isLink())
|
||||
if (!embeddedRef.isRefByValueOnly())
|
||||
localPreTasks.add(new GenerateRefTask(embeddedRef));
|
||||
}
|
||||
}
|
||||
|
||||
List<AbstractTask> currentTasks = new ArrayList<>(localPreTasks);
|
||||
|
||||
if (CalculateTask.hasCalculations(fo))
|
||||
currentTasks.add(new CalculateTask(fo));
|
||||
|
||||
GenerateTask generateTask = new GenerateTask(fo);
|
||||
public Map<Object, List<AbstractTask>> objectToTasksMap = new HashMap<>();
|
||||
|
||||
currentTasks.add(generateTask);
|
||||
public GeneratedObjectsPublishDataStorage publishDataStorage = new GeneratedObjectsPublishDataStorage();
|
||||
|
||||
for (AbstractTask at: localPreTasks)
|
||||
if (((at instanceof GenerateTask) || (at instanceof GenerateRefTask)) && !at.isToMerge() )
|
||||
currentTasks.add(new MergeTask(at, generateTask));
|
||||
|
||||
currentTasks.addAll(localPostTasks);
|
||||
|
||||
for (AbstractTask at: localPostTasks)
|
||||
if (((at instanceof GenerateTask) || (at instanceof GenerateRefTask)) && !at.isToMerge())
|
||||
currentTasks.add(new MergeTask(at, generateTask));
|
||||
|
||||
return currentTasks;
|
||||
}
|
||||
public GenerationModel(ObjectModel objectModel) {
|
||||
this.objectModel = objectModel;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
for (FactoredObject fo : objectModel.objects)
|
||||
if (!fo.isEmbedded())
|
||||
tasks.addAll(generateTasksForObject(fo, null, null));
|
||||
for (AbstractTask at : tasks)
|
||||
at.setGenerationModel(this);
|
||||
}
|
||||
|
||||
protected List<AbstractTask> generateTasksForObject(FactoredObject fo, FactoredObjectRef originRef,
|
||||
FactoredObject originObject) {
|
||||
|
||||
if (fo instanceof FactoredObjectProxy)
|
||||
return Collections.singletonList(new ResolveObjectTask((FactoredObjectProxy) fo));
|
||||
|
||||
List<AbstractTask> localPreTasks = new LinkedList<>();
|
||||
List<AbstractTask> localPostTasks = new LinkedList<>();
|
||||
|
||||
// first process embedded objects
|
||||
|
||||
List<FactoredObject> embedded = fo.embedded.stream().filter(f -> (f instanceof FactoredObject))
|
||||
.map(f -> (FactoredObject) f)
|
||||
.collect(Collectors.toList());
|
||||
for (FactoredObject embeddedObject : embedded) {
|
||||
List<AbstractTask> tasksForEmbedded = generateTasksForObject(embeddedObject, null, fo);
|
||||
localPreTasks.addAll(tasksForEmbedded);
|
||||
}
|
||||
|
||||
// process links to externalized embedded objects
|
||||
|
||||
List<FactoredObjectRef> embeddedLinks = fo.embedded.stream().filter(f -> (f instanceof FactoredObjectRef))
|
||||
.map(f -> (FactoredObjectRef) f)
|
||||
.filter(f -> !f.isBackRef())
|
||||
.filter(f -> f.isLink())
|
||||
.collect(Collectors.toList());
|
||||
for (FactoredObjectRef embeddedRef : embeddedLinks) {
|
||||
FactoredObject embeddedObject = embeddedRef.getTargetObject();
|
||||
List<AbstractTask> tasksForEmbedded = generateTasksForObject(embeddedObject, embeddedRef, fo);
|
||||
|
||||
// check the dependencies:
|
||||
// if embedded depends on main
|
||||
// then it must be generates after the main
|
||||
|
||||
List<FactoredObjectRef> refs = objectModel.refs.stream()
|
||||
.filter(r -> r.isDefinedIn(embeddedObject))
|
||||
.filter(r -> fo.equals(r.getTargetObject()))
|
||||
.collect(Collectors.toList());
|
||||
if (refs.isEmpty())
|
||||
localPreTasks.addAll(tasksForEmbedded);
|
||||
else
|
||||
localPostTasks.addAll(tasksForEmbedded);
|
||||
}
|
||||
|
||||
// process embedded refs
|
||||
|
||||
List<FactoredObjectRef> embeddedRefs = fo.embedded.stream().filter(f -> (f instanceof FactoredObjectRef))
|
||||
.map(f -> (FactoredObjectRef) f)
|
||||
.filter(f -> !f.isBackRef())
|
||||
.filter(f -> !f.isLink() || f.isResolveAlways())
|
||||
.collect(Collectors.toList());
|
||||
for (FactoredObjectRef embeddedRef : embeddedRefs) {
|
||||
|
||||
if (!embeddedRef.isLink() || embeddedRef.isResolveAlways()) {
|
||||
localPreTasks.add(new ResolveRefTask(embeddedRef));
|
||||
if (!embeddedRef.isLink())
|
||||
if (!embeddedRef.isRefByValueOnly())
|
||||
localPreTasks.add(new GenerateRefTask(embeddedRef));
|
||||
}
|
||||
}
|
||||
|
||||
List<AbstractTask> currentTasks = new ArrayList<>(localPreTasks);
|
||||
|
||||
if (CalculateTask.hasCalculations(fo))
|
||||
currentTasks.add(new CalculateTask(fo));
|
||||
|
||||
GenerateTask generateTask = new GenerateTask(fo);
|
||||
generateTask.originRef = originRef;
|
||||
generateTask.originObject = originObject;
|
||||
|
||||
currentTasks.add(generateTask);
|
||||
|
||||
for (AbstractTask at : localPreTasks)
|
||||
if (!at.isToMerge())
|
||||
if ((at instanceof GenerateTask) && checkDoMerge((GenerateTask) at)) {
|
||||
currentTasks.add(new MergeTask(at, generateTask));
|
||||
} else if (at instanceof GenerateRefTask)
|
||||
currentTasks.add(new MergeTask(at, generateTask));
|
||||
|
||||
currentTasks.addAll(localPostTasks);
|
||||
|
||||
for (AbstractTask at : localPostTasks)
|
||||
if (!at.isToMerge())
|
||||
if ((at instanceof GenerateTask) && checkDoMerge((GenerateTask) at)) {
|
||||
currentTasks.add(new MergeTask(at, generateTask));
|
||||
} else if (at instanceof GenerateRefTask)
|
||||
currentTasks.add(new MergeTask(at, generateTask));
|
||||
|
||||
return currentTasks;
|
||||
}
|
||||
|
||||
protected boolean checkDoMerge(GenerateTask generateTask) {
|
||||
if (generateTask.originRef == null)
|
||||
return true;
|
||||
JsonObject jo = generateTask.originRef.origin;
|
||||
|
||||
if (!jo.has(DIRECTIVE_SKIP_MERGE))
|
||||
return true;
|
||||
|
||||
try {
|
||||
return !jo.get(DIRECTIVE_SKIP_MERGE).getAsBoolean();
|
||||
} catch (Exception ignore) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<AbstractTask> getTasks() {
|
||||
return tasks;
|
||||
}
|
||||
|
||||
public List<AbstractTask> getTasks() {
|
||||
return tasks;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -25,12 +25,14 @@
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.executor.generationmodel;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ru.entaxy.esb.platform.runtime.base.connecting.generator.Generated;
|
||||
import ru.entaxy.esb.platform.runtime.base.extensions.api.EntaxyExtensionsProvider;
|
||||
import ru.entaxy.platform.base.objects.EntaxyObject;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactoryException;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
|
||||
@ -41,79 +43,94 @@ import ru.entaxy.platform.core.producer.executor.support.EntaxyObjectPropertiesH
|
||||
|
||||
public class MergeTask extends AbstractTask {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MergeTask.class);
|
||||
|
||||
protected AbstractTask fromTask;
|
||||
protected AbstractTask toTask;
|
||||
|
||||
public MergeTask(AbstractTask fromTask, AbstractTask toTask) {
|
||||
this.fromTask = fromTask;
|
||||
this.toTask = toTask;
|
||||
this.fromTask.mergeTo(this.toTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "MERGE: " + "\n\t FROM: " + fromTask.getInfo() + "\n\t TO: " + toTask.getInfo();
|
||||
}
|
||||
private static final Logger log = LoggerFactory.getLogger(MergeTask.class);
|
||||
|
||||
protected AbstractTask fromTask;
|
||||
protected AbstractTask toTask;
|
||||
|
||||
public MergeTask(AbstractTask fromTask, AbstractTask toTask) {
|
||||
this.fromTask = fromTask;
|
||||
this.toTask = toTask;
|
||||
this.fromTask.mergeTo(this.toTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "MERGE: " + "\n\t FROM: " + fromTask.getInfo() + "\n\t TO: " + toTask.getInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(ProducerResult currentResult, CommandResult currentCommand,
|
||||
EntaxyProducerService producerService, Map<String, Object> instructions) throws Exception {
|
||||
|
||||
Generated source = this.fromTask.getGeneratedResult();
|
||||
Generated target = this.toTask.getGeneratedResult();
|
||||
|
||||
if ((source != null) && (target != null)) {
|
||||
|
||||
if (!MergeHelper.getInstance().canMerge(source.getType(), target.getType())) {
|
||||
printOutput("CAN'T MERGE " + source.getType() + " TO " + target.getType());
|
||||
log.error("CAN'T MERGE " + source.getType() + " TO " + target.getType());
|
||||
throw new EntaxyFactoryException(
|
||||
"Can not merge [" + source.getType() + "] to [" + target.getType() + "]");
|
||||
}
|
||||
|
||||
EntaxyExtensionsProvider extensionsProvider =
|
||||
currentResult.findResultObject(EntaxyExtensionsProvider.class);
|
||||
if (extensionsProvider == null)
|
||||
this.generatedResult = MergeHelper.getInstance().merge(source, target, Collections.emptyList());
|
||||
else
|
||||
this.generatedResult =
|
||||
MergeHelper.getInstance().merge(source, target, extensionsProvider.getExtensions());
|
||||
|
||||
// merge headers
|
||||
|
||||
// GeneratedHeaders sourceGeneratedHeaders =
|
||||
// GeneratedHeaders.getHeaders(source.getProperties());
|
||||
// GeneratedHeaders targetGeneratedHeaders =
|
||||
// GeneratedHeaders.getHeaders(target.getProperties());
|
||||
|
||||
GeneratedHeaders sourceGeneratedHeaders = GeneratedHeaders.getHeaders(
|
||||
EntaxyObjectPropertiesHelper.getMainObjectProperties(source.getProperties()));
|
||||
GeneratedHeaders targetGeneratedHeaders = GeneratedHeaders.getHeaders(
|
||||
EntaxyObjectPropertiesHelper.getMainObjectProperties(target.getProperties()));
|
||||
|
||||
|
||||
GeneratedHeaders resultGeneratedHeaders = GeneratedHeaders.getHeaders(
|
||||
// this.generatedResult.getProperties()
|
||||
EntaxyObjectPropertiesHelper.getMainObjectProperties(this.generatedResult.getProperties()));
|
||||
|
||||
for (String header : targetGeneratedHeaders.headers.keySet())
|
||||
resultGeneratedHeaders.set(header, targetGeneratedHeaders.headers.get(header));
|
||||
|
||||
for (String header : sourceGeneratedHeaders.headers.keySet())
|
||||
if (EntaxyObject.HEADERS.MAIN_OBJECT.equals(header)
|
||||
|| EntaxyObject.HEADERS.ENTAXY_GENERATED.equals(header))
|
||||
continue;
|
||||
else
|
||||
resultGeneratedHeaders.append(header, sourceGeneratedHeaders.headers.get(header));
|
||||
} else {
|
||||
if (source != null)
|
||||
this.generatedResult = source;
|
||||
else if (target != null)
|
||||
this.generatedResult = target;
|
||||
else
|
||||
// nothing to do
|
||||
return true;
|
||||
}
|
||||
|
||||
this.fromTask.setFinal(false);
|
||||
this.toTask.updateGenerated(generatedResult);
|
||||
|
||||
printOutput("\tMERGE RESULT ::");
|
||||
printOutput(generatedResult.getObject().toString());
|
||||
|
||||
// prevent building result of this task
|
||||
this.generatedResult = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(ProducerResult currentResult, CommandResult currentCommand,
|
||||
EntaxyProducerService producerService, Map<String, Object> instructions) throws Exception {
|
||||
|
||||
Generated source = this.fromTask.getGeneratedResult();
|
||||
Generated target = this.toTask.getGeneratedResult();
|
||||
|
||||
if ( (source!=null) && (target != null)) {
|
||||
|
||||
if (!MergeHelper.getInstance().canMerge(source.getType(), target.getType())) {
|
||||
printOutput("CAN'T MERGE " + source.getType() + " TO " + target.getType());
|
||||
log.error("CAN'T MERGE " + source.getType() + " TO " + target.getType());
|
||||
throw new EntaxyFactoryException("Can not merge [" + source.getType() + "] to [" + target.getType() + "]");
|
||||
}
|
||||
|
||||
this.generatedResult = MergeHelper.getInstance().merge(source, target);
|
||||
|
||||
// merge headers
|
||||
|
||||
GeneratedHeaders sourceGeneratedHeaders = GeneratedHeaders.getHeaders(source.getProperties());
|
||||
GeneratedHeaders targetGeneratedHeaders = GeneratedHeaders.getHeaders(target.getProperties());
|
||||
|
||||
GeneratedHeaders resultGeneratedHeaders = GeneratedHeaders.getHeaders(
|
||||
// this.generatedResult.getProperties()
|
||||
EntaxyObjectPropertiesHelper.getMainObjectProperties(this.generatedResult.getProperties())
|
||||
);
|
||||
|
||||
for (String header: targetGeneratedHeaders.headers.keySet())
|
||||
resultGeneratedHeaders.set(header, targetGeneratedHeaders.headers.get(header));
|
||||
|
||||
for (String header: sourceGeneratedHeaders.headers.keySet())
|
||||
if (EntaxyObject.HEADERS.MAIN_OBJECT.equals(header) || EntaxyObject.HEADERS.ENTAXY_GENERATED.equals(header))
|
||||
continue;
|
||||
else
|
||||
resultGeneratedHeaders.append(header, sourceGeneratedHeaders.headers.get(header));
|
||||
} else {
|
||||
if (source != null)
|
||||
this.generatedResult = source;
|
||||
else if (target != null)
|
||||
this.generatedResult = target;
|
||||
else
|
||||
// nothing to do
|
||||
return true;
|
||||
}
|
||||
|
||||
this.fromTask.setFinal(false);
|
||||
this.toTask.updateGenerated(generatedResult);
|
||||
|
||||
printOutput("\tMERGE RESULT ::");
|
||||
printOutput(generatedResult.getObject().toString());
|
||||
|
||||
// prevent building result of this task
|
||||
this.generatedResult = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -40,74 +40,80 @@ import ru.entaxy.platform.core.producer.executor.objectmodel.FactoredObjectRef;
|
||||
|
||||
public class ResolveRefTask extends AbstractRefTask {
|
||||
|
||||
protected ResolveRefTask(FactoredObjectRef objectRef) {
|
||||
super(objectRef);
|
||||
}
|
||||
protected ResolveRefTask(FactoredObjectRef objectRef) {
|
||||
super(objectRef);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "RESOLVE-REF "
|
||||
+ "["
|
||||
+ objectRef.definedIn.getObjectId()
|
||||
+ "] -> "
|
||||
+ "["
|
||||
+ objectRef.getTargetId()
|
||||
+ "]";
|
||||
// + objectRef.factoryId;
|
||||
}
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "RESOLVE-REF "
|
||||
+ "["
|
||||
+ objectRef.definedIn.getObjectId()
|
||||
+ "] -> "
|
||||
+ "["
|
||||
+ objectRef.getTargetId()
|
||||
+ "]";
|
||||
// + objectRef.factoryId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(ProducerResult currentResult, CommandResult currentCommand,
|
||||
EntaxyProducerService producerService, Map<String, Object> instructions) throws Exception {
|
||||
GenerationModel generationModel = currentResult.findResultObject(GenerationModel.class);
|
||||
String fieldName = objectRef.getOrDefault(FIELDS.REF_FIELD, FIELDS.OBJECT_ID).toString();
|
||||
printOutput("RESOLVING REF TO FIELD [" + fieldName + "]");
|
||||
List<AbstractTask> generateTasks = generationModel.tasks.stream()
|
||||
.filter(t->(t instanceof GenerateTask))
|
||||
.map(t->(GenerateTask)t)
|
||||
.filter(t->t.origin==objectRef.getTargetObject())
|
||||
.collect(Collectors.toList());
|
||||
if (generateTasks.size() == 0)
|
||||
generateTasks = generationModel.tasks.stream()
|
||||
.filter(t->(t instanceof ResolveObjectTask))
|
||||
.map(t->(ResolveObjectTask)t)
|
||||
.filter(t->t.origin==objectRef.getTargetObject())
|
||||
.collect(Collectors.toList());
|
||||
if (generateTasks.size() == 0) {
|
||||
printOutput("None of GenerateTask or ResolveObjectTask found for [" + objectRef.getTargetId() + "/" + objectRef.getTargetObject().getObjectType() + "]");
|
||||
return false;
|
||||
}
|
||||
AbstractTask provider = generateTasks.get(0);
|
||||
Object value = null;
|
||||
if (provider instanceof GenerateTask) {
|
||||
GenerateTask generateTask = (GenerateTask)provider;
|
||||
if (GenerateTask.CONTENT_FIELD.equals(fieldName)) {
|
||||
Object val = generateTask.getGeneratedResult().getObject();
|
||||
if (val != null)
|
||||
value = val.toString();
|
||||
else
|
||||
value = "";
|
||||
} else {
|
||||
value = generateTask.generationProperties.getOrDefault(fieldName, "");
|
||||
}
|
||||
} else if (provider instanceof ResolveObjectTask) {
|
||||
ResolveObjectTask task = (ResolveObjectTask)provider;
|
||||
value = ObjectResolveHelper.getInstance().resolve(task.targetObject, fieldName);
|
||||
if (value == null)
|
||||
value = "";
|
||||
}
|
||||
printOutput("RESOLVED REF TO FIELD [" + fieldName + "] to VALUE [" + value.toString() + "]");
|
||||
printOutput("REPLACE: [" + objectRef.origin.toString() + "] in PATH ["
|
||||
+ objectRef.relativePath + "] in OBJECT "
|
||||
+ objectRef.definedIn.origin.toString() );
|
||||
JSONUtils.replaceValue(objectRef.definedIn.origin, objectRef.relativePath, (new Gson()).toJsonTree(value));
|
||||
printOutput("AFTER REPLACEMENT: [" + objectRef.definedIn.origin.toString() + "]");
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean execute(ProducerResult currentResult, CommandResult currentCommand,
|
||||
EntaxyProducerService producerService, Map<String, Object> instructions) throws Exception {
|
||||
GenerationModel generationModel = currentResult.findResultObject(GenerationModel.class);
|
||||
String fieldName = objectRef.getOrDefault(FIELDS.REF_FIELD, FIELDS.OBJECT_ID).toString();
|
||||
printOutput("RESOLVING REF TO FIELD [" + fieldName + "]");
|
||||
List<AbstractTask> generateTasks = generationModel.tasks.stream()
|
||||
.filter(t -> (t instanceof GenerateTask))
|
||||
.map(t -> (GenerateTask) t)
|
||||
.filter(t -> t.origin == objectRef.getTargetObject())
|
||||
.collect(Collectors.toList());
|
||||
if (generateTasks.size() == 0)
|
||||
generateTasks = generationModel.tasks.stream()
|
||||
.filter(t -> (t instanceof ResolveObjectTask))
|
||||
.map(t -> (ResolveObjectTask) t)
|
||||
.filter(t -> t.origin == objectRef.getTargetObject())
|
||||
.collect(Collectors.toList());
|
||||
if (generateTasks.size() == 0) {
|
||||
printOutput("None of GenerateTask or ResolveObjectTask found for [" + objectRef.getTargetId() + "/"
|
||||
+ objectRef.getTargetObject().getObjectType() + "]");
|
||||
return false;
|
||||
}
|
||||
AbstractTask provider = generateTasks.get(0);
|
||||
Object value = null;
|
||||
if (provider instanceof GenerateTask) {
|
||||
GenerateTask generateTask = (GenerateTask) provider;
|
||||
if (GenerateTask.CONTENT_FIELD.equals(fieldName)) {
|
||||
Object val = generateTask.getGeneratedResult().getObject();
|
||||
if (val != null)
|
||||
value = val.toString();
|
||||
else
|
||||
value = "";
|
||||
} else {
|
||||
value = generateTask.generationProperties.getOrDefault(fieldName, null);
|
||||
if (value == null)
|
||||
value = generateTask.getGeneratedResult().getProperties().getOrDefault(fieldName, "");
|
||||
}
|
||||
} else if (provider instanceof ResolveObjectTask) {
|
||||
ResolveObjectTask task = (ResolveObjectTask) provider;
|
||||
value = ObjectResolveHelper.getInstance().resolve(task.targetObject, fieldName);
|
||||
if (value == null)
|
||||
value = "";
|
||||
}
|
||||
printOutput("RESOLVED REF TO FIELD [" + fieldName + "] to VALUE [" + value.toString() + "]");
|
||||
printOutput("REPLACE: [" + objectRef.origin.toString() + "] in PATH ["
|
||||
+ objectRef.relativePath + "] in OBJECT "
|
||||
+ objectRef.definedIn.origin.toString());
|
||||
JSONUtils.setValue(objectRef.definedIn.origin,
|
||||
GenerationModel.UNRESOLVED_CONTAINER_NAME + "." + objectRef.relativePath, objectRef.origin, false,
|
||||
true);
|
||||
JSONUtils.replaceValue(objectRef.definedIn.origin, objectRef.relativePath, (new Gson()).toJsonTree(value));
|
||||
printOutput("AFTER REPLACEMENT: [" + objectRef.definedIn.origin.toString() + "]");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -25,18 +25,22 @@
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.executor.generationmodel.merge;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import ru.entaxy.esb.platform.runtime.base.extensions.api.EntaxyExtension;
|
||||
import ru.entaxy.esb.platform.runtime.base.extensions.api.EntaxyExtensionsAware;
|
||||
import ru.entaxy.platform.core.producer.executor.generationmodel.merge.MergingMap.Mapping;
|
||||
|
||||
public abstract class AbstractMergeProcessor implements MergeProcessor {
|
||||
public abstract class AbstractMergeProcessor implements MergeProcessor, EntaxyExtensionsAware {
|
||||
|
||||
protected Map<String, List<String>> mapping;
|
||||
|
||||
|
||||
protected List<EntaxyExtension> entaxyExtensions = new ArrayList<>();
|
||||
|
||||
protected AbstractMergeProcessor() {
|
||||
super();
|
||||
mapping = new HashMap<>();
|
||||
@ -59,4 +63,14 @@ public abstract class AbstractMergeProcessor implements MergeProcessor {
|
||||
return mapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtension(EntaxyExtension entaxyExtension) {
|
||||
if (!entaxyExtensions.contains(entaxyExtension))
|
||||
entaxyExtensions.add(entaxyExtension);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeExtension(EntaxyExtension entaxyExtension) {
|
||||
entaxyExtensions.remove(entaxyExtension);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -25,6 +25,7 @@
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.executor.generationmodel.merge;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -39,6 +40,8 @@ import org.osgi.service.component.annotations.ReferencePolicy;
|
||||
import org.osgi.service.component.annotations.ReferencePolicyOption;
|
||||
|
||||
import ru.entaxy.esb.platform.runtime.base.connecting.generator.Generated;
|
||||
import ru.entaxy.esb.platform.runtime.base.extensions.api.EntaxyExtension;
|
||||
import ru.entaxy.esb.platform.runtime.base.extensions.api.EntaxyExtensionsAware;
|
||||
|
||||
@Component(service = MergeHelper.class, immediate = true)
|
||||
public class MergeHelper {
|
||||
@ -57,6 +60,8 @@ public class MergeHelper {
|
||||
}
|
||||
}
|
||||
|
||||
protected final List<EntaxyExtension> extensions = new ArrayList<>();
|
||||
|
||||
protected Map<MergeProcessor, MergeProcessorWrapper> wrappersMap = new HashMap<>();
|
||||
|
||||
protected Map<String, Map<String, MergeProcessorWrapper>> processors = new HashMap<>();
|
||||
@ -104,9 +109,12 @@ public class MergeHelper {
|
||||
&& processors.get(source).get(target).mergeProcessor != null;
|
||||
}
|
||||
|
||||
public Generated merge(Generated source, Generated target) {
|
||||
public Generated merge(Generated source, Generated target, List<EntaxyExtension> extensions) {
|
||||
if (!canMerge(source.getType(), target.getType()))
|
||||
return null;
|
||||
return processors.get(source.getType()).get(target.getType()).mergeProcessor.merge(source, target);
|
||||
MergeProcessor processor = processors.get(source.getType()).get(target.getType()).mergeProcessor;
|
||||
if (processor instanceof EntaxyExtensionsAware)
|
||||
((EntaxyExtensionsAware)processor).addExtensions(extensions);
|
||||
return processor.merge(source, target);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -36,284 +36,317 @@ import ru.entaxy.platform.base.objects.EntaxyObject.FIELDS;
|
||||
|
||||
public class FactoredObjectRef extends AbstractFactored {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(FactoredObjectRef.class);
|
||||
|
||||
public static String IS_EXTERNAL_FIELD = "isExternal";
|
||||
public static String TARGET_ID_FIELD = "targetId";
|
||||
public static String TARGET_UUID_FIELD = "targetUuid";
|
||||
public static String TARGET_TYPE_FIELD = "targetType";
|
||||
public static String TARGET_VALUE_FIELD = "targetValue";
|
||||
public static String IS_RESOLVED_FIELD = "isResolved";
|
||||
public static String RESOLVE_ALWAYS_FIELD = "resolveAlways";
|
||||
public static String IS_LINK = "isLink";
|
||||
public static String IS_DEFINITION_ORIGIN = "isDefinitionOrigin";
|
||||
private static final Logger log = LoggerFactory.getLogger(FactoredObjectRef.class);
|
||||
|
||||
protected FactoredObject targetObject = null;
|
||||
|
||||
protected String targetId = "";
|
||||
protected String targetUuid = "";
|
||||
protected String targetType = "";
|
||||
|
||||
protected boolean isExternal = true;
|
||||
protected boolean isResolved = true;
|
||||
protected boolean isBackRef = false;
|
||||
protected boolean refByValueOnly = false;
|
||||
protected boolean isLink = false;
|
||||
protected boolean resolveAlways = false;
|
||||
protected boolean isDefinitionOrigin = false;
|
||||
|
||||
public FactoredObjectRef (ObjectModel objectModel) {
|
||||
super(objectModel);
|
||||
this.origin = new JsonObject();
|
||||
this.origin.addProperty(FIELDS.IS_REF, true);
|
||||
this.origin.addProperty(IS_EXTERNAL_FIELD, false);
|
||||
this.origin.addProperty(TARGET_ID_FIELD, getTargetId());
|
||||
this.origin.addProperty(TARGET_UUID_FIELD, getTargetUuid());
|
||||
this.origin.addProperty(TARGET_TYPE_FIELD, getTargetType());
|
||||
this.origin.addProperty(FIELDS.FACTORY_ID, this.factoryId);
|
||||
this.origin.addProperty(FIELDS.SCOPE, this.scope);
|
||||
this.origin.addProperty(IS_RESOLVED_FIELD, this.isResolved);
|
||||
this.origin.addProperty(RESOLVE_ALWAYS_FIELD, this.resolveAlways);
|
||||
this.origin.addProperty(FIELDS.IS_BACK_REF, this.isBackRef);
|
||||
this.origin.addProperty(IS_LINK, false);
|
||||
}
|
||||
|
||||
public FactoredObjectRef (ObjectModel objectModel, FactoredObject targetObject) {
|
||||
super(objectModel);
|
||||
this.origin = new JsonObject();
|
||||
|
||||
this.setTargetObject(targetObject);
|
||||
this.definedIn = targetObject.definedIn;
|
||||
this.scope = targetObject.scope;
|
||||
this.factoryId = targetObject.factoryId;
|
||||
this.jsonPath = targetObject.jsonPath;
|
||||
this.relativePath = targetObject.relativePath;
|
||||
this.isExternal = false;
|
||||
|
||||
this.isLink = false;
|
||||
|
||||
this.origin.addProperty(FIELDS.IS_REF, true);
|
||||
this.origin.addProperty(IS_EXTERNAL_FIELD, false);
|
||||
this.origin.addProperty(TARGET_ID_FIELD, getTargetId());
|
||||
this.origin.addProperty(TARGET_UUID_FIELD, getTargetUuid());
|
||||
this.origin.addProperty(TARGET_TYPE_FIELD, getTargetType());
|
||||
this.origin.addProperty(FIELDS.FACTORY_ID, this.factoryId);
|
||||
this.origin.addProperty(FIELDS.SCOPE, this.scope);
|
||||
this.origin.addProperty(IS_RESOLVED_FIELD, this.isResolved);
|
||||
this.origin.addProperty(RESOLVE_ALWAYS_FIELD, this.resolveAlways);
|
||||
this.origin.addProperty(FIELDS.IS_BACK_REF, this.isBackRef);
|
||||
|
||||
this.origin.addProperty(IS_LINK, this.isLink);
|
||||
|
||||
objectModel.addRef(this);
|
||||
}
|
||||
|
||||
public static boolean isRef(JsonObject jsonObject) {
|
||||
try {
|
||||
|
||||
// if object has 'targetId' we assume it as a ref
|
||||
// even if there's no 'isRef'
|
||||
if (jsonObject.has(TARGET_ID_FIELD))
|
||||
if (!jsonObject.has(FIELDS.IS_REF))
|
||||
jsonObject.addProperty(FIELDS.IS_REF, true);
|
||||
|
||||
if (!jsonObject.has(TARGET_ID_FIELD) && !AbstractFactored.isFactored(jsonObject))
|
||||
return false;
|
||||
if (!jsonObject.has(FIELDS.IS_REF))
|
||||
return false;
|
||||
boolean isRef = jsonObject.get(FIELDS.IS_REF).getAsBoolean();
|
||||
return isRef;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wrap(JsonObject object, Map<String, Object> context, String path) {
|
||||
super.wrap(object, context, path);
|
||||
public static final String DIRECTIVE_AUTO_CREATED = "@AUTOCREATED";
|
||||
public static final String DIRECTIVE_REF_CONFIG = "@REF_CONFIG";
|
||||
|
||||
updateFromObject(object);
|
||||
|
||||
AbstractFactored contextOwner = getContextOwner(context);
|
||||
if ((contextOwner != null) && (contextOwner instanceof FactoredObject)) {
|
||||
FactoredObject fo = (FactoredObject)contextOwner;
|
||||
log.debug("\t IN CONTEXT :: " + fo.factoryId + "[" + fo.jsonPath + "]");
|
||||
computeRelativePath(fo.jsonPath);
|
||||
if (null == this.ownScope || this.ownScope.isEmpty())
|
||||
this.scope = fo.scope;
|
||||
this.definedIn = fo;
|
||||
}
|
||||
|
||||
|
||||
objectModel.addRef(this);
|
||||
}
|
||||
public static final String DIRECTIVE_SOFT_UPDATE = "@SOFT_UPDATE";
|
||||
|
||||
@Override
|
||||
public void updateFromOrigin() {
|
||||
super.updateFromOrigin();
|
||||
updateFromObject(origin);
|
||||
}
|
||||
public static String IS_EXTERNAL_FIELD = "isExternal";
|
||||
public static String TARGET_ID_FIELD = "targetId";
|
||||
public static String TARGET_UUID_FIELD = "targetUuid";
|
||||
public static String TARGET_TYPE_FIELD = "targetType";
|
||||
public static String TARGET_VALUE_FIELD = "targetValue";
|
||||
public static String IS_RESOLVED_FIELD = "isResolved";
|
||||
public static String RESOLVE_ALWAYS_FIELD = "resolveAlways";
|
||||
public static String IS_LINK = "isLink";
|
||||
public static String IS_DEFINITION_ORIGIN = "isDefinitionOrigin";
|
||||
|
||||
protected void updateFromObject(JsonObject object) {
|
||||
if (object.has(TARGET_ID_FIELD))
|
||||
this.targetId = object.get(TARGET_ID_FIELD).getAsString();
|
||||
protected FactoredObject targetObject = null;
|
||||
|
||||
if (object.has(TARGET_UUID_FIELD))
|
||||
this.targetUuid = object.get(TARGET_UUID_FIELD).getAsString();
|
||||
/*
|
||||
if (object.has(TARGET_VALUE_FIELD))
|
||||
this.targetValue = object.get(TARGET_VALUE_FIELD).getAsString();
|
||||
*/
|
||||
if (object.has(TARGET_TYPE_FIELD))
|
||||
this.targetType = object.get(TARGET_TYPE_FIELD).getAsString();
|
||||
protected String targetId = "";
|
||||
protected String targetUuid = "";
|
||||
protected String targetType = "";
|
||||
|
||||
if (object.has(IS_EXTERNAL_FIELD))
|
||||
try{
|
||||
this.isExternal = object.get(IS_EXTERNAL_FIELD).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
protected boolean isExternal = true;
|
||||
protected boolean isResolved = true;
|
||||
protected boolean isBackRef = false;
|
||||
protected boolean refByValueOnly = false;
|
||||
protected boolean isLink = false;
|
||||
protected boolean resolveAlways = false;
|
||||
protected boolean isDefinitionOrigin = false;
|
||||
|
||||
if (object.has(IS_RESOLVED_FIELD))
|
||||
try{
|
||||
this.isResolved = object.get(IS_RESOLVED_FIELD).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
public FactoredObjectRef(ObjectModel objectModel) {
|
||||
super(objectModel);
|
||||
this.origin = new JsonObject();
|
||||
this.origin.addProperty(FIELDS.IS_REF, true);
|
||||
this.origin.addProperty(IS_EXTERNAL_FIELD, false);
|
||||
this.origin.addProperty(TARGET_ID_FIELD, getTargetId());
|
||||
this.origin.addProperty(TARGET_UUID_FIELD, getTargetUuid());
|
||||
this.origin.addProperty(TARGET_TYPE_FIELD, getTargetType());
|
||||
this.origin.addProperty(FIELDS.FACTORY_ID, this.factoryId);
|
||||
this.origin.addProperty(FIELDS.SCOPE, this.scope);
|
||||
this.origin.addProperty(IS_RESOLVED_FIELD, this.isResolved);
|
||||
this.origin.addProperty(RESOLVE_ALWAYS_FIELD, this.resolveAlways);
|
||||
this.origin.addProperty(FIELDS.IS_BACK_REF, this.isBackRef);
|
||||
this.origin.addProperty(IS_LINK, false);
|
||||
}
|
||||
|
||||
if (object.has(RESOLVE_ALWAYS_FIELD))
|
||||
try{
|
||||
this.resolveAlways = object.get(RESOLVE_ALWAYS_FIELD).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
public FactoredObjectRef(ObjectModel objectModel, FactoredObject targetObject) {
|
||||
super(objectModel);
|
||||
this.origin = new JsonObject();
|
||||
|
||||
if (object.has(IS_DEFINITION_ORIGIN))
|
||||
try{
|
||||
this.isDefinitionOrigin = object.get(IS_DEFINITION_ORIGIN).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
this.setTargetObject(targetObject);
|
||||
this.definedIn = targetObject.definedIn;
|
||||
this.scope = targetObject.scope;
|
||||
this.factoryId = targetObject.factoryId;
|
||||
this.jsonPath = targetObject.jsonPath;
|
||||
this.relativePath = targetObject.relativePath;
|
||||
this.isExternal = false;
|
||||
|
||||
if (object.has(FIELDS.IS_BACK_REF))
|
||||
try{
|
||||
this.isBackRef = object.get(FIELDS.IS_BACK_REF).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
this.isLink = false;
|
||||
|
||||
if (object.has(IS_LINK))
|
||||
try{
|
||||
this.isLink = object.get(IS_LINK).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (object.has(FIELDS.IS_REF_BY_VALUE_ONLY))
|
||||
try{
|
||||
this.refByValueOnly = object.get(FIELDS.IS_REF_BY_VALUE_ONLY).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public boolean isBackRef() {
|
||||
return isBackRef;
|
||||
}
|
||||
this.origin.addProperty(FIELDS.IS_REF, true);
|
||||
this.origin.addProperty(IS_EXTERNAL_FIELD, false);
|
||||
this.origin.addProperty(TARGET_ID_FIELD, getTargetId());
|
||||
this.origin.addProperty(TARGET_UUID_FIELD, getTargetUuid());
|
||||
this.origin.addProperty(TARGET_TYPE_FIELD, getTargetType());
|
||||
this.origin.addProperty(FIELDS.FACTORY_ID, this.factoryId);
|
||||
this.origin.addProperty(FIELDS.SCOPE, this.scope);
|
||||
this.origin.addProperty(IS_RESOLVED_FIELD, this.isResolved);
|
||||
this.origin.addProperty(RESOLVE_ALWAYS_FIELD, this.resolveAlways);
|
||||
this.origin.addProperty(FIELDS.IS_BACK_REF, this.isBackRef);
|
||||
|
||||
public boolean isExternal() {
|
||||
return isExternal;
|
||||
}
|
||||
this.origin.addProperty(IS_LINK, this.isLink);
|
||||
|
||||
public boolean isResolved() {
|
||||
return isResolved;
|
||||
}
|
||||
objectModel.addRef(this);
|
||||
}
|
||||
|
||||
public void setResolved(boolean isResolved) {
|
||||
this.isResolved = isResolved;
|
||||
this.origin.remove(IS_RESOLVED_FIELD);
|
||||
this.origin.addProperty(IS_RESOLVED_FIELD, this.isResolved);
|
||||
}
|
||||
public static boolean isRef(JsonObject jsonObject) {
|
||||
try {
|
||||
|
||||
public boolean isResolveAlways() {
|
||||
return resolveAlways;
|
||||
}
|
||||
// if object has 'targetId' we assume it as a ref
|
||||
// even if there's no 'isRef'
|
||||
if (jsonObject.has(TARGET_ID_FIELD))
|
||||
if (!jsonObject.has(FIELDS.IS_REF))
|
||||
jsonObject.addProperty(FIELDS.IS_REF, true);
|
||||
|
||||
public void setResolveAlways(boolean resolveAlways) {
|
||||
this.resolveAlways = resolveAlways;
|
||||
}
|
||||
if (!jsonObject.has(TARGET_ID_FIELD) && !AbstractFactored.isFactored(jsonObject))
|
||||
return false;
|
||||
if (!jsonObject.has(FIELDS.IS_REF))
|
||||
return false;
|
||||
boolean isRef = jsonObject.get(FIELDS.IS_REF).getAsBoolean();
|
||||
return isRef;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setBackRef(boolean isBaskRef) {
|
||||
this.isBackRef = isBaskRef;
|
||||
this.origin.remove(FIELDS.IS_BACK_REF);
|
||||
this.origin.addProperty(FIELDS.IS_BACK_REF, this.isBackRef);
|
||||
}
|
||||
@Override
|
||||
public void wrap(JsonObject object, Map<String, Object> context, String path) {
|
||||
super.wrap(object, context, path);
|
||||
|
||||
public void setExternal(boolean isExternal) {
|
||||
this.isExternal = isExternal;
|
||||
this.origin.remove(IS_EXTERNAL_FIELD);
|
||||
this.origin.addProperty(IS_EXTERNAL_FIELD, this.isExternal);
|
||||
}
|
||||
updateFromObject(object);
|
||||
|
||||
public void setLink(boolean isLink) {
|
||||
this.isLink = isLink;
|
||||
this.origin.remove(IS_LINK);
|
||||
this.origin.addProperty(IS_LINK, this.isLink);
|
||||
}
|
||||
|
||||
public boolean isLink() {
|
||||
return isLink;
|
||||
}
|
||||
AbstractFactored contextOwner = getContextOwner(context);
|
||||
if ((contextOwner != null) && (contextOwner instanceof FactoredObject)) {
|
||||
FactoredObject fo = (FactoredObject) contextOwner;
|
||||
log.debug("\t IN CONTEXT :: " + fo.factoryId + "[" + fo.jsonPath + "]");
|
||||
computeRelativePath(fo.jsonPath);
|
||||
if (null == this.ownScope || this.ownScope.isEmpty())
|
||||
this.scope = fo.scope;
|
||||
this.definedIn = fo;
|
||||
}
|
||||
|
||||
public boolean isDefinitionOrigin() {
|
||||
return isDefinitionOrigin;
|
||||
}
|
||||
|
||||
public void setDefinitionOrigin(boolean isDefinitionOrigin) {
|
||||
this.isDefinitionOrigin = isDefinitionOrigin;
|
||||
}
|
||||
objectModel.addRef(this);
|
||||
}
|
||||
|
||||
public boolean isRefByValueOnly() {
|
||||
return refByValueOnly;
|
||||
}
|
||||
public boolean isAutoGenerated() {
|
||||
return this.origin.has(DIRECTIVE_AUTO_CREATED);
|
||||
}
|
||||
|
||||
public void setRefByValueOnly(boolean isRefByValueOnly) {
|
||||
this.refByValueOnly = isRefByValueOnly;
|
||||
}
|
||||
public void setAutoGenerated(boolean value) {
|
||||
this.origin.remove(DIRECTIVE_AUTO_CREATED);
|
||||
if (value)
|
||||
this.origin.addProperty(DIRECTIVE_AUTO_CREATED, true);
|
||||
}
|
||||
|
||||
public String getTargetId() {
|
||||
if (targetObject == null)
|
||||
return targetId;
|
||||
return targetObject.getObjectId();
|
||||
}
|
||||
@Override
|
||||
public void updateFromOrigin() {
|
||||
super.updateFromOrigin();
|
||||
updateFromObject(origin);
|
||||
}
|
||||
|
||||
public String getTargetUuid() {
|
||||
return targetUuid;
|
||||
}
|
||||
|
||||
public String getTargetType() {
|
||||
if (targetObject == null)
|
||||
return targetType;
|
||||
return targetObject.getObjectType();
|
||||
}
|
||||
protected void updateFromObject(JsonObject object) {
|
||||
if (object.has(TARGET_ID_FIELD))
|
||||
this.targetId = object.get(TARGET_ID_FIELD).getAsString();
|
||||
|
||||
public FactoredObject getTargetObject() {
|
||||
return targetObject;
|
||||
}
|
||||
if (object.has(TARGET_UUID_FIELD))
|
||||
this.targetUuid = object.get(TARGET_UUID_FIELD).getAsString();
|
||||
/*
|
||||
* if (object.has(TARGET_VALUE_FIELD)) this.targetValue =
|
||||
* object.get(TARGET_VALUE_FIELD).getAsString();
|
||||
*/
|
||||
if (object.has(TARGET_TYPE_FIELD))
|
||||
this.targetType = object.get(TARGET_TYPE_FIELD).getAsString();
|
||||
|
||||
if (object.has(IS_EXTERNAL_FIELD))
|
||||
try {
|
||||
this.isExternal = object.get(IS_EXTERNAL_FIELD).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
if (object.has(IS_RESOLVED_FIELD))
|
||||
try {
|
||||
this.isResolved = object.get(IS_RESOLVED_FIELD).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
if (object.has(RESOLVE_ALWAYS_FIELD))
|
||||
try {
|
||||
this.resolveAlways = object.get(RESOLVE_ALWAYS_FIELD).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
if (object.has(IS_DEFINITION_ORIGIN))
|
||||
try {
|
||||
this.isDefinitionOrigin = object.get(IS_DEFINITION_ORIGIN).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
if (object.has(FIELDS.IS_BACK_REF))
|
||||
try {
|
||||
this.isBackRef = object.get(FIELDS.IS_BACK_REF).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
if (object.has(IS_LINK))
|
||||
try {
|
||||
this.isLink = object.get(IS_LINK).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (object.has(FIELDS.IS_REF_BY_VALUE_ONLY))
|
||||
try {
|
||||
this.refByValueOnly = object.get(FIELDS.IS_REF_BY_VALUE_ONLY).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public boolean isBackRef() {
|
||||
return isBackRef;
|
||||
}
|
||||
|
||||
public boolean isExternal() {
|
||||
return isExternal;
|
||||
}
|
||||
|
||||
public boolean isResolved() {
|
||||
return isResolved;
|
||||
}
|
||||
|
||||
public void setResolved(boolean isResolved) {
|
||||
this.isResolved = isResolved;
|
||||
this.origin.remove(IS_RESOLVED_FIELD);
|
||||
this.origin.addProperty(IS_RESOLVED_FIELD, this.isResolved);
|
||||
}
|
||||
|
||||
public boolean isResolveAlways() {
|
||||
return resolveAlways;
|
||||
}
|
||||
|
||||
public void setResolveAlways(boolean resolveAlways) {
|
||||
this.resolveAlways = resolveAlways;
|
||||
}
|
||||
|
||||
public void setBackRef(boolean isBaskRef) {
|
||||
this.isBackRef = isBaskRef;
|
||||
this.origin.remove(FIELDS.IS_BACK_REF);
|
||||
this.origin.addProperty(FIELDS.IS_BACK_REF, this.isBackRef);
|
||||
}
|
||||
|
||||
public void setExternal(boolean isExternal) {
|
||||
this.isExternal = isExternal;
|
||||
this.origin.remove(IS_EXTERNAL_FIELD);
|
||||
this.origin.addProperty(IS_EXTERNAL_FIELD, this.isExternal);
|
||||
}
|
||||
|
||||
public void setLink(boolean isLink) {
|
||||
this.isLink = isLink;
|
||||
this.origin.remove(IS_LINK);
|
||||
this.origin.addProperty(IS_LINK, this.isLink);
|
||||
}
|
||||
|
||||
public boolean isLink() {
|
||||
return isLink;
|
||||
}
|
||||
|
||||
public boolean isDefinitionOrigin() {
|
||||
return isDefinitionOrigin;
|
||||
}
|
||||
|
||||
public void setDefinitionOrigin(boolean isDefinitionOrigin) {
|
||||
this.isDefinitionOrigin = isDefinitionOrigin;
|
||||
}
|
||||
|
||||
public boolean isRefByValueOnly() {
|
||||
return refByValueOnly;
|
||||
}
|
||||
|
||||
public void setRefByValueOnly(boolean isRefByValueOnly) {
|
||||
this.refByValueOnly = isRefByValueOnly;
|
||||
}
|
||||
|
||||
public String getTargetId() {
|
||||
if (targetObject == null)
|
||||
return targetId;
|
||||
return targetObject.getObjectId();
|
||||
}
|
||||
|
||||
public String getTargetUuid() {
|
||||
return targetUuid;
|
||||
}
|
||||
|
||||
public String getTargetType() {
|
||||
if (targetObject == null)
|
||||
return targetType;
|
||||
return targetObject.getObjectType();
|
||||
}
|
||||
|
||||
public void setTargetType(String value) {
|
||||
this.targetType = value;
|
||||
this.origin.remove(TARGET_TYPE_FIELD);
|
||||
this.origin.addProperty(TARGET_TYPE_FIELD, value);
|
||||
}
|
||||
|
||||
public void refeshTargetType() {
|
||||
if (targetObject != null)
|
||||
setTargetType(targetObject.getObjectType());
|
||||
}
|
||||
|
||||
public FactoredObject getTargetObject() {
|
||||
return targetObject;
|
||||
}
|
||||
|
||||
public void setTargetObject(FactoredObject targetObject) {
|
||||
if (this.targetObject != null)
|
||||
this.targetObject.references.remove(this);
|
||||
this.targetObject = targetObject;
|
||||
this.targetUuid = this.targetObject.getUuid();
|
||||
this.targetObject.references.add(this);
|
||||
if (this.origin == null)
|
||||
log.debug("ORIGIN IS NULL!!!");
|
||||
this.origin.remove(TARGET_ID_FIELD);
|
||||
this.origin.addProperty(TARGET_ID_FIELD, getTargetId());
|
||||
|
||||
if (!(targetObject instanceof FactoredObjectProxy)) {
|
||||
this.targetType = targetObject.getObjectType();
|
||||
this.origin.remove(TARGET_TYPE_FIELD);
|
||||
this.origin.addProperty(TARGET_TYPE_FIELD, getTargetType());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setTargetObject(FactoredObject targetObject) {
|
||||
if (this.targetObject != null)
|
||||
this.targetObject.references.remove(this);
|
||||
this.targetObject = targetObject;
|
||||
this.targetUuid = this.targetObject.getUuid();
|
||||
this.targetObject.references.add(this);
|
||||
if (this.origin == null)
|
||||
log.debug("ORIGIN IS NULL!!!");
|
||||
this.origin.remove(TARGET_ID_FIELD);
|
||||
this.origin.addProperty(TARGET_ID_FIELD, getTargetId());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -45,131 +45,156 @@ import ru.entaxy.platform.base.support.JSONUtils.JsonTraverse;
|
||||
|
||||
public class ObjectModel {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ObjectModel.class);
|
||||
|
||||
public List<FactoredObject> objects = new ArrayList<>();
|
||||
|
||||
public List<FactoredObjectRef> refs = new ArrayList<>();
|
||||
|
||||
protected Object rootObject = null;
|
||||
protected JsonObject jsonCurrent = null;
|
||||
protected JsonObject jsonOrigin = null;
|
||||
|
||||
protected boolean isDirty = false;
|
||||
protected boolean isTracked = false;
|
||||
|
||||
public void addObject(FactoredObject factoredObject) {
|
||||
this.objects.add(factoredObject);
|
||||
}
|
||||
|
||||
public void addRef(FactoredObjectRef factoredObjectRef) {
|
||||
this.refs.add(factoredObjectRef);
|
||||
}
|
||||
|
||||
public Object load(JsonElement root) {
|
||||
|
||||
if (!root.isJsonObject()) {
|
||||
log.debug("NOT AN OBJECT!!");
|
||||
return null;
|
||||
}
|
||||
|
||||
jsonCurrent = root.getAsJsonObject();
|
||||
jsonOrigin = jsonCurrent.deepCopy();
|
||||
|
||||
JsonTraverse jsonTraverse = (new JsonTraverse()).checker(new FactoryChecker(this));
|
||||
|
||||
rootObject = jsonTraverse.traverse(jsonCurrent);
|
||||
return rootObject;
|
||||
}
|
||||
|
||||
public void checkRefs() {
|
||||
List<FactoredObjectRef> originRefs = this.refs.stream()
|
||||
.filter(r -> (r.getTargetObject()==null))
|
||||
.collect(Collectors.toList());
|
||||
for (FactoredObjectRef ref: originRefs) {
|
||||
String targetId = ref.getTargetId();
|
||||
String targetUuid = ref.getTargetUuid();
|
||||
List<FactoredObject> fos = this.objects.stream()
|
||||
.filter(fo -> (fo.getObjectId().equals(targetId)) || fo.getUuid().equals(targetUuid))
|
||||
.collect(Collectors.toList());
|
||||
if (fos.isEmpty()) {
|
||||
|
||||
// System.out.println("CREATING PROXY FOR [" + targetId + "]");
|
||||
|
||||
// create proxy
|
||||
FactoredObjectProxy proxy = new FactoredObjectProxy(this);
|
||||
proxy.wrap(FactoredObjectProxy.getDefaultOrigin(), new HashMap<>(), "");
|
||||
proxy.setObjectId(ref.getTargetId());
|
||||
proxy.setObjectType(ref.getTargetType());
|
||||
|
||||
// update ref
|
||||
ref.setExternal(true);
|
||||
ref.setTargetObject(proxy);
|
||||
|
||||
} else {
|
||||
|
||||
// update objectType for proxy
|
||||
if (fos.get(0) instanceof FactoredObjectProxy) {
|
||||
if (!CommonUtils.isValid(fos.get(0).getObjectType()))
|
||||
fos.get(0).setObjectType(ref.getTargetType());
|
||||
}
|
||||
|
||||
ref.setExternal(fos.get(0) instanceof FactoredObjectProxy);
|
||||
ref.setTargetObject(fos.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void layout() throws Exception {
|
||||
private static final Logger log = LoggerFactory.getLogger(ObjectModel.class);
|
||||
|
||||
public List<FactoredObject> objects = new ArrayList<>();
|
||||
|
||||
public List<FactoredObjectRef> refs = new ArrayList<>();
|
||||
|
||||
protected Object rootObject = null;
|
||||
protected JsonObject jsonCurrent = null;
|
||||
protected JsonObject jsonOrigin = null;
|
||||
|
||||
protected boolean isDirty = false;
|
||||
protected boolean isTracked = false;
|
||||
|
||||
public void addObject(FactoredObject factoredObject) {
|
||||
this.objects.add(factoredObject);
|
||||
}
|
||||
|
||||
public void addRef(FactoredObjectRef factoredObjectRef) {
|
||||
this.refs.add(factoredObjectRef);
|
||||
}
|
||||
|
||||
public Object load(JsonElement root) {
|
||||
|
||||
if (!root.isJsonObject()) {
|
||||
log.debug("NOT AN OBJECT!!");
|
||||
return null;
|
||||
}
|
||||
|
||||
jsonCurrent = root.getAsJsonObject();
|
||||
jsonOrigin = jsonCurrent.deepCopy();
|
||||
|
||||
JsonTraverse jsonTraverse = (new JsonTraverse()).checker(new FactoryChecker(this));
|
||||
|
||||
rootObject = jsonTraverse.traverse(jsonCurrent);
|
||||
return rootObject;
|
||||
}
|
||||
|
||||
public void checkRefs() {
|
||||
List<FactoredObjectRef> originRefs = this.refs.stream()
|
||||
.filter(r -> (r.getTargetObject() == null))
|
||||
.collect(Collectors.toList());
|
||||
for (FactoredObjectRef ref : originRefs) {
|
||||
String targetId = ref.getTargetId();
|
||||
String targetUuid = ref.getTargetUuid();
|
||||
List<FactoredObject> fos = this.objects.stream()
|
||||
.filter(fo -> (fo.getObjectId().equals(targetId)) || fo.getUuid().equals(targetUuid))
|
||||
.collect(Collectors.toList());
|
||||
if (fos.isEmpty()) {
|
||||
|
||||
// System.out.println("CREATING PROXY FOR [" + targetId + "]");
|
||||
|
||||
// create proxy
|
||||
FactoredObjectProxy proxy = new FactoredObjectProxy(this);
|
||||
proxy.wrap(FactoredObjectProxy.getDefaultOrigin(), new HashMap<>(), "");
|
||||
proxy.setObjectId(ref.getTargetId());
|
||||
proxy.setObjectType(ref.getTargetType());
|
||||
|
||||
// update ref
|
||||
ref.setExternal(true);
|
||||
ref.setTargetObject(proxy);
|
||||
|
||||
} else {
|
||||
|
||||
// update objectType for proxy
|
||||
if (fos.get(0) instanceof FactoredObjectProxy) {
|
||||
if (!CommonUtils.isValid(fos.get(0).getObjectType()))
|
||||
fos.get(0).setObjectType(ref.getTargetType());
|
||||
}
|
||||
|
||||
ref.setExternal(fos.get(0) instanceof FactoredObjectProxy);
|
||||
ref.setTargetObject(fos.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void layout() throws Exception {
|
||||
|
||||
JsonObject effectiveJson = new JsonObject();
|
||||
|
||||
// collect root objects
|
||||
List<FactoredObject> rootObjects =
|
||||
this.objects.stream().filter(fo -> fo.definedIn == null).collect(Collectors.toList());
|
||||
JsonArray roots = new JsonArray();
|
||||
for (FactoredObject fo : rootObjects)
|
||||
roots.add(fo.origin);
|
||||
|
||||
List<FactoredObject> newRoots = new ArrayList<>();
|
||||
List<JsonElement> movedElements = new ArrayList<>();
|
||||
for (FactoredObject fo : rootObjects)
|
||||
movedElements.addAll(layoutObject(fo, newRoots));
|
||||
|
||||
rootObjects.addAll(newRoots);
|
||||
for (JsonElement je : movedElements)
|
||||
roots.add(je);
|
||||
|
||||
embedReferences();
|
||||
|
||||
for (FactoredObject fo : objects) {
|
||||
List<FactoredObjectRef> objrefs = refs.stream()
|
||||
.filter(r -> r.isDefinedIn(fo))
|
||||
.filter(r -> !fo.equals(r.getTargetObject()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
List<FactoredObject> sortedRootObjects = DependencySorter.getSortedList(
|
||||
rootObjects,
|
||||
new DependencySorter.DependencyProvider<FactoredObject>() {
|
||||
|
||||
@Override
|
||||
public List<FactoredObject> getDependencies(FactoredObject inspectedObject) {
|
||||
|
||||
// calculate dependencies based on refs
|
||||
List<FactoredObject> dependencies =
|
||||
refs.stream().filter(ref -> ref.isDefinedIn(inspectedObject))
|
||||
.filter(ref -> !ref.isBackRef())
|
||||
.filter(ref -> !ref.isLink())
|
||||
// .filter(ref->!ref.isExternal())
|
||||
.filter(ref -> !inspectedObject.equals(ref.getTargetObject()))
|
||||
.map(ref -> ref.getTargetObject())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// calculate transitive dependencies based on refs in embedded objects
|
||||
List<FactoredObject> embedded = inspectedObject.embedded.stream()
|
||||
.filter(obj -> obj instanceof FactoredObjectRef)
|
||||
.map(obj -> (FactoredObjectRef) obj)
|
||||
.filter(ref -> ref.isLink())
|
||||
.map(ref -> ref.getTargetObject())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (FactoredObject inspectedEmbedded : embedded) {
|
||||
List<FactoredObject> transitives =
|
||||
refs.stream().filter(ref -> ref.isDefinedIn(inspectedEmbedded))
|
||||
.filter(ref -> !ref.isBackRef())
|
||||
.filter(ref -> !ref.isLink())
|
||||
// .filter(ref->!ref.isExternal())
|
||||
.filter(ref -> !inspectedObject.equals(ref.getTargetObject()))
|
||||
.filter(ref -> !inspectedEmbedded.equals(ref.getTargetObject()))
|
||||
.map(ref -> ref.getTargetObject())
|
||||
.collect(Collectors.toList());
|
||||
for (FactoredObject t : transitives)
|
||||
if (!dependencies.contains(t))
|
||||
dependencies.add(t);
|
||||
}
|
||||
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
JsonObject effectiveJson = new JsonObject();
|
||||
|
||||
// collect root objects
|
||||
List<FactoredObject> rootObjects = this.objects.stream().filter(fo -> fo.definedIn==null).collect(Collectors.toList());
|
||||
JsonArray roots = new JsonArray();
|
||||
for (FactoredObject fo: rootObjects)
|
||||
roots.add(fo.origin);
|
||||
|
||||
List<FactoredObject> newRoots = new ArrayList<>();
|
||||
List<JsonElement> movedElements = new ArrayList<>();
|
||||
for (FactoredObject fo: rootObjects)
|
||||
movedElements.addAll(layoutObject(fo, newRoots));
|
||||
|
||||
rootObjects.addAll(newRoots);
|
||||
for (JsonElement je: movedElements)
|
||||
roots.add(je);
|
||||
|
||||
embedReferences();
|
||||
|
||||
for (FactoredObject fo: objects) {
|
||||
List<FactoredObjectRef> objrefs = refs.stream()
|
||||
.filter(r -> r.isDefinedIn(fo))
|
||||
.filter(r->!fo.equals(r.getTargetObject()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
List<FactoredObject> sortedRootObjects = DependencySorter.getSortedList(
|
||||
rootObjects,
|
||||
new DependencySorter.DependencyProvider<FactoredObject>() {
|
||||
|
||||
@Override
|
||||
public List<FactoredObject> getDependencies(FactoredObject inspectedObject) {
|
||||
|
||||
// calculate dependencies based on refs
|
||||
List<FactoredObject> dependencies = refs.stream().filter(ref->ref.isDefinedIn(inspectedObject))
|
||||
.filter(ref->!ref.isBackRef())
|
||||
.filter(ref->!ref.isLink())
|
||||
// .filter(ref->!ref.isExternal())
|
||||
.filter(ref->!inspectedObject.equals(ref.getTargetObject()))
|
||||
.map(ref->ref.getTargetObject())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
/* new LinkedList<>(rootObjects);
|
||||
Collections.<FactoredObject>sort(sortedRootObjects, new Comparator<FactoredObject>() {
|
||||
|
||||
@ -183,142 +208,144 @@ public class ObjectModel {
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
this.objects = sortedRootObjects;
|
||||
|
||||
JsonArray sortedRoots = new JsonArray();
|
||||
for (FactoredObject fo: sortedRootObjects)
|
||||
sortedRoots.add(fo.origin);
|
||||
|
||||
|
||||
// and finalize json
|
||||
effectiveJson.add("##objects", sortedRoots);
|
||||
jsonCurrent = effectiveJson;
|
||||
log.debug(effectiveJson.toString());
|
||||
}
|
||||
|
||||
protected void embedReferences() {
|
||||
for (FactoredObjectRef ref: refs) {
|
||||
|
||||
FactoredObject fo = ref.definedIn;
|
||||
/* if ("private".equals(ref.scope))
|
||||
while ((fo!=null) && "private".equals(fo.scope))
|
||||
fo = fo.definedIn;
|
||||
*/
|
||||
if (fo == null) {
|
||||
log.debug("Error: orphaned ref: [" + ref.getTargetId() + "]");
|
||||
continue;
|
||||
}
|
||||
fo.embed(ref);
|
||||
}
|
||||
}
|
||||
|
||||
protected List<JsonElement> layoutObject(FactoredObject factoredObject, List<FactoredObject> rootObjects) {
|
||||
|
||||
List<JsonElement> result = new ArrayList<>();
|
||||
|
||||
for (FactoredObject fo: factoredObject.dependsOn) {
|
||||
|
||||
if ("private".equals(fo.scope) && !fo.isEmbedded()) {
|
||||
log.debug("FOUND PRIVATE OBJECT :: " + fo.getObjectId());
|
||||
fo.setEmbedded(true);
|
||||
log.debug("CREATING REF TO :: " + fo.getObjectId());
|
||||
FactoredObjectRef objectRef = new FactoredObjectRef(this, fo);
|
||||
objectRef.setLink(true);
|
||||
/* FactoredObject owner = fo.definedIn;
|
||||
// find first non-private object
|
||||
while ((owner!=null) && "private".equals(owner.scope))
|
||||
owner = owner.definedIn;
|
||||
if (owner == null) {
|
||||
log.debug("Error: orphaned private object: [" + fo.getObjectId() + "]");
|
||||
continue;
|
||||
} */
|
||||
result.add(fo.origin);
|
||||
|
||||
if (fo.origin.has("refConfig") && fo.origin.get("refConfig").isJsonObject()) {
|
||||
JsonObject refConfig = fo.origin.get("refConfig").getAsJsonObject();
|
||||
for (Entry<String, JsonElement> entry: refConfig.entrySet()) {
|
||||
if (objectRef.origin.has(entry.getKey()))
|
||||
objectRef.origin.remove(entry.getKey());
|
||||
objectRef.origin.add(entry.getKey(), entry.getValue().deepCopy());
|
||||
}
|
||||
objectRef.updateFromOrigin();
|
||||
}
|
||||
|
||||
objectRef.setTraverseMap(JSONUtils.element2map(objectRef.origin), null);
|
||||
|
||||
log.debug("REPLACING :: " + fo.getObjectId());
|
||||
JSONUtils.replaceValue(factoredObject.origin, fo.relativePath, objectRef.origin);
|
||||
log.debug("TOTAL REFS :: " + refs.size());
|
||||
rootObjects.add(fo);
|
||||
// owner.embed(objectRef);
|
||||
result.addAll(layoutObject(fo, rootObjects));
|
||||
} else {
|
||||
FactoredObjectRef objectRef = new FactoredObjectRef(this, fo);
|
||||
result.add(fo.origin);
|
||||
|
||||
// keep definedIn attribute in ref
|
||||
if (fo.definedIn == factoredObject) {
|
||||
if (objectRef.origin.has(FactoredObjectRef.IS_DEFINITION_ORIGIN))
|
||||
objectRef.origin.remove(FactoredObjectRef.IS_DEFINITION_ORIGIN);
|
||||
objectRef.origin.addProperty(FactoredObjectRef.IS_DEFINITION_ORIGIN, true);
|
||||
} else {
|
||||
objectRef.origin.remove(FactoredObjectRef.IS_DEFINITION_ORIGIN);
|
||||
}
|
||||
|
||||
if (fo.origin.has("refConfig") && fo.origin.get("refConfig").isJsonObject()) {
|
||||
JsonObject refConfig = fo.origin.get("refConfig").getAsJsonObject();
|
||||
for (Entry<String, JsonElement> entry: refConfig.entrySet()) {
|
||||
if (objectRef.origin.has(entry.getKey()))
|
||||
objectRef.origin.remove(entry.getKey());
|
||||
objectRef.origin.add(entry.getKey(), entry.getValue().deepCopy());
|
||||
}
|
||||
objectRef.updateFromOrigin();
|
||||
}
|
||||
objectRef.setTraverseMap(JSONUtils.element2map(objectRef.origin), null);
|
||||
|
||||
JSONUtils.replaceValue(factoredObject.origin, fo.relativePath, objectRef.origin);
|
||||
rootObjects.add(fo);
|
||||
result.addAll(layoutObject(fo, rootObjects));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
this.objects = sortedRootObjects;
|
||||
|
||||
public JsonObject getJsonCurrent() {
|
||||
return jsonCurrent;
|
||||
}
|
||||
JsonArray sortedRoots = new JsonArray();
|
||||
for (FactoredObject fo : sortedRootObjects)
|
||||
sortedRoots.add(fo.origin);
|
||||
|
||||
public JsonObject getJsonOrigin() {
|
||||
return jsonOrigin;
|
||||
}
|
||||
|
||||
public Object getRootObject() {
|
||||
return rootObject;
|
||||
}
|
||||
// and finalize json
|
||||
effectiveJson.add("##objects", sortedRoots);
|
||||
jsonCurrent = effectiveJson;
|
||||
log.debug(effectiveJson.toString());
|
||||
}
|
||||
|
||||
protected void embedReferences() {
|
||||
for (FactoredObjectRef ref : refs) {
|
||||
|
||||
FactoredObject fo = ref.definedIn;
|
||||
/* if ("private".equals(ref.scope))
|
||||
while ((fo!=null) && "private".equals(fo.scope))
|
||||
fo = fo.definedIn;
|
||||
*/
|
||||
if (fo == null) {
|
||||
log.debug("Error: orphaned ref: [" + ref.getTargetId() + "]");
|
||||
continue;
|
||||
}
|
||||
fo.embed(ref);
|
||||
}
|
||||
}
|
||||
|
||||
protected List<JsonElement> layoutObject(FactoredObject factoredObject, List<FactoredObject> rootObjects) {
|
||||
|
||||
List<JsonElement> result = new ArrayList<>();
|
||||
|
||||
for (FactoredObject fo : factoredObject.dependsOn) {
|
||||
|
||||
if ("private".equals(fo.scope) && !fo.isEmbedded()) {
|
||||
log.debug("FOUND PRIVATE OBJECT :: " + fo.getObjectId());
|
||||
fo.setEmbedded(true);
|
||||
log.debug("CREATING REF TO :: " + fo.getObjectId());
|
||||
FactoredObjectRef objectRef = new FactoredObjectRef(this, fo);
|
||||
objectRef.setLink(true);
|
||||
objectRef.setAutoGenerated(true);
|
||||
/* FactoredObject owner = fo.definedIn;
|
||||
// find first non-private object
|
||||
while ((owner!=null) && "private".equals(owner.scope))
|
||||
owner = owner.definedIn;
|
||||
if (owner == null) {
|
||||
log.debug("Error: orphaned private object: [" + fo.getObjectId() + "]");
|
||||
continue;
|
||||
} */
|
||||
result.add(fo.origin);
|
||||
|
||||
if (fo.origin.has("refConfig") && fo.origin.get("refConfig").isJsonObject()) {
|
||||
JsonObject refConfig = fo.origin.get("refConfig").getAsJsonObject();
|
||||
for (Entry<String, JsonElement> entry : refConfig.entrySet()) {
|
||||
if (objectRef.origin.has(entry.getKey()))
|
||||
objectRef.origin.remove(entry.getKey());
|
||||
objectRef.origin.add(entry.getKey(), entry.getValue().deepCopy());
|
||||
}
|
||||
objectRef.updateFromOrigin();
|
||||
}
|
||||
|
||||
objectRef.setTraverseMap(JSONUtils.element2map(objectRef.origin), null);
|
||||
|
||||
log.debug("REPLACING :: " + fo.getObjectId());
|
||||
JSONUtils.replaceValue(factoredObject.origin, fo.relativePath, objectRef.origin);
|
||||
log.debug("TOTAL REFS :: " + refs.size());
|
||||
rootObjects.add(fo);
|
||||
// owner.embed(objectRef);
|
||||
result.addAll(layoutObject(fo, rootObjects));
|
||||
} else {
|
||||
FactoredObjectRef objectRef = new FactoredObjectRef(this, fo);
|
||||
objectRef.setAutoGenerated(true);
|
||||
result.add(fo.origin);
|
||||
|
||||
// keep definedIn attribute in ref
|
||||
if (fo.definedIn == factoredObject) {
|
||||
if (objectRef.origin.has(FactoredObjectRef.IS_DEFINITION_ORIGIN))
|
||||
objectRef.origin.remove(FactoredObjectRef.IS_DEFINITION_ORIGIN);
|
||||
objectRef.origin.addProperty(FactoredObjectRef.IS_DEFINITION_ORIGIN, true);
|
||||
} else {
|
||||
objectRef.origin.remove(FactoredObjectRef.IS_DEFINITION_ORIGIN);
|
||||
}
|
||||
|
||||
if (fo.origin.has("refConfig") && fo.origin.get("refConfig").isJsonObject()) {
|
||||
JsonObject refConfig = fo.origin.get("refConfig").getAsJsonObject();
|
||||
for (Entry<String, JsonElement> entry : refConfig.entrySet()) {
|
||||
if (objectRef.origin.has(entry.getKey()))
|
||||
objectRef.origin.remove(entry.getKey());
|
||||
objectRef.origin.add(entry.getKey(), entry.getValue().deepCopy());
|
||||
}
|
||||
objectRef.updateFromOrigin();
|
||||
}
|
||||
objectRef.setTraverseMap(JSONUtils.element2map(objectRef.origin), null);
|
||||
|
||||
JSONUtils.replaceValue(factoredObject.origin, fo.relativePath, objectRef.origin);
|
||||
rootObjects.add(fo);
|
||||
result.addAll(layoutObject(fo, rootObjects));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public JsonObject getJsonCurrent() {
|
||||
return jsonCurrent;
|
||||
}
|
||||
|
||||
public JsonObject getJsonOrigin() {
|
||||
return jsonOrigin;
|
||||
}
|
||||
|
||||
public Object getRootObject() {
|
||||
return rootObject;
|
||||
}
|
||||
|
||||
public void startTracking() {
|
||||
this.isTracked = true;
|
||||
}
|
||||
|
||||
public boolean stopTracking() {
|
||||
this.isTracked = false;
|
||||
boolean result = this.isDirty;
|
||||
this.isDirty = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setDirty() {
|
||||
if (this.isTracked)
|
||||
this.isDirty = true;
|
||||
}
|
||||
|
||||
public boolean isDirty() {
|
||||
return isDirty;
|
||||
}
|
||||
|
||||
public void startTracking() {
|
||||
this.isTracked = true;
|
||||
}
|
||||
|
||||
public boolean stopTracking() {
|
||||
this.isTracked = false;
|
||||
boolean result = this.isDirty;
|
||||
this.isDirty = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setDirty() {
|
||||
if (this.isTracked)
|
||||
this.isDirty = true;
|
||||
}
|
||||
|
||||
public boolean isDirty() {
|
||||
return isDirty;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -25,6 +25,7 @@
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.executor.support;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.osgi.framework.Constants;
|
||||
@ -67,263 +68,296 @@ import ru.entaxy.platform.core.producer.executor.installer.DefaultInstalledObjec
|
||||
import ru.entaxy.platform.core.producer.executor.installer.InstalledObject;
|
||||
import ru.entaxy.platform.core.producer.executor.installer.ObjectInstaller;
|
||||
|
||||
@Component (service = { ObjectBuilder.class, ObjectDeployer.class, ObjectInstaller.class}, immediate = true)
|
||||
@Component(service = {ObjectBuilder.class, ObjectDeployer.class, ObjectInstaller.class}, immediate = true)
|
||||
public class ArtifactSupport implements ObjectBuilder, ObjectDeployer, ObjectInstaller {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ArtifactSupport.class);
|
||||
|
||||
@Reference (cardinality = ReferenceCardinality.MANDATORY)
|
||||
ArtifactService artifactService;
|
||||
|
||||
/*
|
||||
* ObjectBuilder
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean isBuildable(Generated generated) {
|
||||
Artifact artifact = Artifacts.fromGenerated(generated);
|
||||
if ((artifact == null) || Artifact.ARTIFACT_CATEGORY_UNKNOWN.equals(artifact.getCategory())
|
||||
|| !CommonUtils.isValid(artifact.getCategory())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private static final Logger log = LoggerFactory.getLogger(ArtifactSupport.class);
|
||||
|
||||
@Override
|
||||
public BuiltObject build(Generated generated, Map<String, Object> instructions) throws Exception {
|
||||
|
||||
LocalPrintOutput printer = new LocalPrintOutput(instructions);
|
||||
|
||||
Artifact artifact = Artifacts.fromGenerated(generated);
|
||||
if ((artifact == null) || Artifact.ARTIFACT_CATEGORY_UNKNOWN.equals(artifact.getCategory())
|
||||
|| !CommonUtils.isValid(artifact.getCategory())) {
|
||||
log.info("Artifact is not buildable");
|
||||
return null;
|
||||
}
|
||||
log.info("Built artifact of category [{}]", artifact.getCategory());
|
||||
Map<String, String> headers = GeneratedHeaders.getHeaders(
|
||||
//generated.getProperties()
|
||||
EntaxyObjectPropertiesHelper.getMainObjectProperties(generated.getProperties())
|
||||
).getAsStringMap();
|
||||
|
||||
String mainObjectValue = headers.get(HEADERS.MAIN_OBJECT);
|
||||
if (!CommonUtils.isValid(mainObjectValue))
|
||||
throw new Exception("Main object not found");
|
||||
String[] mainObjectData = mainObjectValue.split(":");
|
||||
if (mainObjectData.length<2)
|
||||
throw new Exception("Main object not complete: [" + mainObjectValue + "]");
|
||||
|
||||
String versionPolicy = generated.getProperties().getOrDefault(
|
||||
EntaxyProducerService.INSTRUCTIONS.ARTIFACT.VERSION_POLICY,
|
||||
instructions.getOrDefault(
|
||||
EntaxyProducerService.INSTRUCTIONS.ARTIFACT.VERSION_POLICY
|
||||
, ""))
|
||||
.toString();
|
||||
String timestamp = generated.getProperties().getOrDefault(
|
||||
EntaxyProducerService.INSTRUCTIONS.ARTIFACT.TIMESTAMP,
|
||||
instructions.getOrDefault(
|
||||
EntaxyProducerService.INSTRUCTIONS.ARTIFACT.TIMESTAMP
|
||||
, ""))
|
||||
.toString();
|
||||
artifact.getCoordinates()
|
||||
.groupId(mainObjectData[1])
|
||||
.artifactId(mainObjectData[0])
|
||||
.version("1")
|
||||
.versionPolicy(versionPolicy)
|
||||
.timestamp(timestamp);
|
||||
|
||||
if (artifact instanceof Manifested) {
|
||||
ArtifactManifest manifest = ((Manifested)artifact).getManifest();
|
||||
manifest.getCustomAttributes().putAll(headers);
|
||||
|
||||
// Generate provided capabilities for every included object
|
||||
ManifestCapabilityHelper helper = new ManifestCapabilityHelper(manifest);
|
||||
|
||||
String objectsValue = headers.getOrDefault(HEADERS.GENERATED_OBJECTS, "");
|
||||
if (CommonUtils.isValid(objectsValue)) {
|
||||
String[] objects = objectsValue.split(",");
|
||||
|
||||
for (int i=0; i<objects.length; i++) {
|
||||
String[] objectData = objects[i].split(":");
|
||||
if (objectData.length<2)
|
||||
continue;
|
||||
String objectId = objectData[0];
|
||||
String objectType = objectData[1];
|
||||
if (!CommonUtils.isValid(objectId) || !CommonUtils.isValid(objectType))
|
||||
continue;
|
||||
objectId = objectId.trim();
|
||||
objectType = objectType.trim();
|
||||
Map<String, Object> attributes = null;
|
||||
Map<String, Object> objectProperties = EntaxyObjectPropertiesHelper
|
||||
.getPropertiesFor(objectId, objectType, generated.getProperties());
|
||||
if (objectProperties.containsKey(FIELDS.FIELDS_TO_PUBLISH)) {
|
||||
Object map = objectProperties.get(FIELDS.FIELDS_TO_PUBLISH);
|
||||
if (map != null) {
|
||||
attributes = (Map<String, Object>)((Map<String, Object>)map).get(objectId);
|
||||
for (String directive: EntaxyFactory.CONFIGURATION.DIRECTIVES.getDesingDirectives())
|
||||
attributes.remove(directive);
|
||||
}
|
||||
}
|
||||
helper.provideCapability(objectType).attributes(attributes);
|
||||
}
|
||||
|
||||
helper.save();
|
||||
|
||||
}
|
||||
}
|
||||
artifact.getProperties().putAll(generated.getProperties());
|
||||
// TODO get value from manifest
|
||||
// ArtifactManifest must be improved to provide read access to all attributes
|
||||
if (!artifact.getProperties().containsKey(Constants.BUNDLE_SYMBOLICNAME)) {
|
||||
artifact.getProperties().put(Constants.BUNDLE_SYMBOLICNAME
|
||||
, artifact.getCoordinates().getGroupId()
|
||||
+ "." + artifact.getCoordinates().getArtifactId());
|
||||
}
|
||||
printer.printOutput("\n\t == " + artifact.getCoordinates().toString() + " ==\n");
|
||||
printer.printOutput(new String(artifact.asByteArray()));
|
||||
printer.printOutput("\n\t == \n");
|
||||
return new DefaultBuiltObject(artifact);
|
||||
}
|
||||
// TODO move to EntaxyFactory
|
||||
public static final String DIRECTIVE_SKIP_PROVIDE = "@SKIP_PROVIDE";
|
||||
|
||||
/*
|
||||
* ObjectDeployer
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean isDeployable(BuiltObject object) {
|
||||
return object.getObject() instanceof Artifact;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeployedObject deploy(BuiltObject object, Map<String, Object> instructions) throws Exception {
|
||||
|
||||
if (!(object.getObject() instanceof Artifact)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
LocalPrintOutput printer = new LocalPrintOutput(instructions);
|
||||
|
||||
boolean deployLocal = false;
|
||||
|
||||
Object deployLocalValue = instructions.get(Deploy.DEPLOY_LOCAL_INSTRUCTION);
|
||||
if (deployLocalValue != null)
|
||||
if (deployLocalValue instanceof Boolean)
|
||||
deployLocal = (Boolean)deployLocalValue;
|
||||
|
||||
Artifact artifact = (Artifact)object.getObject();
|
||||
|
||||
DeployedArtifact da = deployLocal
|
||||
?artifactService.deployLocal(artifact)
|
||||
:artifactService.deployShared(artifact);
|
||||
// TODO move to EntaxyFactory
|
||||
public static final String HEADER_OBJECT_MAP = "@OBJECT-MAP";
|
||||
|
||||
printer.printOutput("DEPLOYED: ["
|
||||
+ da.getLocation()
|
||||
+ "]");
|
||||
|
||||
return new DefaultDeployedObject(da);
|
||||
}
|
||||
|
||||
/*
|
||||
* ObjectInstaller
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean isInstallable(DeployedObject object) {
|
||||
return object.getObject() instanceof DeployedArtifact;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstalledObject install(DeployedObject object, Map<String, Object> instructions) throws Exception {
|
||||
|
||||
if (!isInstallable(object))
|
||||
return null;
|
||||
|
||||
LocalPrintOutput printer = new LocalPrintOutput(instructions);
|
||||
|
||||
CommandInstructions commandInstructions = new CommandInstructions(instructions);
|
||||
|
||||
boolean installLocal =
|
||||
commandInstructions.has(Install.INSTALL_LOCAL_INSTRUCTION)
|
||||
?commandInstructions.getBoolean(Install.INSTALL_LOCAL_INSTRUCTION)
|
||||
:false;
|
||||
|
||||
boolean installOnlyIfMissing =
|
||||
commandInstructions.has(Install.INSTALL_ONLY_IF_MISSING_INSTRUCTION)
|
||||
?commandInstructions.getBoolean(Install.INSTALL_ONLY_IF_MISSING_INSTRUCTION)
|
||||
:false;
|
||||
|
||||
String update =
|
||||
commandInstructions.has(Install.UPDATE_INSTRUCTION)
|
||||
?commandInstructions.getString(Install.UPDATE_INSTRUCTION)
|
||||
:null;
|
||||
|
||||
long startLevelValue =
|
||||
commandInstructions.has(Install.START_LEVEL_INSTRUCTION)
|
||||
?commandInstructions.getLong(Install.START_LEVEL_INSTRUCTION)
|
||||
:-1;
|
||||
|
||||
DeployedArtifact da = (DeployedArtifact)object.getObject();
|
||||
|
||||
InstallationResult result = null;
|
||||
|
||||
Installer<?> installer = null;
|
||||
|
||||
String artifactUpdate = update;
|
||||
|
||||
printer.printOutput("-> Installing artifact: [" + da.getArtifact().getCoordinates().toString() + "]");
|
||||
if (installLocal) {
|
||||
LocalInstaller localInstaller = artifactService.installers().local()
|
||||
.artifact(da);
|
||||
installer = localInstaller;
|
||||
printer.printOutput("-> Installing locally");
|
||||
} else {
|
||||
ClusterInstaller clusterInstaller = artifactService.installers().cluster()
|
||||
.artifact(da);
|
||||
installer = clusterInstaller;
|
||||
printer.printOutput("-> Installing clustered");
|
||||
}
|
||||
@Reference(cardinality = ReferenceCardinality.MANDATORY)
|
||||
ArtifactService artifactService;
|
||||
|
||||
// TODO add support for other types when they appear
|
||||
if (da.getArtifact().getCategory().equals(Blueprint.ARTIFACT_CATEGORY_BLUEPRINT)) {
|
||||
// we're installing blueprint
|
||||
printer.printOutput("-> Installing: " + da.getArtifact().getCategory());
|
||||
BlueprintInstaller blueprintInstaller = installer.typed(BlueprintInstaller.class);
|
||||
if (installOnlyIfMissing)
|
||||
blueprintInstaller.installOnlyIfMissing();
|
||||
if (artifactUpdate != null) {
|
||||
if (!CommonUtils.isValid(artifactUpdate)) {
|
||||
artifactUpdate = da
|
||||
.getArtifact().getProperties()
|
||||
.getOrDefault(Constants.BUNDLE_SYMBOLICNAME, "")
|
||||
.toString();
|
||||
}
|
||||
blueprintInstaller.update(artifactUpdate);
|
||||
}
|
||||
if (startLevelValue > 0)
|
||||
blueprintInstaller.startLevel((int)startLevelValue);
|
||||
result = blueprintInstaller.start().install();
|
||||
} else {
|
||||
printer.printOutput("-> Unknown category: " + da.getArtifact().getCategory());
|
||||
}
|
||||
|
||||
if (result != null) {
|
||||
if (result.getResult().equals(InstallationResult.Result.FAILED)) {
|
||||
if (result.getError() != null)
|
||||
throw (Exception)result.getError();
|
||||
throw new RuntimeException(result.getMessage());
|
||||
} else {
|
||||
for (String key: da.getArtifact().getProperties().keySet())
|
||||
result.getProperties().putIfAbsent(key, da.getArtifact().getProperties().get(key));
|
||||
// TODO imrove Coordinates: add "asMap" method
|
||||
result.getProperties().put("artifact.artifactId", da.getArtifact().getCoordinates().getArtifactId());
|
||||
result.getProperties().put("artifact.groupId", da.getArtifact().getCoordinates().getGroupId());
|
||||
result.getProperties().put("artifact.version", da.getArtifact().getCoordinates().getVersion());
|
||||
result.getProperties().put("artifact.type", da.getArtifact().getCoordinates().getType());
|
||||
result.getProperties().put("artifact.classifier", da.getArtifact().getCoordinates().getClassifier());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new DefaultInstalledObject(result);
|
||||
}
|
||||
/*
|
||||
* ObjectBuilder
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean isBuildable(Generated generated) {
|
||||
Artifact artifact = Artifacts.fromGenerated(generated);
|
||||
if ((artifact == null) || Artifact.ARTIFACT_CATEGORY_UNKNOWN.equals(artifact.getCategory())
|
||||
|| !CommonUtils.isValid(artifact.getCategory())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuiltObject build(Generated generated, Map<String, Object> instructions) throws Exception {
|
||||
|
||||
LocalPrintOutput printer = new LocalPrintOutput(instructions);
|
||||
|
||||
Artifact artifact = Artifacts.fromGenerated(generated);
|
||||
if ((artifact == null) || Artifact.ARTIFACT_CATEGORY_UNKNOWN.equals(artifact.getCategory())
|
||||
|| !CommonUtils.isValid(artifact.getCategory())) {
|
||||
log.info("Artifact is not buildable");
|
||||
return null;
|
||||
}
|
||||
log.info("Built artifact of category [{}]", artifact.getCategory());
|
||||
Map<String, String> headers = GeneratedHeaders.getHeaders(
|
||||
// generated.getProperties()
|
||||
EntaxyObjectPropertiesHelper.getMainObjectProperties(generated.getProperties())).getAsStringMap();
|
||||
|
||||
String mainObjectValue = headers.get(HEADERS.MAIN_OBJECT);
|
||||
if (!CommonUtils.isValid(mainObjectValue))
|
||||
throw new Exception("Main object not found");
|
||||
String[] mainObjectData = mainObjectValue.split(":");
|
||||
if (mainObjectData.length < 2)
|
||||
throw new Exception("Main object not complete: [" + mainObjectValue + "]");
|
||||
|
||||
String versionPolicy = generated.getProperties().getOrDefault(
|
||||
EntaxyProducerService.INSTRUCTIONS.ARTIFACT.VERSION_POLICY,
|
||||
instructions.getOrDefault(
|
||||
EntaxyProducerService.INSTRUCTIONS.ARTIFACT.VERSION_POLICY, ""))
|
||||
.toString();
|
||||
String timestamp = generated.getProperties().getOrDefault(
|
||||
EntaxyProducerService.INSTRUCTIONS.ARTIFACT.TIMESTAMP,
|
||||
instructions.getOrDefault(
|
||||
EntaxyProducerService.INSTRUCTIONS.ARTIFACT.TIMESTAMP, ""))
|
||||
.toString();
|
||||
artifact.getCoordinates()
|
||||
.groupId(mainObjectData[1])
|
||||
.artifactId(mainObjectData[0])
|
||||
.version("1")
|
||||
.versionPolicy(versionPolicy)
|
||||
.timestamp(timestamp);
|
||||
|
||||
if (artifact instanceof Manifested) {
|
||||
ArtifactManifest manifest = ((Manifested) artifact).getManifest();
|
||||
|
||||
// Generate provided capabilities for every included object
|
||||
ManifestCapabilityHelper helper = new ManifestCapabilityHelper(manifest);
|
||||
helper.setMultipleNamespacesSupported(true);
|
||||
|
||||
Map<String, String> objectMap = new HashMap<>();
|
||||
String objectMapValue = headers.getOrDefault(HEADER_OBJECT_MAP, "");
|
||||
if (CommonUtils.isValid(objectMapValue)) {
|
||||
String[] entries = objectMapValue.split(",");
|
||||
for (String entry : entries) {
|
||||
String[] data = entry.split("::");
|
||||
if (data.length < 2)
|
||||
continue;
|
||||
// we invert map from published id to origin id
|
||||
objectMap.put(data[1], data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
headers.remove(HEADER_OBJECT_MAP);
|
||||
|
||||
manifest.getCustomAttributes().putAll(headers);
|
||||
|
||||
String objectsValue = headers.getOrDefault(HEADERS.GENERATED_OBJECTS, "");
|
||||
if (CommonUtils.isValid(objectsValue)) {
|
||||
String[] objects = objectsValue.split(",");
|
||||
|
||||
for (int i = 0; i < objects.length; i++) {
|
||||
String[] objectData = objects[i].split(":");
|
||||
if (objectData.length < 2)
|
||||
continue;
|
||||
String objectId = objectData[0];
|
||||
String objectType = objectData[1];
|
||||
if (!CommonUtils.isValid(objectId) || !CommonUtils.isValid(objectType))
|
||||
continue;
|
||||
objectId = objectId.trim();
|
||||
objectType = objectType.trim();
|
||||
|
||||
if (objectMap.containsKey(objectId + ":" + objectType)) {
|
||||
String mappedValue = objectMap.get(objectId + ":" + objectType);
|
||||
String[] mappedData = mappedValue.split(":");
|
||||
if (mappedData.length > 1) {
|
||||
objectId = mappedData[0];
|
||||
objectType = mappedData[1];
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> attributes = null;
|
||||
Map<String, Object> objectProperties = EntaxyObjectPropertiesHelper
|
||||
.getPropertiesFor(objectId, objectType, generated.getProperties());
|
||||
boolean skipProvide = Boolean.parseBoolean(
|
||||
objectProperties.getOrDefault(DIRECTIVE_SKIP_PROVIDE, false).toString());
|
||||
if (skipProvide)
|
||||
continue;
|
||||
if (objectProperties.containsKey(FIELDS.FIELDS_TO_PUBLISH)) {
|
||||
Object map = objectProperties.get(FIELDS.FIELDS_TO_PUBLISH);
|
||||
if (map != null) {
|
||||
attributes = (Map<String, Object>) ((Map<String, Object>) map).get(objectId);
|
||||
for (String directive : EntaxyFactory.CONFIGURATION.DIRECTIVES.getDesignDirectives())
|
||||
attributes.remove(directive);
|
||||
}
|
||||
}
|
||||
helper.provideCapability(objectType).attributes(attributes);
|
||||
}
|
||||
|
||||
helper.save();
|
||||
|
||||
}
|
||||
}
|
||||
artifact.getProperties().putAll(generated.getProperties());
|
||||
// TODO get value from manifest
|
||||
// ArtifactManifest must be improved to provide read access to all attributes
|
||||
if (!artifact.getProperties().containsKey(Constants.BUNDLE_SYMBOLICNAME)) {
|
||||
artifact.getProperties().put(Constants.BUNDLE_SYMBOLICNAME, artifact.getCoordinates().getGroupId()
|
||||
+ "." + artifact.getCoordinates().getArtifactId());
|
||||
}
|
||||
printer.printOutput("\n\t == " + artifact.getCoordinates().toString() + " ==\n");
|
||||
printer.printOutput(new String(artifact.asByteArray()));
|
||||
printer.printOutput("\n\t == \n");
|
||||
return new DefaultBuiltObject(artifact);
|
||||
}
|
||||
|
||||
/*
|
||||
* ObjectDeployer
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean isDeployable(BuiltObject object) {
|
||||
return object.getObject() instanceof Artifact;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeployedObject deploy(BuiltObject object, Map<String, Object> instructions) throws Exception {
|
||||
|
||||
if (!(object.getObject() instanceof Artifact)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
LocalPrintOutput printer = new LocalPrintOutput(instructions);
|
||||
|
||||
boolean deployLocal = false;
|
||||
|
||||
Object deployLocalValue = instructions.get(Deploy.DEPLOY_LOCAL_INSTRUCTION);
|
||||
if (deployLocalValue != null)
|
||||
if (deployLocalValue instanceof Boolean)
|
||||
deployLocal = (Boolean) deployLocalValue;
|
||||
|
||||
Artifact artifact = (Artifact) object.getObject();
|
||||
|
||||
DeployedArtifact da = deployLocal
|
||||
? artifactService.deployLocal(artifact)
|
||||
: artifactService.deployShared(artifact);
|
||||
|
||||
printer.printOutput("DEPLOYED: ["
|
||||
+ da.getLocation()
|
||||
+ "]");
|
||||
|
||||
return new DefaultDeployedObject(da);
|
||||
}
|
||||
|
||||
/*
|
||||
* ObjectInstaller
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean isInstallable(DeployedObject object) {
|
||||
return object.getObject() instanceof DeployedArtifact;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstalledObject install(DeployedObject object, Map<String, Object> instructions) throws Exception {
|
||||
|
||||
if (!isInstallable(object))
|
||||
return null;
|
||||
|
||||
LocalPrintOutput printer = new LocalPrintOutput(instructions);
|
||||
|
||||
CommandInstructions commandInstructions = new CommandInstructions(instructions);
|
||||
|
||||
boolean installLocal =
|
||||
commandInstructions.has(Install.INSTALL_LOCAL_INSTRUCTION)
|
||||
? commandInstructions.getBoolean(Install.INSTALL_LOCAL_INSTRUCTION)
|
||||
: false;
|
||||
|
||||
boolean installOnlyIfMissing =
|
||||
commandInstructions.has(Install.INSTALL_ONLY_IF_MISSING_INSTRUCTION)
|
||||
? commandInstructions.getBoolean(Install.INSTALL_ONLY_IF_MISSING_INSTRUCTION)
|
||||
: false;
|
||||
|
||||
String update =
|
||||
commandInstructions.has(Install.UPDATE_INSTRUCTION)
|
||||
? commandInstructions.getString(Install.UPDATE_INSTRUCTION)
|
||||
: null;
|
||||
|
||||
long startLevelValue =
|
||||
commandInstructions.has(Install.START_LEVEL_INSTRUCTION)
|
||||
? commandInstructions.getLong(Install.START_LEVEL_INSTRUCTION)
|
||||
: -1;
|
||||
|
||||
DeployedArtifact da = (DeployedArtifact) object.getObject();
|
||||
|
||||
InstallationResult result = null;
|
||||
|
||||
Installer<?> installer = null;
|
||||
|
||||
String artifactUpdate = update;
|
||||
|
||||
printer.printOutput("-> Installing artifact: [" + da.getArtifact().getCoordinates().toString() + "]");
|
||||
if (installLocal) {
|
||||
LocalInstaller localInstaller = artifactService.installers().local()
|
||||
.artifact(da);
|
||||
installer = localInstaller;
|
||||
printer.printOutput("-> Installing locally");
|
||||
} else {
|
||||
ClusterInstaller clusterInstaller = artifactService.installers().cluster()
|
||||
.artifact(da);
|
||||
installer = clusterInstaller;
|
||||
printer.printOutput("-> Installing clustered");
|
||||
}
|
||||
|
||||
// TODO add support for other types when they appear
|
||||
if (da.getArtifact().getCategory().equals(Blueprint.ARTIFACT_CATEGORY_BLUEPRINT)) {
|
||||
// we're installing blueprint
|
||||
printer.printOutput("-> Installing: " + da.getArtifact().getCategory());
|
||||
BlueprintInstaller blueprintInstaller = installer.typed(BlueprintInstaller.class);
|
||||
if (installOnlyIfMissing)
|
||||
blueprintInstaller.installOnlyIfMissing();
|
||||
if (artifactUpdate != null) {
|
||||
if (!CommonUtils.isValid(artifactUpdate)) {
|
||||
artifactUpdate = da
|
||||
.getArtifact().getProperties()
|
||||
.getOrDefault(Constants.BUNDLE_SYMBOLICNAME, "")
|
||||
.toString();
|
||||
}
|
||||
blueprintInstaller.update(artifactUpdate);
|
||||
}
|
||||
if (startLevelValue > 0)
|
||||
blueprintInstaller.startLevel((int) startLevelValue);
|
||||
result = blueprintInstaller.start().install();
|
||||
} else {
|
||||
printer.printOutput("-> Unknown category: " + da.getArtifact().getCategory());
|
||||
}
|
||||
|
||||
if (result != null) {
|
||||
if (result.getResult().equals(InstallationResult.Result.FAILED)) {
|
||||
if (result.getError() != null)
|
||||
throw (Exception) result.getError();
|
||||
throw new RuntimeException(result.getMessage());
|
||||
} else {
|
||||
for (String key : da.getArtifact().getProperties().keySet())
|
||||
result.getProperties().putIfAbsent(key, da.getArtifact().getProperties().get(key));
|
||||
// TODO imrove Coordinates: add "asMap" method
|
||||
result.getProperties().put("artifact.artifactId", da.getArtifact().getCoordinates().getArtifactId());
|
||||
result.getProperties().put("artifact.groupId", da.getArtifact().getCoordinates().getGroupId());
|
||||
result.getProperties().put("artifact.version", da.getArtifact().getCoordinates().getVersion());
|
||||
result.getProperties().put("artifact.type", da.getArtifact().getCoordinates().getType());
|
||||
result.getProperties().put("artifact.classifier", da.getArtifact().getCoordinates().getClassifier());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new DefaultInstalledObject(result);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -37,55 +37,65 @@ import ru.entaxy.platform.core.producer.wrapper.AbstractFactoryWrapper;
|
||||
import ru.entaxy.platform.core.producer.wrapper.AbstractFactoryWrapper.GenerationProcessor;
|
||||
|
||||
public class CommonObjectProducer extends DefaultProducer implements GenerationProcessor {
|
||||
|
||||
protected final Map<String, String> defaultFieldsPublished = new HashMap<>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
{
|
||||
put(FIELDS.OBJECT_ID, FIELDS.OBJECT_ID);
|
||||
}};
|
||||
|
||||
protected Map<String, String> getFieldsToPublish(String outputType, String scope, String objectType, String objectId){
|
||||
return defaultFieldsPublished;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addFields(AbstractFactoryWrapper factoryWrapper) {
|
||||
super.addFields(factoryWrapper);
|
||||
/*factoryWrapper.addField(
|
||||
(new FieldInfoImpl())
|
||||
.name(FIELDS.OBJECT_ID)
|
||||
.type("String")
|
||||
.required(true)
|
||||
.immutable(true)
|
||||
);
|
||||
*/
|
||||
}
|
||||
@Deprecated(since = "1.10", forRemoval = true)
|
||||
protected final Map<String, String> defaultFieldsPublished = new HashMap<>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
{
|
||||
put(FIELDS.OBJECT_ID, FIELDS.OBJECT_ID);
|
||||
}
|
||||
};
|
||||
|
||||
@Deprecated(since = "1.10", forRemoval = true)
|
||||
protected Map<String, String> getFieldsToPublish(String outputType, String scope, String objectType,
|
||||
String objectId) {
|
||||
return defaultFieldsPublished;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addFields(AbstractFactoryWrapper factoryWrapper) {
|
||||
super.addFields(factoryWrapper);
|
||||
/*factoryWrapper.addField(
|
||||
(new FieldInfoImpl())
|
||||
.name(FIELDS.OBJECT_ID)
|
||||
.type("String")
|
||||
.required(true)
|
||||
.immutable(true)
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postGenerate(EntaxyWrappedFactory wrappedFactory, String outputType, String scope, String objectType,
|
||||
Map<String, Object> parameters,
|
||||
Generated generated) throws EntaxyFactoryException {
|
||||
|
||||
// BEGIN : deprecated code for publishing properties
|
||||
// TODO remove
|
||||
String objectId = parameters.getOrDefault(FIELDS.OBJECT_ID, "").toString();
|
||||
|
||||
Map<String, String> publishedFields = getFieldsToPublish(outputType, scope, objectType, objectId);
|
||||
|
||||
Map<String, Object> dataToPublish = new HashMap<>();
|
||||
|
||||
if (parameters.containsKey(FIELDS.FIELDS_TO_PUBLISH)) {
|
||||
Object obj = parameters.get(FIELDS.FIELDS_TO_PUBLISH);
|
||||
if (obj instanceof Map) {
|
||||
Map<String, Object> ownData = (Map) obj;
|
||||
dataToPublish.putAll(ownData);
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<String, String> entry : publishedFields.entrySet())
|
||||
dataToPublish.putIfAbsent(entry.getKey(), generated.getProperties().get(entry.getValue()));
|
||||
|
||||
generated.getProperties().put(FIELDS.FIELDS_TO_PUBLISH, new HashMap<String, Map<String, Object>>() {
|
||||
{
|
||||
put(objectId, dataToPublish);
|
||||
}
|
||||
});
|
||||
// END : deprecated code for publishing properties
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postGenerate(EntaxyWrappedFactory wrappedFactory, String outputType, String scope, String objectType, Map<String, Object> parameters,
|
||||
Generated generated) throws EntaxyFactoryException {
|
||||
|
||||
String objectId = parameters.getOrDefault(FIELDS.OBJECT_ID, "").toString();
|
||||
|
||||
Map<String, String> publishedFields = getFieldsToPublish(outputType, scope, objectType, objectId);
|
||||
|
||||
Map<String, Object> dataToPublish = new HashMap<>();
|
||||
|
||||
if (parameters.containsKey(FIELDS.FIELDS_TO_PUBLISH)) {
|
||||
Object obj = parameters.get(FIELDS.FIELDS_TO_PUBLISH);
|
||||
if (obj instanceof Map) {
|
||||
Map<String, Object> ownData = (Map)obj;
|
||||
dataToPublish.putAll(ownData);
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<String, String> entry: publishedFields.entrySet())
|
||||
dataToPublish.put(entry.getKey(), generated.getProperties().get(entry.getValue()));
|
||||
|
||||
generated.getProperties().put(FIELDS.FIELDS_TO_PUBLISH, new HashMap<String, Map<String, Object>>() {{
|
||||
put(objectId, dataToPublish);
|
||||
}});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -45,142 +45,146 @@ import ru.entaxy.platform.core.producer.wrapper.DefaultFactoryWrapper;
|
||||
|
||||
public abstract class DefaultProducer implements EntaxyProducer {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DefaultProducer.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(DefaultProducer.class);
|
||||
|
||||
protected Class<? extends AbstractFactoryWrapper> factoryWrapperClass = DefaultFactoryWrapper.class;
|
||||
|
||||
protected Map<EntaxyFactory, AbstractFactoryWrapper> factories = new HashMap<>();
|
||||
protected Class<? extends AbstractFactoryWrapper> factoryWrapperClass = DefaultFactoryWrapper.class;
|
||||
|
||||
protected List<String> supportedTypesOrigin = new ArrayList<>();
|
||||
|
||||
protected List<String> supportedTypes = new ArrayList<>();
|
||||
protected List<String> supportedTypesPatterns = new ArrayList<>();
|
||||
|
||||
protected List<EntaxyProducerListener> listeners = new ArrayList<>();
|
||||
|
||||
public DefaultProducer() {
|
||||
if (this.getClass().isAnnotationPresent(EntaxyProducerInfo.class)) {
|
||||
EntaxyProducerInfo info = this.getClass().getAnnotation(EntaxyProducerInfo.class);
|
||||
setSupportedTypes(Arrays.asList(info.supportedTypes()));
|
||||
this.factoryWrapperClass = info.factoryWrapperClass();
|
||||
}
|
||||
}
|
||||
|
||||
protected void setSupportedTypes(List<String> typesToSet) {
|
||||
this.supportedTypesOrigin = typesToSet;
|
||||
for (String s: typesToSet) {
|
||||
if (EntaxyProducerUtils.isPattern(s)) {
|
||||
this.supportedTypesPatterns.add(EntaxyProducerUtils.toRegexPattern(s));
|
||||
} else {
|
||||
this.supportedTypes.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(EntaxyProducerListener listener) {
|
||||
synchronized (this.listeners) {
|
||||
this.listeners.remove(listener);
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(EntaxyProducerListener listener) {
|
||||
synchronized (this.listeners) {
|
||||
this.listeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
protected AbstractFactoryWrapper doAddFactory(EntaxyFactory factory) {
|
||||
return doAddFactory(factory, factoryWrapperClass);
|
||||
}
|
||||
protected AbstractFactoryWrapper doAddFactory(EntaxyFactory factory, Class<? extends AbstractFactoryWrapper> wrapperClass) {
|
||||
if (isTypeSupported(factory.getType())) {
|
||||
|
||||
try {
|
||||
AbstractFactoryWrapper wrapper = createWrapper(factory, wrapperClass);
|
||||
addFields(wrapper);
|
||||
factories.put(factory, wrapper);
|
||||
|
||||
synchronized (this.listeners) {
|
||||
for (EntaxyProducerListener listener: this.listeners)
|
||||
listener.factoryAdded(wrapper.getId(), wrapper.getType(), this);
|
||||
}
|
||||
|
||||
log.debug("Factory added:" + factory.getId());
|
||||
return wrapper;
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
|
||||
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
|
||||
log.error("FactoryWrapper creation failed: ", e);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
log.debug("Factory addition ignored: [{}:{}] for types [{}]"
|
||||
, factory.getId()
|
||||
, factory.getType()
|
||||
, getSupportedTypes().stream().collect(Collectors.joining(",")));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isTypeSupported(String type) {
|
||||
if (this.supportedTypes.contains(type))
|
||||
return true;
|
||||
for (String s: supportedTypesPatterns)
|
||||
if (Pattern.matches(s, type))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected AbstractFactoryWrapper createWrapper(EntaxyFactory factory, Class<? extends AbstractFactoryWrapper> wrapperClass) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
|
||||
return wrapperClass.getConstructor(EntaxyFactory.class).newInstance(factory);
|
||||
}
|
||||
|
||||
protected void addFields(AbstractFactoryWrapper factoryWrapper) {
|
||||
|
||||
}
|
||||
|
||||
public void removeFactory(EntaxyFactory factory) {
|
||||
if (isTypeSupported(factory.getType())) {
|
||||
factories.remove(factory);
|
||||
synchronized (this.listeners) {
|
||||
for (EntaxyProducerListener listener: this.listeners)
|
||||
listener.factoryRemoved(factory.getFactoryId(), factory.getFactoryType(), this);
|
||||
}
|
||||
|
||||
log.debug("Factory removed:" + factory.getFactoryId());
|
||||
} else {
|
||||
log.debug("Factory removal ignored:" + factory.getFactoryId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProducerId() {
|
||||
return this.getClass().getName();
|
||||
}
|
||||
protected Map<String, AbstractFactoryWrapper> factories = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public List<EntaxyFactory> getAllFactories() {
|
||||
return new ArrayList<>(factories.values());
|
||||
}
|
||||
protected List<String> supportedTypesOrigin = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public List<EntaxyFactory> getFactoriesForType(String factoryType) {
|
||||
return factories.values().stream().filter((f)->{return f.getFactoryType().equals(factoryType);})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
protected List<String> supportedTypes = new ArrayList<>();
|
||||
protected List<String> supportedTypesPatterns = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public EntaxyFactory getFactoryById(String factoryId) {
|
||||
for (EntaxyFactory f: factories.values())
|
||||
if (f.getFactoryId().equals(factoryId))
|
||||
return f;
|
||||
return null;
|
||||
}
|
||||
protected List<EntaxyProducerListener> listeners = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public List<String> getSupportedTypes() {
|
||||
return this.supportedTypesOrigin;
|
||||
}
|
||||
public DefaultProducer() {
|
||||
if (this.getClass().isAnnotationPresent(EntaxyProducerInfo.class)) {
|
||||
EntaxyProducerInfo info = this.getClass().getAnnotation(EntaxyProducerInfo.class);
|
||||
setSupportedTypes(Arrays.asList(info.supportedTypes()));
|
||||
this.factoryWrapperClass = info.factoryWrapperClass();
|
||||
}
|
||||
}
|
||||
|
||||
protected void setSupportedTypes(List<String> typesToSet) {
|
||||
this.supportedTypesOrigin = typesToSet;
|
||||
for (String s : typesToSet) {
|
||||
if (EntaxyProducerUtils.isPattern(s)) {
|
||||
this.supportedTypesPatterns.add(EntaxyProducerUtils.toRegexPattern(s));
|
||||
} else {
|
||||
this.supportedTypes.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(EntaxyProducerListener listener) {
|
||||
synchronized (this.listeners) {
|
||||
this.listeners.remove(listener);
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(EntaxyProducerListener listener) {
|
||||
synchronized (this.listeners) {
|
||||
this.listeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
protected AbstractFactoryWrapper doAddFactory(EntaxyFactory factory) {
|
||||
return doAddFactory(factory, factoryWrapperClass);
|
||||
}
|
||||
|
||||
protected AbstractFactoryWrapper doAddFactory(EntaxyFactory factory,
|
||||
Class<? extends AbstractFactoryWrapper> wrapperClass) {
|
||||
if (isTypeSupported(factory.getType())) {
|
||||
|
||||
try {
|
||||
AbstractFactoryWrapper wrapper = createWrapper(factory, wrapperClass);
|
||||
addFields(wrapper);
|
||||
factories.put(factory.getId(), wrapper);
|
||||
|
||||
synchronized (this.listeners) {
|
||||
for (EntaxyProducerListener listener : this.listeners)
|
||||
listener.factoryAdded(wrapper.getId(), wrapper.getType(), this);
|
||||
}
|
||||
|
||||
log.debug("Factory added:" + factory.getId());
|
||||
return wrapper;
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
|
||||
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
|
||||
log.error("FactoryWrapper creation failed: ", e);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
log.debug("Factory addition ignored: [{}:{}] for types [{}]", factory.getId(), factory.getType(),
|
||||
getSupportedTypes().stream().collect(Collectors.joining(",")));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isTypeSupported(String type) {
|
||||
if (this.supportedTypes.contains(type))
|
||||
return true;
|
||||
for (String s : supportedTypesPatterns)
|
||||
if (Pattern.matches(s, type))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected AbstractFactoryWrapper createWrapper(EntaxyFactory factory,
|
||||
Class<? extends AbstractFactoryWrapper> wrapperClass) throws InstantiationException, IllegalAccessException,
|
||||
IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
|
||||
return wrapperClass.getConstructor(EntaxyFactory.class).newInstance(factory);
|
||||
}
|
||||
|
||||
protected void addFields(AbstractFactoryWrapper factoryWrapper) {
|
||||
|
||||
}
|
||||
|
||||
public void removeFactory(EntaxyFactory factory) {
|
||||
if (isTypeSupported(factory.getType())) {
|
||||
factories.remove(factory);
|
||||
synchronized (this.listeners) {
|
||||
for (EntaxyProducerListener listener : this.listeners)
|
||||
listener.factoryRemoved(factory.getFactoryId(), factory.getFactoryType(), this);
|
||||
}
|
||||
|
||||
log.debug("Factory removed:" + factory.getFactoryId());
|
||||
} else {
|
||||
log.debug("Factory removal ignored:" + factory.getFactoryId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProducerId() {
|
||||
return this.getClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EntaxyFactory> getAllFactories() {
|
||||
return new ArrayList<>(factories.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EntaxyFactory> getFactoriesForType(String factoryType) {
|
||||
return factories.values().stream().filter((f) -> {
|
||||
return f.getFactoryType().equals(factoryType);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntaxyFactory getFactoryById(String factoryId) {
|
||||
for (EntaxyFactory f : factories.values())
|
||||
if (f.getFactoryId().equals(factoryId))
|
||||
return f;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSupportedTypes() {
|
||||
return this.supportedTypesOrigin;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -44,6 +44,10 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ru.entaxy.esb.platform.runtime.base.extensions.api.EntaxyExtendable;
|
||||
import ru.entaxy.esb.platform.runtime.base.extensions.api.EntaxyExtension;
|
||||
import ru.entaxy.esb.platform.runtime.base.extensions.api.EntaxyExtensionsAware;
|
||||
import ru.entaxy.esb.platform.runtime.base.extensions.api.Extendable;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
|
||||
import ru.entaxy.platform.base.support.JSONUtils;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyProducer;
|
||||
@ -63,138 +67,185 @@ import ru.entaxy.platform.core.producer.executor.commands.PrepareGenerate;
|
||||
import ru.entaxy.platform.core.producer.executor.commands.Store;
|
||||
import ru.entaxy.platform.core.producer.executor.commands.Validate;
|
||||
|
||||
@Component (service = {EntaxyProducerService.class}, immediate = true)
|
||||
public class EntaxyProducerServiceImpl implements EntaxyProducerService {
|
||||
@Component(service = {EntaxyProducerService.class, EntaxyExtendable.class}, immediate = true)
|
||||
@Extendable("objectproducer")
|
||||
public class EntaxyProducerServiceImpl implements EntaxyProducerService, EntaxyExtendable {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(EntaxyProducerServiceImpl.class);
|
||||
|
||||
private static final String LIFECYCLES_FILE_PATH = System.getProperty("karaf.etc")
|
||||
+ File.separator
|
||||
+ "producing.lifecycles.json";
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(EntaxyProducerServiceImpl.class);
|
||||
|
||||
private static final String LIFECYCLES_FILE_PATH = System.getProperty("karaf.etc")
|
||||
+ File.separator
|
||||
+ "producing.lifecycles.json";
|
||||
|
||||
protected JsonObject lifecycles = new JsonObject();
|
||||
|
||||
|
||||
protected InstructionsHelper instructionsHelper;
|
||||
|
||||
protected List<EntaxyProducer> producers = new ArrayList<>();
|
||||
|
||||
protected Map<String, ProducingCommandExecutor> commandExecutors = new HashMap<>();
|
||||
|
||||
@Reference (bind = "addProducer", unbind = "removeProducer", cardinality = ReferenceCardinality.MULTIPLE
|
||||
, collectionType = CollectionType.SERVICE, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY)
|
||||
public void addProducer(EntaxyProducer producer) {
|
||||
producers.add(producer);
|
||||
log.debug("Producer added: " + producer.getProducerId());
|
||||
}
|
||||
|
||||
public void removeProducer(EntaxyProducer producer) {
|
||||
producers.remove(producer);
|
||||
log.debug("Producer removed: " + producer.getProducerId());
|
||||
}
|
||||
|
||||
@Activate
|
||||
public void activate(ComponentContext componentContext) {
|
||||
registerCommand(new Analyze(this));
|
||||
registerCommand(new Layout(this));
|
||||
registerCommand(new Validate(this));
|
||||
registerCommand(new PrepareGenerate(this));
|
||||
registerCommand(new Generate(this));
|
||||
registerCommand(new Build(this));
|
||||
registerCommand(new Deploy(this));
|
||||
registerCommand(new Install(this));
|
||||
registerCommand(new Enrich(this));
|
||||
registerCommand(new Store(this));
|
||||
initLifecycles();
|
||||
}
|
||||
|
||||
protected void initLifecycles() {
|
||||
File lc = new File(LIFECYCLES_FILE_PATH);
|
||||
if (lc.exists() && lc.canRead()) {
|
||||
try {
|
||||
this.lifecycles = JSONUtils.getJsonRootObject(lc.toURI().toURL());
|
||||
} catch (Exception e) {
|
||||
log.warn("Eror reading lifecycles config", e);
|
||||
}
|
||||
}
|
||||
this.instructionsHelper = new InstructionsHelper(this.lifecycles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCommand(ProducingCommandExecutor commandExecutor) {
|
||||
this.commandExecutors.put(commandExecutor.getId(), commandExecutor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProducerResult produce(String configuration) {
|
||||
return this.produce(configuration, "{}");
|
||||
}
|
||||
protected List<EntaxyProducer> producers = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public ProducerResult produce(String configuration, String instructions) {
|
||||
return produce(JSONUtils.getJsonRootObject(configuration), instructions);
|
||||
}
|
||||
protected Map<String, ProducingCommandExecutor> commandExecutors = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public ProducerResult produce(JsonObject configuration) {
|
||||
return produce(configuration, "{}");
|
||||
}
|
||||
protected Map<String, Map<String, Map<String, Object>>> lifecycleExtensions = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public ProducerResult produce(JsonObject configuration, String instructions) {
|
||||
try {
|
||||
return (new ProducingExecutor(configuration
|
||||
, instructionsHelper.prepareInstructions(instructions)
|
||||
,this))
|
||||
.execute();
|
||||
} catch (Exception e) {
|
||||
log.error("Produce failed", e);
|
||||
return ProducerResult.createFailed(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<EntaxyProducer> getAllProducers() {
|
||||
return producers;
|
||||
}
|
||||
protected Object lifecycleExtensionsLock = new Object();
|
||||
|
||||
@Override
|
||||
public EntaxyProducer getProducerForType(String type) {
|
||||
List<EntaxyProducer> directSupport = new ArrayList<>();
|
||||
List<EntaxyProducer> patternSupport = new ArrayList<>();
|
||||
for (EntaxyProducer p: producers)
|
||||
for (String s: p.getSupportedTypes()) {
|
||||
if (EntaxyProducerUtils.isPattern(s)) {
|
||||
if (EntaxyProducerUtils.isMatched(s, type))
|
||||
patternSupport.add(p);
|
||||
} else
|
||||
if (s.equalsIgnoreCase(type))
|
||||
directSupport.add(p);
|
||||
}
|
||||
if (!directSupport.isEmpty())
|
||||
return directSupport.get(0);
|
||||
if (!patternSupport.isEmpty())
|
||||
return patternSupport.get(0);
|
||||
return null;
|
||||
}
|
||||
protected final List<EntaxyExtension> entaxyExtensions = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public List<ProducingCommandExecutor> getAvailableCommands() {
|
||||
return new ArrayList<>(commandExecutors.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProducingCommandExecutor getCommandById(String id) {
|
||||
return this.commandExecutors.get(id);
|
||||
}
|
||||
@Reference(bind = "addProducer", unbind = "removeProducer", cardinality = ReferenceCardinality.MULTIPLE,
|
||||
collectionType = CollectionType.SERVICE, policy = ReferencePolicy.DYNAMIC,
|
||||
policyOption = ReferencePolicyOption.GREEDY)
|
||||
public void addProducer(EntaxyProducer producer) {
|
||||
producers.add(producer);
|
||||
if (producer instanceof EntaxyExtensionsAware)
|
||||
((EntaxyExtensionsAware) producer).addExtensions(entaxyExtensions);
|
||||
log.debug("Producer added: " + producer.getProducerId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntaxyFactory findFactoryById(String factoryId) {
|
||||
for (EntaxyProducer p: getAllProducers()) {
|
||||
EntaxyFactory f = p.getFactoryById(factoryId);
|
||||
if (f != null)
|
||||
return f;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public void removeProducer(EntaxyProducer producer) {
|
||||
producers.remove(producer);
|
||||
log.debug("Producer removed: " + producer.getProducerId());
|
||||
}
|
||||
|
||||
@Activate
|
||||
public void activate(ComponentContext componentContext) {
|
||||
registerCommand(new Analyze(this));
|
||||
registerCommand(new Layout(this));
|
||||
registerCommand(new Validate(this));
|
||||
registerCommand(new PrepareGenerate(this));
|
||||
registerCommand(new Generate(this));
|
||||
registerCommand(new Build(this));
|
||||
registerCommand(new Deploy(this));
|
||||
registerCommand(new Install(this));
|
||||
registerCommand(new Enrich(this));
|
||||
registerCommand(new Store(this));
|
||||
initLifecycles();
|
||||
}
|
||||
|
||||
protected void initLifecycles() {
|
||||
File lc = new File(LIFECYCLES_FILE_PATH);
|
||||
if (lc.exists() && lc.canRead()) {
|
||||
try {
|
||||
this.lifecycles = JSONUtils.getJsonRootObject(lc.toURI().toURL());
|
||||
} catch (Exception e) {
|
||||
log.warn("Error reading lifecycles config", e);
|
||||
}
|
||||
}
|
||||
this.instructionsHelper = new InstructionsHelper(this.lifecycles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCommand(ProducingCommandExecutor commandExecutor) {
|
||||
this.commandExecutors.put(commandExecutor.getId(), commandExecutor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void extendLifecycle(String lifecycle, ProducingCommandExecutor commandExecutor,
|
||||
Map<String, Object> parameters) {
|
||||
synchronized (lifecycleExtensionsLock) {
|
||||
if (!lifecycleExtensions.containsKey(lifecycle))
|
||||
lifecycleExtensions.put(lifecycle, new HashMap<String, Map<String, Object>>());
|
||||
Map<String, Map<String, Object>> lifecycleExtension =
|
||||
lifecycleExtensions.get(lifecycle);
|
||||
|
||||
lifecycleExtension.put(commandExecutor.getId(), parameters);
|
||||
|
||||
this.instructionsHelper.setLifecycleExtensions(lifecycleExtensions);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProducerResult produce(String configuration) {
|
||||
return this.produce(configuration, "{}");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProducerResult produce(String configuration, String instructions) {
|
||||
return produce(JSONUtils.getJsonRootObject(configuration), instructions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProducerResult produce(JsonObject configuration) {
|
||||
return produce(configuration, "{}");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProducerResult produce(JsonObject configuration, String instructions) {
|
||||
try {
|
||||
return (new ProducingExecutor(configuration, instructionsHelper.prepareInstructions(instructions), this))
|
||||
.execute();
|
||||
} catch (Exception e) {
|
||||
log.error("Produce failed", e);
|
||||
return ProducerResult.createFailed(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<EntaxyProducer> getAllProducers() {
|
||||
return producers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntaxyProducer getProducerForType(String type) {
|
||||
List<EntaxyProducer> directSupport = new ArrayList<>();
|
||||
List<EntaxyProducer> patternSupport = new ArrayList<>();
|
||||
for (EntaxyProducer p : producers)
|
||||
for (String s : p.getSupportedTypes()) {
|
||||
if (EntaxyProducerUtils.isPattern(s)) {
|
||||
if (EntaxyProducerUtils.isMatched(s, type))
|
||||
patternSupport.add(p);
|
||||
} else if (s.equalsIgnoreCase(type))
|
||||
directSupport.add(p);
|
||||
}
|
||||
if (!directSupport.isEmpty())
|
||||
return directSupport.get(0);
|
||||
if (!patternSupport.isEmpty())
|
||||
return patternSupport.get(0);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProducingCommandExecutor> getAvailableCommands() {
|
||||
return new ArrayList<>(commandExecutors.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProducingCommandExecutor getCommandById(String id) {
|
||||
return this.commandExecutors.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntaxyFactory findFactoryById(String factoryId) {
|
||||
for (EntaxyProducer p : getAllProducers()) {
|
||||
EntaxyFactory f = p.getFactoryById(factoryId);
|
||||
if (f != null)
|
||||
return f;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtension(EntaxyExtension entaxyExtension) {
|
||||
if (!entaxyExtensions.contains(entaxyExtension)) {
|
||||
entaxyExtensions.add(entaxyExtension);
|
||||
producers.stream()
|
||||
.filter(p -> (p instanceof EntaxyExtensionsAware))
|
||||
.map(p -> (EntaxyExtensionsAware) p)
|
||||
.forEach(p -> p.addExtension(entaxyExtension));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeExtension(EntaxyExtension entaxyExtension) {
|
||||
entaxyExtensions.remove(entaxyExtension);
|
||||
producers.stream()
|
||||
.filter(p -> (p instanceof EntaxyExtensionsAware))
|
||||
.map(p -> (EntaxyExtensionsAware) p)
|
||||
.forEach(p -> p.removeExtension(entaxyExtension));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EntaxyExtension> getExtensions() {
|
||||
return entaxyExtensions;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -42,52 +42,72 @@ import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
|
||||
|
||||
public class InstructionsHelper {
|
||||
|
||||
public static final String DEFAULT_INSTRUCTIONS = "{'validate':{}}";
|
||||
public static final String LIFECYCLE_DIRECTIVE = EntaxyProducerService.DIRECTIVES.LIFECYCLE;
|
||||
|
||||
protected JsonObject lifecyclesOrigin;
|
||||
|
||||
protected Map<String, JsonObject> lifecycles = new HashMap<>();
|
||||
|
||||
public InstructionsHelper(JsonObject lifecycles) {
|
||||
super();
|
||||
this.lifecyclesOrigin = lifecycles.deepCopy();
|
||||
fillMap(this.lifecyclesOrigin);
|
||||
}
|
||||
|
||||
protected void fillMap(JsonObject origin) {
|
||||
for (Entry<String, JsonElement> entry: origin.entrySet())
|
||||
if (entry.getValue().isJsonObject())
|
||||
this.lifecycles.put(entry.getKey(), entry.getValue().getAsJsonObject().deepCopy());
|
||||
}
|
||||
|
||||
public String prepareInstructions(String originalInstructions) {
|
||||
JsonObject origin = JSONUtils.getJsonRootObject(originalInstructions);
|
||||
JsonObject result = new JsonObject();
|
||||
if (origin.has(LIFECYCLE_DIRECTIVE)) {
|
||||
JsonElement directiveValue = origin.get(LIFECYCLE_DIRECTIVE);
|
||||
List<String> lcIdToApply = new ArrayList<>();
|
||||
List<JsonObject> lcToApply = new ArrayList<>();
|
||||
if (directiveValue.isJsonPrimitive())
|
||||
lcIdToApply.add(directiveValue.getAsString());
|
||||
if (directiveValue.isJsonArray()) {
|
||||
JsonArray ja = directiveValue.getAsJsonArray();
|
||||
for (int i=0; i<ja.size(); i++)
|
||||
lcIdToApply.add(ja.get(i).getAsString());
|
||||
}
|
||||
origin.remove(LIFECYCLE_DIRECTIVE);
|
||||
for (String id: lcIdToApply)
|
||||
if (this.lifecycles.containsKey(id))
|
||||
EntaxyFactoryUtils.processObjectOverriding(
|
||||
result
|
||||
, this.lifecycles.get(id)
|
||||
, OVERRIDE_MODE.UPDATE);
|
||||
}
|
||||
EntaxyFactoryUtils.processObjectOverriding(
|
||||
result
|
||||
, origin
|
||||
, OVERRIDE_MODE.UPDATE);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static final String DEFAULT_INSTRUCTIONS = "{'validate':{}}";
|
||||
public static final String LIFECYCLE_DIRECTIVE = EntaxyProducerService.DIRECTIVES.LIFECYCLE;
|
||||
|
||||
protected JsonObject lifecyclesOrigin;
|
||||
|
||||
protected Map<String, JsonObject> lifecycles = new HashMap<>();
|
||||
|
||||
protected Map<String, JsonObject> lifecycleExtensions = new HashMap<>();
|
||||
|
||||
protected Object lifecycleExtensionsLock = new Object();
|
||||
|
||||
public InstructionsHelper(JsonObject lifecycles) {
|
||||
super();
|
||||
this.lifecyclesOrigin = lifecycles.deepCopy();
|
||||
fillMap(this.lifecyclesOrigin);
|
||||
}
|
||||
|
||||
protected void fillMap(JsonObject origin) {
|
||||
for (Entry<String, JsonElement> entry : origin.entrySet())
|
||||
if (entry.getValue().isJsonObject())
|
||||
this.lifecycles.put(entry.getKey(), entry.getValue().getAsJsonObject().deepCopy());
|
||||
}
|
||||
|
||||
public String prepareInstructions(String originalInstructions) {
|
||||
JsonObject origin = JSONUtils.getJsonRootObject(originalInstructions);
|
||||
JsonObject result = new JsonObject();
|
||||
if (origin.has(LIFECYCLE_DIRECTIVE)) {
|
||||
JsonElement directiveValue = origin.get(LIFECYCLE_DIRECTIVE);
|
||||
List<String> lcIdToApply = new ArrayList<>();
|
||||
List<JsonObject> lcToApply = new ArrayList<>();
|
||||
if (directiveValue.isJsonPrimitive())
|
||||
lcIdToApply.add(directiveValue.getAsString());
|
||||
if (directiveValue.isJsonArray()) {
|
||||
JsonArray ja = directiveValue.getAsJsonArray();
|
||||
for (int i = 0; i < ja.size(); i++)
|
||||
lcIdToApply.add(ja.get(i).getAsString());
|
||||
}
|
||||
origin.remove(LIFECYCLE_DIRECTIVE);
|
||||
for (String id : lcIdToApply)
|
||||
if (this.lifecycles.containsKey(id)) {
|
||||
EntaxyFactoryUtils.processObjectOverriding(
|
||||
result, this.lifecycles.get(id), OVERRIDE_MODE.UPDATE);
|
||||
synchronized (lifecycleExtensionsLock) {
|
||||
if (lifecycleExtensions.containsKey(id))
|
||||
EntaxyFactoryUtils.processObjectOverriding(result, this.lifecycleExtensions.get(id),
|
||||
OVERRIDE_MODE.UPDATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
EntaxyFactoryUtils.processObjectOverriding(
|
||||
result, origin, OVERRIDE_MODE.UPDATE);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public void setLifecycleExtensions(Map<String, Map<String, Map<String, Object>>> lcExtensions) {
|
||||
synchronized (lifecycleExtensionsLock) {
|
||||
this.lifecycleExtensions = new HashMap<>();
|
||||
for (String lc : lcExtensions.keySet()) {
|
||||
Map<String, Map<String, Object>> lcContent = lcExtensions.get(lc);
|
||||
|
||||
JsonObject jo =
|
||||
lcContent == null ? new JsonObject() : JSONUtils.GSON.toJsonTree(lcContent).getAsJsonObject();
|
||||
|
||||
this.lifecycleExtensions.put(lc, jo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -44,259 +44,275 @@ import ru.entaxy.platform.base.objects.factory.EntaxyFactoryUtils;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyWrappedFactory;
|
||||
|
||||
public class DefaultFactoryWrapper extends AbstractFactoryWrapper implements EntaxyWrappedFactory {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DefaultFactoryWrapper.class);
|
||||
|
||||
public static final String ANY_OUTPUT_TYPE = "__all";
|
||||
|
||||
protected EntaxyFactory origin;
|
||||
|
||||
// outputType -> extrafields map
|
||||
protected Map<String, Map<String, FieldInfo>> extraFields = new HashMap<>();
|
||||
|
||||
protected Map<String, List<FieldInfo>> wrappedFieldsCache = new HashMap<>();
|
||||
|
||||
public DefaultFactoryWrapper(EntaxyFactory origin) {
|
||||
super(origin);
|
||||
this.origin = origin;
|
||||
}
|
||||
private static final Logger log = LoggerFactory.getLogger(DefaultFactoryWrapper.class);
|
||||
|
||||
@Override
|
||||
public void addField(String outputType, FieldInfo fieldInfo) {
|
||||
if (!extraFields.containsKey(outputType))
|
||||
extraFields.put(outputType, new HashMap<>());
|
||||
this.extraFields.get(outputType).put(fieldInfo.getName(), fieldInfo);
|
||||
clearCache();
|
||||
}
|
||||
public static final String ANY_OUTPUT_TYPE = "__all";
|
||||
|
||||
@Override
|
||||
public void addField(FieldInfo fieldInfo) {
|
||||
this.addField(ANY_OUTPUT_TYPE, fieldInfo);
|
||||
clearCache();
|
||||
}
|
||||
|
||||
protected void clearCache() {
|
||||
synchronized (wrappedFieldsCache) {
|
||||
wrappedFieldsCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return origin.getId();
|
||||
}
|
||||
protected EntaxyFactory origin;
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return origin.getType();
|
||||
}
|
||||
// outputType -> extrafields map
|
||||
protected Map<String, Map<String, FieldInfo>> extraFields = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return origin.getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return origin.getDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCategory() {
|
||||
return origin.getCategory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return origin.getLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OutputInfo> getOutputs() {
|
||||
return origin.getOutputs();
|
||||
}
|
||||
protected Map<String, List<FieldInfo>> wrappedFieldsCache = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public OutputInfo getDefaultOutput() {
|
||||
return origin.getDefaultOutput();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputInfo getOutputByType(String outputType) {
|
||||
return origin.getOutputByType(outputType);
|
||||
}
|
||||
public DefaultFactoryWrapper(EntaxyFactory origin) {
|
||||
super(origin);
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FieldInfo> getFields() {
|
||||
return getFields(getDefaultOutput().getType());
|
||||
}
|
||||
@Override
|
||||
public void addField(String outputType, FieldInfo fieldInfo) {
|
||||
if (!extraFields.containsKey(outputType))
|
||||
extraFields.put(outputType, new HashMap<>());
|
||||
this.extraFields.get(outputType).put(fieldInfo.getName(), fieldInfo);
|
||||
clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FieldInfo> getFields(String outputType) {
|
||||
if (!wrappedFieldsCache.containsKey(outputType))
|
||||
wrapFields(outputType);
|
||||
return wrappedFieldsCache.get(outputType);
|
||||
}
|
||||
|
||||
protected void wrapFields(String outputType) {
|
||||
List<FieldInfo> result = new ArrayList<>();
|
||||
if (origin.getOutputByType(outputType) != null) {
|
||||
@Override
|
||||
public void addField(FieldInfo fieldInfo) {
|
||||
this.addField(ANY_OUTPUT_TYPE, fieldInfo);
|
||||
clearCache();
|
||||
}
|
||||
|
||||
Map<String, FieldInfo> extras = new HashMap<>();
|
||||
if (extraFields.containsKey(ANY_OUTPUT_TYPE))
|
||||
extras.putAll(extraFields.get(ANY_OUTPUT_TYPE));
|
||||
if (extraFields.containsKey(outputType))
|
||||
extras.putAll(extraFields.get(outputType));
|
||||
result.addAll(extras.values());
|
||||
result.addAll(origin.getFields(outputType));
|
||||
|
||||
}
|
||||
List<FieldInfo> wrappers = new LinkedList<>();
|
||||
for (FieldInfo fi: result) {
|
||||
if (fi.isRef())
|
||||
wrappers.add(new RefFieldWrapper((RefFieldInfo)fi));
|
||||
else
|
||||
wrappers.add(new FieldWrapper(fi));
|
||||
}
|
||||
wrappedFieldsCache.put(outputType, wrappers);
|
||||
}
|
||||
|
||||
protected Map<String, Object> wrapParameters(Map<String, Object> parameters){
|
||||
Map<String, Object> result = new HashMap<>(parameters);
|
||||
Map<String, Object> properties = new HashMap<>(parameters);
|
||||
result.put("allProperties", properties);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generated generate(Map<String, Object> parameters) throws EntaxyFactoryException {
|
||||
/* if (generationProcessor != null)
|
||||
generationProcessor.preGenerate(this, null, null, getFactoryType(), parameters);
|
||||
Generated g = origin.generate(wrapParameters(parameters));
|
||||
if (generationProcessor != null)
|
||||
generationProcessor.postGenerate(this, null, null, getFactoryType(), parameters, g);
|
||||
return g;
|
||||
*/
|
||||
return generate(null, parameters);
|
||||
}
|
||||
protected void clearCache() {
|
||||
synchronized (wrappedFieldsCache) {
|
||||
wrappedFieldsCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generated generate(String outputType, Map<String, Object> parameters) throws EntaxyFactoryException {
|
||||
/* if (generationProcessor != null)
|
||||
generationProcessor.preGenerate(this, outputType, null, getFactoryType(), parameters);
|
||||
Generated g = origin.generate(outputType, wrapParameters(parameters));
|
||||
if (generationProcessor != null)
|
||||
generationProcessor.postGenerate(this, outputType, null, getFactoryType(), parameters, g);
|
||||
return g;
|
||||
*/
|
||||
return generate(outputType, null, parameters);
|
||||
}
|
||||
@Override
|
||||
public String getId() {
|
||||
return origin.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generated generate(String outputType, String scope, Map<String, Object> parameters)
|
||||
throws EntaxyFactoryException {
|
||||
log.debug("generate :: processor is [{}]", (generationProcessor==null?"":"NOT ")+"null");
|
||||
if (generationProcessor != null)
|
||||
generationProcessor.preGenerate(this, outputType, scope, getFactoryType(), parameters);
|
||||
preGenerateWithPlugins(outputType, scope, parameters);
|
||||
Generated g = origin.generate(outputType, scope, wrapParameters(parameters));
|
||||
postGenerateWithPlugins(outputType, scope, parameters, g);
|
||||
if (generationProcessor != null)
|
||||
generationProcessor.postGenerate(this, outputType, scope, getFactoryType(), parameters, g);
|
||||
return g;
|
||||
}
|
||||
@Override
|
||||
public String getType() {
|
||||
return origin.getType();
|
||||
}
|
||||
|
||||
protected void preGenerateWithPlugins(String outputType, String scope, Map<String, Object> parameters) {
|
||||
|
||||
BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
|
||||
try {
|
||||
List<ServiceReference<GenerationProcessor>> refs = /*bundleContext.getAllServiceReferences(
|
||||
GenerationProcessor.class.getName()
|
||||
, "(|(generation.factory.type~=*)(generation.factory.type~=" + getFactoryType() + "))");*/
|
||||
GenerationProcessorService.getInstance().getProcessorsRefs(this);
|
||||
|
||||
log.debug("FOUND SERVICES: " + (refs==null?"0":refs.size()));
|
||||
if (refs == null)
|
||||
return;
|
||||
for (ServiceReference<GenerationProcessor> r: refs) {
|
||||
try {
|
||||
GenerationProcessor processor = (GenerationProcessor)bundleContext.getService(r);
|
||||
processor.preGenerate(this, outputType, scope, getFactoryType(), parameters);
|
||||
} catch (Exception e) {
|
||||
|
||||
} finally {
|
||||
try {
|
||||
bundleContext.ungetService(r);
|
||||
} catch (Exception e) {
|
||||
log.warn("Error ungetting service", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Error getting services", e);
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public String getShortName() {
|
||||
return origin.getShortName();
|
||||
}
|
||||
|
||||
protected void postGenerateWithPlugins(String outputType, String scope, Map<String, Object> parameters, Generated generated) {
|
||||
BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
|
||||
try {
|
||||
List<ServiceReference<GenerationProcessor>> refs = /* bundleContext.getAllServiceReferences(
|
||||
GenerationProcessor.class.getName()
|
||||
, "(|(generation.factory.type~=*)(generation.factory.type~=" + getFactoryType() + "))"); */
|
||||
GenerationProcessorService.getInstance().getProcessorsRefs(this);
|
||||
|
||||
log.debug("FOUND SERVICES: " + (refs==null?"0":refs.size()));
|
||||
if (refs == null)
|
||||
return;
|
||||
for (ServiceReference<GenerationProcessor> r: refs) {
|
||||
try {
|
||||
GenerationProcessor processor = (GenerationProcessor)bundleContext.getService(r);
|
||||
processor.postGenerate(this, outputType, scope, getFactoryType(), parameters, generated);
|
||||
} catch (Exception e) {
|
||||
|
||||
} finally {
|
||||
try {
|
||||
bundleContext.ungetService(r);
|
||||
} catch (Exception e) {
|
||||
log.warn("Error ungetting service", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Error getting services", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntaxyFactory getOrigin() {
|
||||
return this.origin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getTypeInfo() {
|
||||
return this.origin.getTypeInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJsonConfiguration() {
|
||||
return EntaxyFactoryUtils.getEffectiveJson(this);
|
||||
}
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return origin.getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParent() {
|
||||
return this.origin.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return this.origin.isAbstract();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeprecated() {
|
||||
return this.origin.isDeprecated();
|
||||
}
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return origin.getDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCategory() {
|
||||
return origin.getCategory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return origin.getLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OutputInfo> getOutputs() {
|
||||
return origin.getOutputs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputInfo getDefaultOutput() {
|
||||
return origin.getDefaultOutput();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputInfo getOutputByType(String outputType) {
|
||||
return origin.getOutputByType(outputType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FieldInfo> getFields() {
|
||||
return getFields(getDefaultOutput().getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FieldInfo> getFields(String outputType) {
|
||||
if (!wrappedFieldsCache.containsKey(outputType))
|
||||
wrapFields(outputType);
|
||||
return wrappedFieldsCache.get(outputType);
|
||||
}
|
||||
|
||||
protected void wrapFields(String outputType) {
|
||||
List<FieldInfo> result = new ArrayList<>();
|
||||
if (origin.getOutputByType(outputType) != null) {
|
||||
|
||||
Map<String, FieldInfo> extras = new HashMap<>();
|
||||
if (extraFields.containsKey(ANY_OUTPUT_TYPE))
|
||||
extras.putAll(extraFields.get(ANY_OUTPUT_TYPE));
|
||||
if (extraFields.containsKey(outputType))
|
||||
extras.putAll(extraFields.get(outputType));
|
||||
result.addAll(extras.values());
|
||||
result.addAll(origin.getFields(outputType));
|
||||
|
||||
}
|
||||
List<FieldInfo> wrappers = new LinkedList<>();
|
||||
for (FieldInfo fi : result) {
|
||||
if (fi.isRef())
|
||||
wrappers.add(new RefFieldWrapper((RefFieldInfo) fi));
|
||||
else
|
||||
wrappers.add(new FieldWrapper(fi));
|
||||
}
|
||||
wrappedFieldsCache.put(outputType, wrappers);
|
||||
}
|
||||
|
||||
protected Map<String, Object> wrapParameters(Map<String, Object> parameters) {
|
||||
Map<String, Object> result = new HashMap<>(parameters);
|
||||
Map<String, Object> properties = new HashMap<>(parameters);
|
||||
result.put("allProperties", properties);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generated generate(Map<String, Object> parameters) throws EntaxyFactoryException {
|
||||
/* if (generationProcessor != null)
|
||||
generationProcessor.preGenerate(this, null, null, getFactoryType(), parameters);
|
||||
Generated g = origin.generate(wrapParameters(parameters));
|
||||
if (generationProcessor != null)
|
||||
generationProcessor.postGenerate(this, null, null, getFactoryType(), parameters, g);
|
||||
return g;
|
||||
*/
|
||||
return generate(null, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generated generate(String outputType, Map<String, Object> parameters) throws EntaxyFactoryException {
|
||||
/* if (generationProcessor != null)
|
||||
generationProcessor.preGenerate(this, outputType, null, getFactoryType(), parameters);
|
||||
Generated g = origin.generate(outputType, wrapParameters(parameters));
|
||||
if (generationProcessor != null)
|
||||
generationProcessor.postGenerate(this, outputType, null, getFactoryType(), parameters, g);
|
||||
return g;
|
||||
*/
|
||||
return generate(outputType, null, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generated generate(String outputType, String scope, Map<String, Object> parameters)
|
||||
throws EntaxyFactoryException {
|
||||
log.debug("generate :: processor is [{}]", (generationProcessor == null ? "" : "NOT ") + "null");
|
||||
if (generationProcessor != null)
|
||||
generationProcessor.preGenerate(this, outputType, scope, getFactoryType(), parameters);
|
||||
preGenerateWithPlugins(outputType, scope, parameters);
|
||||
Generated g = origin.generate(outputType, scope, wrapParameters(parameters));
|
||||
postGenerateWithPlugins(outputType, scope, parameters, g);
|
||||
if (generationProcessor != null)
|
||||
generationProcessor.postGenerate(this, outputType, scope, getFactoryType(), parameters, g);
|
||||
return g;
|
||||
}
|
||||
|
||||
protected void preGenerateWithPlugins(String outputType, String scope, Map<String, Object> parameters) {
|
||||
|
||||
BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
|
||||
try {
|
||||
List<ServiceReference<GenerationProcessor>> refs = /*bundleContext.getAllServiceReferences(
|
||||
GenerationProcessor.class.getName()
|
||||
, "(|(generation.factory.type~=*)(generation.factory.type~=" + getFactoryType() + "))");*/
|
||||
GenerationProcessorService.getInstance().getProcessorsRefs(this);
|
||||
|
||||
log.debug("FOUND SERVICES: " + (refs == null ? "0" : refs.size()));
|
||||
if (refs == null)
|
||||
return;
|
||||
for (ServiceReference<GenerationProcessor> r : refs) {
|
||||
try {
|
||||
GenerationProcessor processor = (GenerationProcessor) bundleContext.getService(r);
|
||||
processor.preGenerate(this, outputType, scope, getFactoryType(), parameters);
|
||||
} catch (Exception e) {
|
||||
|
||||
} finally {
|
||||
try {
|
||||
bundleContext.ungetService(r);
|
||||
} catch (Exception e) {
|
||||
log.warn("Error ungetting service", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Error getting services", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void postGenerateWithPlugins(String outputType, String scope, Map<String, Object> parameters,
|
||||
Generated generated) {
|
||||
BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
|
||||
try {
|
||||
List<ServiceReference<GenerationProcessor>> refs = /* bundleContext.getAllServiceReferences(
|
||||
GenerationProcessor.class.getName()
|
||||
, "(|(generation.factory.type~=*)(generation.factory.type~=" + getFactoryType() + "))"); */
|
||||
GenerationProcessorService.getInstance().getProcessorsRefs(this);
|
||||
|
||||
log.debug("FOUND SERVICES: " + (refs == null ? "0" : refs.size()));
|
||||
if (refs == null)
|
||||
return;
|
||||
for (ServiceReference<GenerationProcessor> r : refs) {
|
||||
try {
|
||||
GenerationProcessor processor = (GenerationProcessor) bundleContext.getService(r);
|
||||
processor.postGenerate(this, outputType, scope, getFactoryType(), parameters, generated);
|
||||
} catch (Exception e) {
|
||||
|
||||
} finally {
|
||||
try {
|
||||
bundleContext.ungetService(r);
|
||||
} catch (Exception e) {
|
||||
log.warn("Error ungetting service", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Error getting services", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntaxyFactory getOrigin() {
|
||||
return this.origin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getTypeInfo() {
|
||||
return this.origin.getTypeInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJsonConfiguration() {
|
||||
return EntaxyFactoryUtils.getEffectiveJson(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJsonOrigin() {
|
||||
return this.origin.getJsonOrigin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParent() {
|
||||
return this.origin.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return this.origin.isAbstract();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return this.origin.isInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeprecated() {
|
||||
return this.origin.isDeprecated();
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* test-producers
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -4,27 +4,72 @@
|
||||
},
|
||||
"fragment": {
|
||||
"isTransparent": true
|
||||
},
|
||||
},
|
||||
"bean": {
|
||||
"targetNodeName": "##root",
|
||||
"position": "inside_first",
|
||||
"unique": ["id"],
|
||||
"conflict": "ignore" /*[ignore, replace]*/
|
||||
},
|
||||
"reference": {
|
||||
"targetNodeName": "##root",
|
||||
"position": "inside_first",
|
||||
"unique": ["id"],
|
||||
"conflict": "ignore" /*[ignore, replace]*/
|
||||
},
|
||||
"globalOptions": {
|
||||
"targetNodeName": "camelContext",
|
||||
"position": "inside_first",
|
||||
"conflict": "ignore" /*[ignore, replace]*/
|
||||
},
|
||||
"globalOption": {
|
||||
"targetNodeName": "camelContext/globalOptions",
|
||||
"position": "inside_last",
|
||||
"createTargetNode": true,
|
||||
"targetNodeXML": "<globalOptions />",
|
||||
"unique": ["key"],
|
||||
"conflict": "replace" /*[ignore, replace]*/
|
||||
},
|
||||
"propertyPlaceholder": {
|
||||
"recoursive": true,
|
||||
"targetNodeName": "camelContext/globalOptions",
|
||||
"position": "after",
|
||||
"createTargetNode": true,
|
||||
"targetNodeXML": "<globalOptions><globalOption key=\"entaxyContext\" value=\"true\"/></globalOptions>",
|
||||
"unique": ["id"],
|
||||
"conflict": "ignore" /*[ignore, replace]*/
|
||||
},
|
||||
"propertiesFunction": {
|
||||
"targetNodeName": "camelContext/propertyPlaceholder",
|
||||
"unique": ["ref"],
|
||||
"createTargetNode": true,
|
||||
"targetNodeXML": "<propertyPlaceholder id=\"propertiesForCamel\" xmlns=\"http://camel.apache.org/schema/blueprint\" />"
|
||||
},
|
||||
"errorHandler": {
|
||||
"targetNodeName": "camelContext/propertyPlaceholder",
|
||||
"position": "after",
|
||||
"conflict": "ignore" /*[ignore, replace]*/,
|
||||
"createTargetNode": true,
|
||||
"targetNodeXML": "<propertyPlaceholder id=\"propertiesForCamel\" xmlns=\"http://camel.apache.org/schema/blueprint\" />"
|
||||
},
|
||||
"redeliveryPolicyProfile": {
|
||||
"targetNodeName": "camelContext/errorHandler",
|
||||
"position": "after",
|
||||
"conflict": "ignore" /*[ignore, replace]*/,
|
||||
"createTargetNode": true,
|
||||
"targetNodeXML": "<errorHandler />"
|
||||
},
|
||||
"errorHandlerRef": {
|
||||
"targetNodeName": "camelContext",
|
||||
"targetAttributeName": "errorHandlerRef",
|
||||
"createTargetNode": true,
|
||||
"targetNodeXML": "<camelContext xmlns=\"http://camel.apache.org/schema/blueprint\" />"
|
||||
},
|
||||
"route": {
|
||||
"recoursive": true,
|
||||
"targetNodeName": "camelContext",
|
||||
"position": "inside_last",
|
||||
"createTargetNode": true,
|
||||
"targetNodeXML": "<camelContext xmlns=\"http://camel.apache.org/schema/blueprint\" />"
|
||||
},
|
||||
"propertyPlaceholder": {
|
||||
"recoursive": true,
|
||||
"targetNodeName": "camelContext",
|
||||
"unique": ["id"],
|
||||
"conflict": "ignore" /*[ignore, replace]*/
|
||||
},
|
||||
"propertiesFunction": {
|
||||
"targetNodeName": "camelContext/propertyPlaceholder"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
|
||||
<artifactId>object-producing</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<version>1.10.0</version>
|
||||
</parent>
|
||||
<groupId>ru.entaxy.esb.platform.runtime.core.object-producing</groupId>
|
||||
<artifactId>object-producing-config-support</artifactId>
|
||||
@ -15,14 +15,33 @@
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.karaf.config</groupId>
|
||||
<artifactId>org.apache.karaf.config.core</artifactId>
|
||||
<version>${karaf.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>org.apache.felix.configadmin</artifactId>
|
||||
<version>${felix.configadmin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>
|
||||
ru.entaxy.esb.platform.runtime.core.object-producing
|
||||
</groupId>
|
||||
<artifactId>object-producer-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>bundle</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
|
||||
<artifactId>object-runtime-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.entaxy.esb.platform.runtime.core.objects-implementations.config-implementation</groupId>
|
||||
<artifactId>config-runtime</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@ -37,6 +56,7 @@
|
||||
<instructions>
|
||||
<Entaxy-Factory-Provider>true</Entaxy-Factory-Provider>
|
||||
<Entaxy-Template-Provider>true</Entaxy-Template-Provider>
|
||||
<Entaxy-Extensions-Provider>true</Entaxy-Extensions-Provider>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producing-config-support
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -49,11 +49,13 @@ import ru.entaxy.platform.base.objects.factory.EntaxyFactory.OutputInfo;
|
||||
import ru.entaxy.platform.base.objects.factory.exceptions.FactoryNotFoundException;
|
||||
import ru.entaxy.platform.base.support.CommonUtils;
|
||||
import ru.entaxy.platform.base.support.JSONUtils;
|
||||
import ru.entaxy.platform.config.runtime.ObjectConfig;
|
||||
import ru.entaxy.platform.config.runtime.ObjectConfigHelper;
|
||||
import ru.entaxy.platform.config.runtime.ObjectConfig.FactoryOutputConfiguration;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
|
||||
import ru.entaxy.platform.core.producer.api.ExecutionPlan.ExecutionPlanUpdate;
|
||||
import ru.entaxy.platform.core.producer.api.ProducerResult;
|
||||
import ru.entaxy.platform.core.producer.api.ProducerResult.CommandResult;
|
||||
import ru.entaxy.platform.core.producer.config.ObjectConfig.FactoryOutputConfiguration;
|
||||
import ru.entaxy.platform.core.producer.api.ProducingCommandExecutor;
|
||||
import ru.entaxy.platform.core.producer.executor.AbstractCommandExecutor;
|
||||
import ru.entaxy.platform.core.producer.executor.CommandExecutor;
|
||||
@ -66,223 +68,251 @@ import ru.entaxy.platform.core.producer.executor.objectmodel.ObjectModel;
|
||||
@CommandExecutor(id = "add-config", predecessors = {"enrich"}, descendants = {"validate"})
|
||||
public class AddConfigCommand extends AbstractCommandExecutor implements ProducingCommandExecutor {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AddConfigCommand.class);
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.MANDATORY)
|
||||
EntaxyProducerService entaxyProducerServiceLocal;
|
||||
|
||||
public AddConfigCommand() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
protected AddConfigCommand(EntaxyProducerService entaxyProducerService) {
|
||||
super(entaxyProducerService);
|
||||
}
|
||||
private static final Logger log = LoggerFactory.getLogger(AddConfigCommand.class);
|
||||
|
||||
@Activate
|
||||
public void activate(ComponentContext componentContext) {
|
||||
this.entaxyProducerService = this.entaxyProducerServiceLocal;
|
||||
this.entaxyProducerService.registerCommand(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doExecute(ProducerResult currentResult, CommandResult commandResult,
|
||||
Map<String, Object> instructions) throws Exception {
|
||||
@Reference(cardinality = ReferenceCardinality.MANDATORY)
|
||||
EntaxyProducerService entaxyProducerServiceLocal;
|
||||
|
||||
printOutput("\n\n\t== ADD-CONFIG == \n\n");
|
||||
|
||||
ObjectModel objectModel = currentResult.findResultObject(ObjectModel.class);
|
||||
objectModel.startTracking();
|
||||
|
||||
JsonObject incomingJson = objectModel.getJsonCurrent().deepCopy();
|
||||
|
||||
for (FactoredObject fo: objectModel.objects) {
|
||||
|
||||
// skip proxies
|
||||
if (fo instanceof FactoredObjectProxy)
|
||||
continue;
|
||||
|
||||
log.debug("OBJECT :: {}/{}", fo.getObjectId(), fo.getObjectType());
|
||||
|
||||
String factoryId = fo.factoryId;
|
||||
|
||||
EntaxyFactory factory = entaxyProducerService.findFactoryById(factoryId);
|
||||
if (factory == null)
|
||||
throw new FactoryNotFoundException(factoryId);
|
||||
public AddConfigCommand() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
String output = fo.getOutputType();
|
||||
log.debug("OUTPUT :: {}", output);
|
||||
|
||||
OutputInfo oi = CommonUtils.isValid(output)?factory.getOutputByType(output):factory.getDefaultOutput();
|
||||
Map<String, Object> config = oi.getConfig();
|
||||
if ((config == null) || (config.isEmpty()))
|
||||
continue;
|
||||
|
||||
String val = config.getOrDefault(ObjectConfig.CONFIGURABLE_ATTRIBUTE_NAME, "false").toString();
|
||||
Boolean configurable = Boolean.valueOf(val);
|
||||
if (!configurable)
|
||||
continue;
|
||||
|
||||
JsonObject objectOrigin = fo.origin;
|
||||
JsonObject objectProperties = objectOrigin.get(FIELDS.PROPERTIES).getAsJsonObject();
|
||||
|
||||
if (objectProperties.has(ObjectConfig.CONFIG_FIELD_NAME))
|
||||
continue;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
Generated g = this.entaxyProducerService.findFactoryById("common-config")
|
||||
.generate("config-field"
|
||||
, "private", new HashMap<String, Object>(){{
|
||||
put(FIELDS.FACTORY_ID, "common-config");
|
||||
put(ObjectConfig.TARGET_FACTORY_FIELD_NAME, fo.factoryId);
|
||||
put(ObjectConfig.TARGET_TYPE_FIELD_NAME, fo.getObjectType());
|
||||
put(ObjectConfig.TARGET_ID_FIELD_NAME, fo.getObjectId());
|
||||
put(ObjectConfig.TARGET_OUTPUT_FIELD_NAME, fo.getOutputType());
|
||||
}});
|
||||
|
||||
objectProperties.add(ObjectConfig.CONFIG_FIELD_NAME, JSONUtils.getJsonRootObject(g.getObject().toString()));
|
||||
objectModel.setDirty();
|
||||
|
||||
}
|
||||
|
||||
for (FactoredObjectRef ref: objectModel.refs) {
|
||||
// process external refs and replace ref to object with ref to config if
|
||||
// - ref is not marked 'directValueOnly'
|
||||
// - the referenced object has config
|
||||
// - the referenced field is configurable
|
||||
|
||||
// if (!ref.isExternal())
|
||||
// continue;
|
||||
protected AddConfigCommand(EntaxyProducerService entaxyProducerService) {
|
||||
super(entaxyProducerService);
|
||||
}
|
||||
|
||||
log.debug("REF :: " + ref.relativePath);
|
||||
|
||||
if (ObjectConfigHelper.getInstance().isDirectValueOnly(ref))
|
||||
continue;
|
||||
|
||||
String objectId = ref.getTargetId();
|
||||
String objectType = ref.getTargetType();
|
||||
@Activate
|
||||
public void activate(ComponentContext componentContext) {
|
||||
this.entaxyProducerService = this.entaxyProducerServiceLocal;
|
||||
this.entaxyProducerService.registerCommand(this);
|
||||
}
|
||||
|
||||
log.debug("TO :: " + objectId + ":" + objectType);
|
||||
log.debug("DEFINED IN :: " + ref.definedIn.getObjectId());
|
||||
|
||||
String refField = ref.getOrDefault(FIELDS.REF_FIELD, FIELDS.OBJECT_ID).toString();
|
||||
if (FIELDS.OBJECT_ID.equals(refField))
|
||||
// objectId can't be configured
|
||||
continue;
|
||||
|
||||
// skip if it's already config
|
||||
if (ObjectConfig.CONFIG_OBJECT_TYPE.equals(objectType))
|
||||
continue;
|
||||
@Override
|
||||
protected boolean doExecute(ProducerResult currentResult, CommandResult commandResult,
|
||||
Map<String, Object> instructions) throws Exception {
|
||||
|
||||
String configurationPid = ObjectConfig.getConfigurationPid(objectId, objectType);
|
||||
|
||||
String factoryId = null;
|
||||
printOutput("\n\n\t== ADD-CONFIG == \n\n");
|
||||
|
||||
JsonElement newTargetId = null;
|
||||
|
||||
if (ref.isExternal()) {
|
||||
|
||||
EntaxyObject theObject = ObjectConfigHelper.getInstance().findObject(objectId, objectType);
|
||||
if (theObject == null)
|
||||
// referenced object not found
|
||||
continue;
|
||||
|
||||
factoryId = theObject.getFactoryId();
|
||||
|
||||
EntaxyObject configObject = ObjectConfigHelper.getInstance()
|
||||
.findObject(configurationPid, ObjectConfig.CONFIG_OBJECT_TYPE);
|
||||
if (configObject == null)
|
||||
// config for referenced object not found
|
||||
continue;
|
||||
|
||||
newTargetId = new JsonPrimitive(configurationPid);
|
||||
|
||||
} else {
|
||||
ObjectModel objectModel = currentResult.findResultObject(ObjectModel.class);
|
||||
objectModel.startTracking();
|
||||
|
||||
log.debug("EXTERNAL :: false");
|
||||
|
||||
Optional<FactoredObject> theObjectOpt = objectModel.objects.stream()
|
||||
.filter(obj -> objectId.equals(obj.getObjectId())).findFirst();
|
||||
if (!theObjectOpt.isPresent())
|
||||
continue;
|
||||
|
||||
FactoredObject theObject = theObjectOpt.get();
|
||||
JsonObject incomingJson = objectModel.getJsonCurrent().deepCopy();
|
||||
|
||||
log.debug("TARGET OBJECT :: found");
|
||||
|
||||
factoryId = theObject.factoryId;
|
||||
|
||||
Optional<FactoredObjectRef> configRefOpt = objectModel.refs.stream()
|
||||
.filter(r -> r.definedIn.equals(theObject))
|
||||
.filter(r -> r.relativePath.endsWith(ObjectConfig.CONFIG_FIELD_NAME))
|
||||
.findFirst();
|
||||
|
||||
if (!configRefOpt.isPresent())
|
||||
continue;
|
||||
for (FactoredObject fo : objectModel.objects) {
|
||||
|
||||
log.debug("REF TO CONFIG :: found; TARGET :: " + configRefOpt.get().getTargetId());
|
||||
|
||||
Optional<FactoredObject> configObjectOpt = objectModel.objects.stream()
|
||||
.filter(obj -> obj.getObjectId().equals(configRefOpt.get().getTargetId()))
|
||||
.findFirst();
|
||||
if (!configObjectOpt.isPresent())
|
||||
continue;
|
||||
// skip proxies
|
||||
if (fo instanceof FactoredObjectProxy)
|
||||
continue;
|
||||
|
||||
log.debug("CONFIG OBJECT :: found");
|
||||
|
||||
newTargetId = new JsonPrimitive(configObjectOpt.get().getObjectId());
|
||||
}
|
||||
|
||||
log.debug("OBJECT :: {}/{}", fo.getObjectId(), fo.getObjectType());
|
||||
|
||||
EntaxyFactory entaxyFactory = entaxyProducerService.findFactoryById(factoryId);
|
||||
if (entaxyFactory == null)
|
||||
// factory for referenced object not found
|
||||
continue;
|
||||
|
||||
FactoryOutputConfiguration conf = FactoryOutputConfiguration.read(entaxyFactory, EntaxyFactory.CONFIGURATION.OUTPUTS.OUTPUT_TYPE_INIT);
|
||||
if (!conf.isConfigurable)
|
||||
continue;
|
||||
String factoryId = fo.factoryId;
|
||||
|
||||
|
||||
if (!ObjectConfig.isConfigurable(entaxyFactory
|
||||
, EntaxyFactory.CONFIGURATION.OUTPUTS.OUTPUT_TYPE_INIT, refField
|
||||
, conf.defaultFieldsConfigurable, conf.configurations))
|
||||
// field is not configurable
|
||||
continue;
|
||||
|
||||
JSONUtils.replaceValue(ref.origin, FIELDS.OBJECT_TYPE, new JsonPrimitive(ObjectConfig.CONFIG_OBJECT_TYPE));
|
||||
JSONUtils.replaceValue(ref.origin, FactoredObjectRef.TARGET_TYPE_FIELD, new JsonPrimitive(ObjectConfig.CONFIG_OBJECT_TYPE));
|
||||
JSONUtils.replaceValue(ref.origin, FactoredObjectRef.TARGET_ID_FIELD, newTargetId);
|
||||
EntaxyFactory factory = entaxyProducerService.findFactoryById(factoryId);
|
||||
if (factory == null)
|
||||
throw new FactoryNotFoundException(factoryId);
|
||||
|
||||
// and we must generate ref to config to merge to main object
|
||||
JSONUtils.replaceValue(ref.origin, FIELDS.IS_REF_BY_VALUE_ONLY, new JsonPrimitive(false));
|
||||
|
||||
objectModel.setDirty();
|
||||
String output = fo.getOutputType();
|
||||
log.debug("OUTPUT :: {}", output);
|
||||
|
||||
}
|
||||
|
||||
if (objectModel.stopTracking()) {
|
||||
OutputInfo oi = CommonUtils.isValid(output) ? factory.getOutputByType(output) : factory.getDefaultOutput();
|
||||
Map<String, Object> config = oi.getConfig();
|
||||
if ((config == null) || (config.isEmpty()))
|
||||
continue;
|
||||
|
||||
// remove ##embedded
|
||||
for (FactoredObject fo: objectModel.objects)
|
||||
fo.origin.remove(FactoredObject.EMBEDDED_FIELD);
|
||||
String val = config.getOrDefault(ObjectConfig.CONFIGURABLE_ATTRIBUTE_NAME, "false").toString();
|
||||
Boolean configurable = Boolean.valueOf(val);
|
||||
if (!configurable)
|
||||
continue;
|
||||
|
||||
|
||||
commandResult.planUpdate = ExecutionPlanUpdate.create()
|
||||
// .updateInstructions().target("enrich").value("skip", true).complete()
|
||||
.reset().target("analyze").complete();
|
||||
}
|
||||
|
||||
JsonObject outgoingJson = objectModel.getJsonCurrent();
|
||||
|
||||
printOutput("\n== INCOMING JSON ==\n");
|
||||
printOutput(incomingJson.toString());
|
||||
printOutput("\n== OUTGOING JSON ==\n");
|
||||
printOutput(outgoingJson.toString());
|
||||
|
||||
commandResult.resultObject(outgoingJson);
|
||||
JsonObject objectOrigin = fo.origin;
|
||||
JsonObject objectProperties = objectOrigin.get(FIELDS.PROPERTIES).getAsJsonObject();
|
||||
|
||||
return true;
|
||||
}
|
||||
if (objectProperties.has(ObjectConfig.CONFIG_FIELD_NAME))
|
||||
continue;
|
||||
|
||||
// add config defaults
|
||||
@SuppressWarnings("serial")
|
||||
Generated g = this.entaxyProducerService.findFactoryById("object-config")
|
||||
.generate("config-defaults-field", "private", new HashMap<String, Object>() {
|
||||
{
|
||||
put(FIELDS.FACTORY_ID, "object-config");
|
||||
put(FIELDS.OBJECT_ID, fo.getObjectId() + "-config");
|
||||
put(ObjectConfig.CONFIG_PID_FIELD_NAME,
|
||||
ObjectConfig.getConfigurationPid(fo.getObjectId(), fo.getObjectType()));
|
||||
put(ObjectConfig.TARGET_FACTORY_FIELD_NAME, fo.factoryId);
|
||||
put(ObjectConfig.TARGET_TYPE_FIELD_NAME, fo.getObjectType());
|
||||
put(ObjectConfig.TARGET_ID_FIELD_NAME, fo.getObjectId());
|
||||
put(ObjectConfig.TARGET_OUTPUT_FIELD_NAME, fo.getOutputType());
|
||||
}
|
||||
});
|
||||
|
||||
objectProperties.add(ObjectConfig.CONFIG_DEFAULTS_FIELD_NAME,
|
||||
JSONUtils.getJsonRootObject(g.getObject().toString()));
|
||||
objectModel.setDirty();
|
||||
|
||||
// add config link
|
||||
@SuppressWarnings("serial")
|
||||
Generated g1 = this.entaxyProducerService.findFactoryById("object-config")
|
||||
.generate("config-link-field", "private", new HashMap<String, Object>() {
|
||||
{
|
||||
put(FIELDS.FACTORY_ID, "object-config");
|
||||
put(FIELDS.OBJECT_ID,
|
||||
ObjectConfig.getConfigurationPid(fo.getObjectId(), fo.getObjectType()));
|
||||
put(ObjectConfig.CONFIG_PID_FIELD_NAME,
|
||||
ObjectConfig.getConfigurationPid(fo.getObjectId(), fo.getObjectType()));
|
||||
put(ObjectConfig.TARGET_FACTORY_FIELD_NAME, fo.factoryId);
|
||||
put(ObjectConfig.TARGET_TYPE_FIELD_NAME, fo.getObjectType());
|
||||
put(ObjectConfig.TARGET_ID_FIELD_NAME, fo.getObjectId());
|
||||
put(ObjectConfig.TARGET_OUTPUT_FIELD_NAME, fo.getOutputType());
|
||||
}
|
||||
});
|
||||
|
||||
objectProperties.add(ObjectConfig.CONFIG_LINK_FIELD_NAME,
|
||||
JSONUtils.getJsonRootObject(g1.getObject().toString()));
|
||||
objectModel.setDirty();
|
||||
|
||||
}
|
||||
|
||||
for (FactoredObjectRef ref : objectModel.refs) {
|
||||
// process external refs and replace ref to object with ref to config if
|
||||
// - ref is not marked 'directValueOnly'
|
||||
// - the referenced object has config
|
||||
// - the referenced field is configurable
|
||||
|
||||
// if (!ref.isExternal())
|
||||
// continue;
|
||||
|
||||
log.debug("REF :: " + ref.relativePath);
|
||||
|
||||
if (ObjectConfigHelper.getInstance().isDirectValueOnly(ref))
|
||||
continue;
|
||||
|
||||
String objectId = ref.getTargetId();
|
||||
String objectType = ref.getTargetType();
|
||||
|
||||
log.debug("TO :: " + objectId + ":" + objectType);
|
||||
log.debug("DEFINED IN :: " + ref.definedIn.getObjectId());
|
||||
|
||||
String refField = ref.getOrDefault(FIELDS.REF_FIELD, FIELDS.OBJECT_ID).toString();
|
||||
if (FIELDS.OBJECT_ID.equals(refField))
|
||||
// objectId can't be configured
|
||||
continue;
|
||||
|
||||
// skip if it's already config
|
||||
if (ObjectConfig.CONFIG_OBJECT_TYPE.equals(objectType))
|
||||
continue;
|
||||
|
||||
String configurationPid = ObjectConfig.getConfigurationPid(objectId, objectType);
|
||||
|
||||
String factoryId = null;
|
||||
|
||||
JsonElement newTargetId = null;
|
||||
|
||||
if (ref.isExternal()) {
|
||||
|
||||
EntaxyObject theObject = ObjectConfigHelper.getInstance().findObject(objectId, objectType);
|
||||
if (theObject == null)
|
||||
// referenced object not found
|
||||
continue;
|
||||
|
||||
factoryId = theObject.getFactoryId();
|
||||
|
||||
EntaxyObject configObject = ObjectConfigHelper.getInstance()
|
||||
.findObject(configurationPid, ObjectConfig.CONFIG_OBJECT_TYPE);
|
||||
if (configObject == null)
|
||||
// config for referenced object not found
|
||||
continue;
|
||||
|
||||
newTargetId = new JsonPrimitive(configurationPid);
|
||||
|
||||
} else {
|
||||
|
||||
log.debug("EXTERNAL :: false");
|
||||
|
||||
Optional<FactoredObject> theObjectOpt = objectModel.objects.stream()
|
||||
.filter(obj -> objectId.equals(obj.getObjectId())).findFirst();
|
||||
if (!theObjectOpt.isPresent())
|
||||
continue;
|
||||
|
||||
FactoredObject theObject = theObjectOpt.get();
|
||||
|
||||
log.debug("TARGET OBJECT :: found");
|
||||
|
||||
factoryId = theObject.factoryId;
|
||||
|
||||
Optional<FactoredObjectRef> configRefOpt = objectModel.refs.stream()
|
||||
.filter(r -> r.definedIn.equals(theObject))
|
||||
.filter(r -> r.relativePath.endsWith(ObjectConfig.CONFIG_FIELD_NAME))
|
||||
.findFirst();
|
||||
|
||||
if (!configRefOpt.isPresent())
|
||||
continue;
|
||||
|
||||
log.debug("REF TO CONFIG :: found; TARGET :: " + configRefOpt.get().getTargetId());
|
||||
|
||||
Optional<FactoredObject> configObjectOpt = objectModel.objects.stream()
|
||||
.filter(obj -> obj.getObjectId().equals(configRefOpt.get().getTargetId()))
|
||||
.findFirst();
|
||||
if (!configObjectOpt.isPresent())
|
||||
continue;
|
||||
|
||||
log.debug("CONFIG OBJECT :: found");
|
||||
|
||||
newTargetId = new JsonPrimitive(configObjectOpt.get().getObjectId());
|
||||
}
|
||||
|
||||
|
||||
EntaxyFactory entaxyFactory = entaxyProducerService.findFactoryById(factoryId);
|
||||
if (entaxyFactory == null)
|
||||
// factory for referenced object not found
|
||||
continue;
|
||||
|
||||
FactoryOutputConfiguration conf = FactoryOutputConfiguration.read(entaxyFactory,
|
||||
EntaxyFactory.CONFIGURATION.OUTPUTS.OUTPUT_TYPE_INIT);
|
||||
if (!conf.isConfigurable)
|
||||
continue;
|
||||
|
||||
|
||||
if (!ObjectConfig.isConfigurable(entaxyFactory, EntaxyFactory.CONFIGURATION.OUTPUTS.OUTPUT_TYPE_INIT,
|
||||
refField, conf.defaultFieldsConfigurable, conf.configurations))
|
||||
// field is not configurable
|
||||
continue;
|
||||
|
||||
JSONUtils.replaceValue(ref.origin, FIELDS.OBJECT_TYPE, new JsonPrimitive(ObjectConfig.CONFIG_OBJECT_TYPE));
|
||||
JSONUtils.replaceValue(ref.origin, FactoredObjectRef.TARGET_TYPE_FIELD,
|
||||
new JsonPrimitive(ObjectConfig.CONFIG_OBJECT_TYPE));
|
||||
JSONUtils.replaceValue(ref.origin, FactoredObjectRef.TARGET_ID_FIELD, newTargetId);
|
||||
|
||||
// and we must generate ref to config to merge to main object
|
||||
JSONUtils.replaceValue(ref.origin, FIELDS.IS_REF_BY_VALUE_ONLY, new JsonPrimitive(false));
|
||||
|
||||
objectModel.setDirty();
|
||||
|
||||
}
|
||||
|
||||
if (objectModel.stopTracking()) {
|
||||
|
||||
// remove ##embedded
|
||||
for (FactoredObject fo : objectModel.objects)
|
||||
fo.origin.remove(FactoredObject.EMBEDDED_FIELD);
|
||||
|
||||
|
||||
commandResult.planUpdate = ExecutionPlanUpdate.create()
|
||||
// .updateInstructions().target("enrich").value("skip", true).complete()
|
||||
.reset().target("analyze").complete();
|
||||
}
|
||||
|
||||
JsonObject outgoingJson = objectModel.getJsonCurrent();
|
||||
|
||||
printOutput("\n== INCOMING JSON ==\n");
|
||||
printOutput(incomingJson.toString());
|
||||
printOutput("\n== OUTGOING JSON ==\n");
|
||||
printOutput(outgoingJson.toString());
|
||||
|
||||
commandResult.resultObject(outgoingJson);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producing-config-support
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -32,6 +32,7 @@ import com.google.gson.JsonObject;
|
||||
|
||||
import ru.entaxy.platform.base.objects.EntaxyObject;
|
||||
import ru.entaxy.platform.base.objects.EntaxyObject.FIELDS;
|
||||
import ru.entaxy.platform.config.runtime.ObjectConfig;
|
||||
import ru.entaxy.platform.core.producer.executor.generationmodel.DefaultObjectDataResolver;
|
||||
import ru.entaxy.platform.core.producer.executor.generationmodel.ObjectDataResolver;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producing-config-support
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -25,8 +25,6 @@
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
@ -35,35 +33,32 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import ru.entaxy.esb.platform.runtime.base.connecting.generator.Generated;
|
||||
import ru.entaxy.platform.base.objects.EntaxyObject;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory.OutputInfo;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactoryException;
|
||||
import ru.entaxy.platform.config.runtime.ObjectConfig;
|
||||
import ru.entaxy.platform.config.runtime.ObjectConfig.FactoryOutputConfiguration;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyWrappedFactory;
|
||||
import ru.entaxy.platform.core.producer.config.ObjectConfig.FactoryOutputConfiguration;
|
||||
import ru.entaxy.platform.core.producer.wrapper.AbstractFactoryWrapper.GenerationProcessor;
|
||||
|
||||
@Component (service = GenerationProcessor.class
|
||||
, property = {
|
||||
"generation.plugin.id=config-support"
|
||||
, "generation.factory.type=entaxy.runtime.connection"
|
||||
, "generation.factory.type=entaxy.runtime.profile"
|
||||
}
|
||||
, immediate = true)
|
||||
@Component(service = GenerationProcessor.class, property = {
|
||||
"generation.plugin.id=config-support", "generation.factory.type=entaxy.runtime.*",
|
||||
"generation.factory.type=!entaxy.runtime.config"
|
||||
}, immediate = true)
|
||||
public class ConfigProcessor implements GenerationProcessor {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ConfigProcessor.class);
|
||||
|
||||
@Override
|
||||
public void preGenerate(EntaxyWrappedFactory wrappedFactory, String outputType, String scope, String objectType,
|
||||
Map<String, Object> parameters) throws EntaxyFactoryException {
|
||||
|
||||
if (!parameters.containsKey(EntaxyObject.FIELDS.PROPERTIES))
|
||||
return;
|
||||
private static final Logger log = LoggerFactory.getLogger(ConfigProcessor.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> properties = (Map<String, Object>)parameters.get(EntaxyObject.FIELDS.PROPERTIES);
|
||||
@Override
|
||||
public void preGenerate(EntaxyWrappedFactory wrappedFactory, String outputType, String scope, String objectType,
|
||||
Map<String, Object> parameters) throws EntaxyFactoryException {
|
||||
|
||||
if (!properties.containsKey(ObjectConfig.CONFIG_FIELD_NAME))
|
||||
return;
|
||||
if (!parameters.containsKey(EntaxyObject.FIELDS.PROPERTIES))
|
||||
return;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> properties = (Map<String, Object>) parameters.get(EntaxyObject.FIELDS.PROPERTIES);
|
||||
|
||||
if (!properties.containsKey(ObjectConfig.CONFIG_FIELD_NAME))
|
||||
return;
|
||||
/*
|
||||
OutputInfo oi = wrappedFactory.getOutputByType(outputType);
|
||||
if (oi == null)
|
||||
@ -115,39 +110,40 @@ public class ConfigProcessor implements GenerationProcessor {
|
||||
} else {
|
||||
fieldsConfiguration.add(new ObjectConfig.ConfigurableFieldsConfiguration());
|
||||
}
|
||||
*/
|
||||
FactoryOutputConfiguration conf = FactoryOutputConfiguration.read(wrappedFactory, outputType);
|
||||
if (!conf.isConfigurable)
|
||||
return;
|
||||
|
||||
ObjectConfig.backupProperties(parameters);
|
||||
|
||||
String objectId = parameters.get(EntaxyObject.FIELDS.OBJECT_ID).toString();
|
||||
|
||||
for (Map.Entry<String, Object> entry: properties.entrySet()) {
|
||||
|
||||
if (entry.getKey().startsWith("#"))
|
||||
continue;
|
||||
|
||||
if (!ObjectConfig.isConfigurable(wrappedFactory, outputType, entry.getKey()
|
||||
, conf.defaultFieldsConfigurable, conf.configurations))
|
||||
continue;
|
||||
|
||||
properties.put(entry.getKey(), ObjectConfig.getConfigurationPrefix(objectId, objectType) + entry.getKey() + "}");
|
||||
|
||||
}
|
||||
|
||||
ObjectConfig.removeConfigData(parameters);
|
||||
|
||||
log.debug("preGenerate for {}:{}", wrappedFactory.getId(), wrappedFactory.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postGenerate(EntaxyWrappedFactory wrappedFactory, String outputType, String scope, String objectType,
|
||||
Map<String, Object> parameters, Generated generated) throws EntaxyFactoryException {
|
||||
log.debug("postGenerate for {}:{}", wrappedFactory.getFactoryId(), wrappedFactory.getFactoryType());
|
||||
// restore initial properties
|
||||
ObjectConfig.restoreBackupProperties(parameters);
|
||||
}
|
||||
|
||||
*/
|
||||
FactoryOutputConfiguration conf = FactoryOutputConfiguration.read(wrappedFactory, outputType);
|
||||
if (!conf.isConfigurable)
|
||||
return;
|
||||
|
||||
ObjectConfig.backupProperties(parameters);
|
||||
|
||||
String objectId = parameters.get(EntaxyObject.FIELDS.OBJECT_ID).toString();
|
||||
|
||||
for (Map.Entry<String, Object> entry : properties.entrySet()) {
|
||||
|
||||
if (entry.getKey().startsWith("#"))
|
||||
continue;
|
||||
|
||||
if (!ObjectConfig.isConfigurable(wrappedFactory, outputType, entry.getKey(), conf.defaultFieldsConfigurable,
|
||||
conf.configurations))
|
||||
continue;
|
||||
|
||||
properties.put(entry.getKey(),
|
||||
ObjectConfig.getConfigurationPrefix(objectId, objectType) + entry.getKey() + "}");
|
||||
|
||||
}
|
||||
|
||||
ObjectConfig.removeConfigData(parameters);
|
||||
|
||||
log.debug("preGenerate for {}:{}", wrappedFactory.getId(), wrappedFactory.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postGenerate(EntaxyWrappedFactory wrappedFactory, String outputType, String scope, String objectType,
|
||||
Map<String, Object> parameters, Generated generated) throws EntaxyFactoryException {
|
||||
log.debug("postGenerate for {}:{}", wrappedFactory.getFactoryId(), wrappedFactory.getFactoryType());
|
||||
// restore initial properties
|
||||
ObjectConfig.restoreBackupProperties(parameters);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producing-config-support
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -40,11 +40,16 @@ import org.osgi.service.component.annotations.ReferencePolicyOption;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import ru.entaxy.esb.platform.runtime.base.connecting.generator.Generated;
|
||||
import ru.entaxy.platform.base.objects.EntaxyObject;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactoryException;
|
||||
import ru.entaxy.platform.base.support.CommonUtils;
|
||||
import ru.entaxy.platform.base.support.JSONUtils;
|
||||
import ru.entaxy.platform.config.runtime.ObjectConfig;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyProducer;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyWrappedFactory;
|
||||
@ -54,139 +59,175 @@ import ru.entaxy.platform.core.producer.impl.EntaxyProducerInfo;
|
||||
import ru.entaxy.platform.core.producer.wrapper.AbstractFactoryWrapper;
|
||||
|
||||
@Component(service = EntaxyProducer.class, immediate = true)
|
||||
@EntaxyProducerInfo (supportedTypes = {ObjectConfig.CONFIG_OBJECT_TYPE})
|
||||
@EntaxyProducerInfo(supportedTypes = {ObjectConfig.CONFIG_OBJECT_TYPE})
|
||||
public class ConfigProducer extends CommonObjectProducer implements EntaxyProducer {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ConfigProducer.class);
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.MANDATORY)
|
||||
EntaxyProducerService entaxyProducerService;
|
||||
|
||||
@Reference(bind = "addFactory", unbind = "removeFactory", cardinality = ReferenceCardinality.MULTIPLE
|
||||
, collectionType = CollectionType.SERVICE, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY)
|
||||
public void addFactory(EntaxyFactory factory) {
|
||||
AbstractFactoryWrapper wrapper = super.doAddFactory(factory);
|
||||
if (wrapper != null)
|
||||
wrapper.setGenerationProcessor(this);
|
||||
}
|
||||
|
||||
// WE MUST DECLARE IT for @Reference annotation processor
|
||||
@Override
|
||||
public void removeFactory(EntaxyFactory factory) {
|
||||
super.removeFactory(factory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preGenerate(EntaxyWrappedFactory wrappedFactory, String outputType, String scope, String objectType,
|
||||
Map<String, Object> parameters) throws EntaxyFactoryException {
|
||||
super.preGenerate(wrappedFactory, outputType, scope, objectType, parameters);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> properties = (Map<String, Object>)parameters.get(EntaxyObject.FIELDS.PROPERTIES);
|
||||
private static final Logger log = LoggerFactory.getLogger(ConfigProducer.class);
|
||||
|
||||
// System.out.println("\n\n\tCONFIG PRODUCER :: preGenerate");
|
||||
// System.out.println("\t" + parameters.toString());
|
||||
|
||||
// properties can be null for 'config-field' output
|
||||
if (properties != null) {
|
||||
|
||||
/* System.out.println("\n\n\tGENERATE CONFIG: "
|
||||
+ "\noutput: " + outputType
|
||||
+ "\nscope: " + scope
|
||||
+ "\nproperties: " + properties.toString()); */
|
||||
|
||||
ObjectConfig.backupProperties(parameters, ObjectConfig.CONFIG_PROPERTIES_FIELD_NAME);
|
||||
ObjectConfig.removeConfigData(parameters, ObjectConfig.CONFIG_PROPERTIES_FIELD_NAME);
|
||||
|
||||
Map<String, Object> configurables = new HashMap<>();
|
||||
Map<String, Object> immutables = new HashMap<>();
|
||||
|
||||
String targetFactoryId = properties.get(ObjectConfig.CONFIG_FACTORY_FIELD_NAME).toString();
|
||||
String targetOutput = properties.get(ObjectConfig.CONFIG_OUTPUT_FIELD_NAME).toString();
|
||||
|
||||
EntaxyFactory f = entaxyProducerService.findFactoryById(targetFactoryId);
|
||||
if (!CommonUtils.isValid(targetOutput))
|
||||
targetOutput = f.getDefaultOutput().getType();
|
||||
|
||||
fillConfigMaps(f, targetOutput, scope, objectType, parameters, configurables, immutables);
|
||||
|
||||
parameters.put(ObjectConfig.CONFIGURABLES_FIELD_NAME, configurables);
|
||||
parameters.put(ObjectConfig.IMMUTABLES_FIELD_NAME, immutables);
|
||||
|
||||
String configuredId = parameters.get(ObjectConfig.CONFIG_ID_FIELD_NAME).toString();
|
||||
String configuredType = parameters.get(ObjectConfig.CONFIG_TYPE_FIELD_NAME).toString();
|
||||
|
||||
String configurationPid = ObjectConfig.getConfigurationPid(configuredId, configuredType);
|
||||
String placeholderPrefix = ObjectConfig.getConfigurationPrefix(configuredId, configuredType);
|
||||
|
||||
// set objectId to configurationPid
|
||||
|
||||
parameters.put(EntaxyObject.FIELDS.OBJECT_ID, configurationPid);
|
||||
|
||||
parameters.put(ObjectConfig.CONFIG_PID_FIELD_NAME, configurationPid);
|
||||
parameters.put(ObjectConfig.CONFIG_PLACEHOLDER_PREFIX_FIELD_NAME, placeholderPrefix);
|
||||
protected static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postGenerate(EntaxyWrappedFactory wrappedFactory, String outputType, String scope, String objectType,
|
||||
Map<String, Object> parameters, Generated generated) throws EntaxyFactoryException {
|
||||
super.postGenerate(wrappedFactory, outputType, scope, objectType, parameters, generated);
|
||||
ObjectConfig.restoreBackupProperties(parameters, ObjectConfig.CONFIG_PROPERTIES_FIELD_NAME);
|
||||
protected static final String DIRECTIVE_FILL_CONFIGURABLES = "@FILL_CONFIGURABLES";
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> properties = (Map<String, Object>)parameters.get(EntaxyObject.FIELDS.PROPERTIES);
|
||||
@Reference(cardinality = ReferenceCardinality.MANDATORY)
|
||||
EntaxyProducerService entaxyProducerService;
|
||||
|
||||
// properties can be null for 'config-field' output
|
||||
if (properties != null) {
|
||||
@Reference(bind = "addFactory", unbind = "removeFactory", cardinality = ReferenceCardinality.MULTIPLE,
|
||||
collectionType = CollectionType.SERVICE, policy = ReferencePolicy.DYNAMIC,
|
||||
policyOption = ReferencePolicyOption.GREEDY)
|
||||
public void addFactory(EntaxyFactory factory) {
|
||||
AbstractFactoryWrapper wrapper = super.doAddFactory(factory);
|
||||
if (wrapper != null)
|
||||
wrapper.setGenerationProcessor(this);
|
||||
}
|
||||
|
||||
// WE MUST DECLARE IT for @Reference annotation processor
|
||||
@Override
|
||||
public void removeFactory(EntaxyFactory factory) {
|
||||
super.removeFactory(factory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preGenerate(EntaxyWrappedFactory wrappedFactory, String outputType, String scope, String objectType,
|
||||
Map<String, Object> parameters) throws EntaxyFactoryException {
|
||||
super.preGenerate(wrappedFactory, outputType, scope, objectType, parameters);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> properties = (Map<String, Object>) parameters.get(EntaxyObject.FIELDS.PROPERTIES);
|
||||
|
||||
// System.out.println("\n\n\tCONFIG PRODUCER :: preGenerate");
|
||||
// System.out.println("\t" + parameters.toString());
|
||||
|
||||
// properties can be null for 'config-field' output
|
||||
if (properties != null) {
|
||||
|
||||
/* System.out.println("\n\n\tGENERATE CONFIG: "
|
||||
+ "\noutput: " + outputType
|
||||
+ "\nscope: " + scope
|
||||
+ "\nproperties: " + properties.toString()); */
|
||||
|
||||
ObjectConfig.backupProperties(parameters, ObjectConfig.CONFIG_PROPERTIES_FIELD_NAME);
|
||||
ObjectConfig.removeConfigData(parameters, ObjectConfig.CONFIG_PROPERTIES_FIELD_NAME);
|
||||
|
||||
Map resultMap = properties;
|
||||
|
||||
if (parameters.containsKey(DIRECTIVE_FILL_CONFIGURABLES)) {
|
||||
|
||||
String targetConfigurables = parameters
|
||||
.getOrDefault(DIRECTIVE_FILL_CONFIGURABLES, ObjectConfig.CONFIGURABLES_FIELD_NAME).toString();
|
||||
if (!CommonUtils.isValid(targetConfigurables))
|
||||
targetConfigurables = ObjectConfig.CONFIGURABLES_FIELD_NAME;
|
||||
|
||||
Map<String, Object> configurables = new HashMap<>();
|
||||
Map<String, Object> immutables = new HashMap<>();
|
||||
|
||||
String targetFactoryId = properties.get(ObjectConfig.CONFIG_FACTORY_FIELD_NAME).toString();
|
||||
String targetOutput = properties.get(ObjectConfig.CONFIG_OUTPUT_FIELD_NAME).toString();
|
||||
|
||||
EntaxyFactory f = entaxyProducerService.findFactoryById(targetFactoryId);
|
||||
if (!CommonUtils.isValid(targetOutput))
|
||||
targetOutput = f.getDefaultOutput().getType();
|
||||
|
||||
fillConfigMaps(f, targetOutput, scope, objectType, parameters, configurables, immutables);
|
||||
|
||||
resultMap = configurables;
|
||||
|
||||
if (parameters.containsKey(targetConfigurables)) {
|
||||
Object value = parameters.get(targetConfigurables);
|
||||
if (value instanceof Map) {
|
||||
((Map) value).putAll(configurables);
|
||||
resultMap = (Map) value;
|
||||
} else {
|
||||
parameters.put(targetConfigurables, configurables);
|
||||
}
|
||||
} else {
|
||||
parameters.put(targetConfigurables, configurables);
|
||||
|
||||
}
|
||||
|
||||
parameters.put(ObjectConfig.IMMUTABLES_FIELD_NAME, immutables);
|
||||
|
||||
}
|
||||
|
||||
parameters.put(ObjectConfig.CONFIGURABLES_FIELD_NAME + "_json",
|
||||
JSONUtils.GSON.toJsonTree(resultMap).toString());
|
||||
|
||||
String configuredId = parameters.get(ObjectConfig.CONFIG_ID_FIELD_NAME).toString();
|
||||
String configuredType = parameters.get(ObjectConfig.CONFIG_TYPE_FIELD_NAME).toString();
|
||||
|
||||
String configurationPid = ObjectConfig.getConfigurationPid(configuredId, configuredType);
|
||||
String placeholderPrefix = ObjectConfig.getConfigurationPrefix(configuredId, configuredType);
|
||||
|
||||
// set objectId to configurationPid
|
||||
// if not set before
|
||||
if (!parameters.containsKey(EntaxyObject.FIELDS.OBJECT_ID))
|
||||
parameters.put(EntaxyObject.FIELDS.OBJECT_ID, configurationPid);
|
||||
|
||||
parameters.put(ObjectConfig.CONFIG_PID_FIELD_NAME, configurationPid);
|
||||
parameters.put(ObjectConfig.CONFIG_PLACEHOLDER_PREFIX_FIELD_NAME, placeholderPrefix);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postGenerate(EntaxyWrappedFactory wrappedFactory, String outputType, String scope, String objectType,
|
||||
Map<String, Object> parameters, Generated generated) throws EntaxyFactoryException {
|
||||
super.postGenerate(wrappedFactory, outputType, scope, objectType, parameters, generated);
|
||||
ObjectConfig.restoreBackupProperties(parameters, ObjectConfig.CONFIG_PROPERTIES_FIELD_NAME);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> properties = (Map<String, Object>) parameters.get(EntaxyObject.FIELDS.PROPERTIES);
|
||||
|
||||
// properties can be null for 'config-field' output
|
||||
if (properties != null) {
|
||||
|
||||
// enrich paramaters with configured fields placeholders
|
||||
String placeholderPrefix = parameters.get(ObjectConfig.CONFIG_PLACEHOLDER_PREFIX_FIELD_NAME).toString();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> configuredFields =
|
||||
(Map<String, Object>) parameters.getOrDefault(ObjectConfig.CONFIGURABLES_FIELD_NAME,
|
||||
Collections.emptyMap());
|
||||
// configuredFields.putAll(
|
||||
// (Map<String, Object>) parameters.getOrDefault(ObjectConfig.IMMUTABLES_FIELD_NAME,
|
||||
// Collections.emptyMap()));
|
||||
|
||||
log.debug("CONFIGURED: \n" + configuredFields);
|
||||
|
||||
Map<String, Object> placeholdersMap = configuredFields.entrySet().stream()
|
||||
// .map(entry -> entry.setValue(placeholderPrefix + entry.getKey() + "}"))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, entry -> placeholderPrefix + entry.getKey() + "}"));
|
||||
|
||||
log.debug("\n\n\tPLACEHOLDERS: \n" + placeholdersMap);
|
||||
|
||||
parameters.putAll(placeholdersMap);
|
||||
|
||||
// add headers
|
||||
String configuredId = parameters.get(ObjectConfig.CONFIG_ID_FIELD_NAME).toString();
|
||||
String configuredType = parameters.get(ObjectConfig.CONFIG_TYPE_FIELD_NAME).toString();
|
||||
|
||||
String configurationPid = ObjectConfig.getConfigurationPid(configuredId, configuredType);
|
||||
|
||||
GeneratedHeaders headers = GeneratedHeaders.getHeaders(generated.getProperties());
|
||||
headers.set(ObjectConfig.HEADER_OBJECT_CONFIG_PID,
|
||||
configuredId + ":" + configuredType + ":" + configurationPid);
|
||||
}
|
||||
}
|
||||
|
||||
protected void fillConfigMaps(EntaxyFactory factory, String outputType, String scope, String objectType,
|
||||
Map<String, Object> parameters, Map<String, Object> configurables, Map<String, Object> immutables) {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> properties =
|
||||
(Map<String, Object>) parameters.get(ObjectConfig.CONFIG_PROPERTIES_FIELD_NAME);
|
||||
for (Entry<String, Object> entry : properties.entrySet()) {
|
||||
Map<String, Object> targetMap =
|
||||
ObjectConfig.getTargetConfigMap(factory, outputType, entry.getKey(), configurables, immutables);
|
||||
if (targetMap == null) {
|
||||
continue;
|
||||
}
|
||||
targetMap.put(entry.getKey(), entry.getValue());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// enrich paramaters with configured fields placeholders
|
||||
String placeholderPrefix = parameters.get(ObjectConfig.CONFIG_PLACEHOLDER_PREFIX_FIELD_NAME).toString();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> configuredFields =
|
||||
(Map<String, Object>)parameters.getOrDefault(ObjectConfig.CONFIGURABLES_FIELD_NAME
|
||||
, Collections.emptyMap());
|
||||
configuredFields.putAll(
|
||||
(Map<String, Object>)parameters.getOrDefault(ObjectConfig.IMMUTABLES_FIELD_NAME
|
||||
, Collections.emptyMap())
|
||||
);
|
||||
|
||||
log.debug("CONFIGURED: \n" + configuredFields);
|
||||
|
||||
Map<String, Object> placeholdersMap = configuredFields.entrySet().stream()
|
||||
//.map(entry -> entry.setValue(placeholderPrefix + entry.getKey() + "}"))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, entry -> placeholderPrefix + entry.getKey() + "}"));
|
||||
|
||||
log.debug("\n\n\tPLACEHOLDERS: \n" + placeholdersMap);
|
||||
|
||||
parameters.putAll(placeholdersMap);
|
||||
|
||||
// add headers
|
||||
String configuredId = parameters.get(ObjectConfig.CONFIG_ID_FIELD_NAME).toString();
|
||||
String configuredType = parameters.get(ObjectConfig.CONFIG_TYPE_FIELD_NAME).toString();
|
||||
|
||||
String configurationPid = ObjectConfig.getConfigurationPid(configuredId, configuredType);
|
||||
|
||||
GeneratedHeaders headers = GeneratedHeaders.getHeaders(generated.getProperties());
|
||||
headers.set(ObjectConfig.HEADER_OBJECT_CONFIG_PID, configuredId + ":" + configuredType + ":" + configurationPid);
|
||||
}
|
||||
}
|
||||
|
||||
protected void fillConfigMaps(EntaxyFactory factory, String outputType, String scope, String objectType,
|
||||
Map<String, Object> parameters, Map<String, Object> configurables, Map<String, Object> immutables) {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> properties = (Map<String, Object>)parameters.get(ObjectConfig.CONFIG_PROPERTIES_FIELD_NAME);
|
||||
for (Entry<String, Object> entry: properties.entrySet()) {
|
||||
Map<String, Object> targetMap = ObjectConfig.getTargetConfigMap(factory, outputType, entry.getKey(), configurables, immutables);
|
||||
if (targetMap == null) {
|
||||
continue;
|
||||
}
|
||||
targetMap.put(entry.getKey(), entry.getValue());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,359 +0,0 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producing-config-support
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ru.entaxy.platform.base.objects.EntaxyObject;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory.FieldInfo;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory.OutputInfo;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyProducerUtils;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyWrappedFactory;
|
||||
|
||||
public class ObjectConfig {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ObjectConfig.class);
|
||||
|
||||
public static final String CONFIG_OBJECT_TYPE = "entaxy.runtime.config";
|
||||
|
||||
public static final String TARGET_FACTORY_FIELD_NAME = "targetObjectFactoryId";
|
||||
public static final String TARGET_TYPE_FIELD_NAME = "targetObjectType";
|
||||
public static final String TARGET_ID_FIELD_NAME = "targetObjectId";
|
||||
public static final String TARGET_OUTPUT_FIELD_NAME = "targetObjectOutput";
|
||||
|
||||
public static final String CONFIG_PROPERTIES_FIELD_NAME = "configuredProperties";
|
||||
public static final String CONFIG_FACTORY_FIELD_NAME = "configuredFactoryId";
|
||||
public static final String CONFIG_TYPE_FIELD_NAME = "configuredType";
|
||||
public static final String CONFIG_ID_FIELD_NAME = "configured";
|
||||
public static final String CONFIG_OUTPUT_FIELD_NAME = "configuredOutput";
|
||||
|
||||
public static final String CONFIG_PID_FIELD_NAME = "configurationPid";
|
||||
public static final String CONFIG_PLACEHOLDER_PREFIX_FIELD_NAME = "placeholderPrefix";
|
||||
|
||||
|
||||
public static final String CONFIG_FIELD_NAME = "##config";
|
||||
public static final String CONFIGURABLE_ATTRIBUTE_NAME = "configurable";
|
||||
public static final String DEFAULT_FIELDS_CONFIGURABLE_ATTRIBUTE_NAME = "fieldsConfigurableByDefault";
|
||||
public static final String CONFIGURABLE_FIELDS_ATTRIBUTE_NAME = "configurableFields";
|
||||
public static final String PROPERTIES_BACKUP_FIELD = EntaxyObject.FIELDS.PROPERTIES + "_backup";
|
||||
|
||||
public static final String DIRECT_VALUE_ONLY_ATTR_NAME = "directValueOnly";
|
||||
|
||||
public static final String CONFIGURABLES_FIELD_NAME = "configurables";
|
||||
public static final String IMMUTABLES_FIELD_NAME = "immutables";
|
||||
|
||||
public static final String HEADER_OBJECT_CONFIG_PID = "Entaxy-Generated-Object-Config-Pid";
|
||||
|
||||
protected static Gson GSON = new GsonBuilder().create();
|
||||
|
||||
public static String getConfigurationPid(String objectId, String type) {
|
||||
return reduceType(type) + "." + objectId.replace("-", "_");
|
||||
}
|
||||
|
||||
public static String reduceType(String type) {
|
||||
return type.replace(EntaxyObject.OBJECT_TYPES.ENTAXY_RUNTIME_TYPE_PREFIX, "e_r_").replace("-", "_");
|
||||
}
|
||||
|
||||
public static String getConfigurationPrefix(String objectId, String type) {
|
||||
return "$" + getConfigurationPid(objectId, type) + "{";
|
||||
}
|
||||
|
||||
public static boolean isConfigurable(EntaxyFactory factory, String outputType, String fieldName
|
||||
, boolean defaultFieldsConfigurable, List<ConfigurableFieldsConfiguration> configurations) {
|
||||
Optional<FieldInfo> fi = factory.getOutputByType(outputType).getFields().stream().filter(f -> f.getName().equals(fieldName)).findFirst();
|
||||
if (!fi.isPresent())
|
||||
return false;
|
||||
|
||||
boolean fieldIsConfigurable = defaultFieldsConfigurable;
|
||||
|
||||
try {
|
||||
fieldIsConfigurable = fi.get().getJsonOrigin().get(CONFIGURABLE_ATTRIBUTE_NAME).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
// usinf default value
|
||||
}
|
||||
|
||||
if (!fieldIsConfigurable)
|
||||
return false;
|
||||
|
||||
for (ConfigurableFieldsConfiguration cfc: configurations)
|
||||
if (cfc.isConfigurable(factory, outputType, fieldName))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void backupProperties(Map<String, Object> parameters) {
|
||||
backupProperties(parameters, EntaxyObject.FIELDS.PROPERTIES);
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void backupProperties(Map<String, Object> parameters, String fieldName) {
|
||||
if (!parameters.containsKey(fieldName))
|
||||
return;
|
||||
Map<String, Object> backup = new HashMap<>();
|
||||
backup.putAll((Map<String, Object>)parameters.get(fieldName));
|
||||
parameters.put(ObjectConfig.PROPERTIES_BACKUP_FIELD, backup);
|
||||
}
|
||||
|
||||
public static void restoreBackupProperties(Map<String, Object> parameters) {
|
||||
restoreBackupProperties(parameters, EntaxyObject.FIELDS.PROPERTIES);
|
||||
}
|
||||
public static void restoreBackupProperties(Map<String, Object> parameters, String fieldName) {
|
||||
if (!parameters.containsKey(ObjectConfig.PROPERTIES_BACKUP_FIELD))
|
||||
return;
|
||||
parameters.put(fieldName, parameters.get(ObjectConfig.PROPERTIES_BACKUP_FIELD));
|
||||
}
|
||||
|
||||
public static void removeConfigData(Map<String, Object> parameters) {
|
||||
removeConfigData(parameters, EntaxyObject.FIELDS.PROPERTIES);
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void removeConfigData(Map<String, Object> parameters, String fieldName) {
|
||||
if (!parameters.containsKey(fieldName))
|
||||
return;
|
||||
((Map<String, Object>)parameters.get(fieldName)).remove(CONFIG_FIELD_NAME);
|
||||
}
|
||||
|
||||
public static Map<String, Object> getTargetConfigMap(EntaxyFactory factory, String outputType, String fieldName
|
||||
, Map<String, Object> configurables, Map<String, Object> immutables){
|
||||
/*
|
||||
Optional<FieldInfo> fi = factory.getOutputByType(outputType).getFields().stream().filter(f -> f.getName().equals(fieldName)).findFirst();
|
||||
|
||||
if (!fi.isPresent()) {
|
||||
log.debug("FIELD NOT FOUND: " + fieldName);
|
||||
return null;
|
||||
}
|
||||
FieldInfo field = fi.get();
|
||||
boolean isConfigurable = true;
|
||||
log.debug("\n FIELDNAME:: " + fieldName + " -> " + field.getJsonOrigin());
|
||||
if (field.getJsonOrigin().has(CONFIGURABLE_ATTRIBUTE_NAME))
|
||||
try {
|
||||
isConfigurable = field.getJsonOrigin().get(CONFIGURABLE_ATTRIBUTE_NAME).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
isConfigurable = true;
|
||||
}
|
||||
if (!isConfigurable) {
|
||||
log.debug("FIELD NOT CONFIGURABLE: " + fieldName);
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
Optional<FieldInfo> fi = factory.getOutputByType(outputType).getFields().stream().filter(f -> f.getName().equals(fieldName)).findFirst();
|
||||
|
||||
if (!fi.isPresent()) {
|
||||
log.debug("FIELD NOT FOUND: " + fieldName);
|
||||
return null;
|
||||
}
|
||||
|
||||
FactoryOutputConfiguration conf = FactoryOutputConfiguration.read(factory, outputType);
|
||||
|
||||
if (!isConfigurable(factory, outputType, fieldName, conf.defaultFieldsConfigurable, conf.configurations))
|
||||
return null;
|
||||
|
||||
FieldInfo field = fi.get();
|
||||
|
||||
if (field.isImmutable())
|
||||
return immutables;
|
||||
return configurables;
|
||||
}
|
||||
|
||||
public static class FactoryOutputConfiguration {
|
||||
|
||||
public static FactoryOutputConfiguration read(EntaxyFactory factory, String outputType) {
|
||||
|
||||
FactoryOutputConfiguration result = new FactoryOutputConfiguration();
|
||||
|
||||
OutputInfo oi = factory.getOutputByType(outputType);
|
||||
if (oi == null)
|
||||
oi = factory.getDefaultOutput();
|
||||
|
||||
Map<String, Object> outputConfig = oi.getConfig();
|
||||
|
||||
result.isConfigurable = false;
|
||||
try {
|
||||
result.isConfigurable = (Boolean)outputConfig.get(ObjectConfig.CONFIGURABLE_ATTRIBUTE_NAME);
|
||||
} catch (Exception e) {
|
||||
log.trace("Parameter [{}] not found in [{}]:[{}]"
|
||||
, ObjectConfig.CONFIGURABLE_ATTRIBUTE_NAME
|
||||
, factory.getId()
|
||||
, outputType);
|
||||
}
|
||||
if (!result.isConfigurable)
|
||||
return result;
|
||||
|
||||
result.defaultFieldsConfigurable = false;
|
||||
try {
|
||||
result.defaultFieldsConfigurable = (Boolean)outputConfig.get(ObjectConfig.DEFAULT_FIELDS_CONFIGURABLE_ATTRIBUTE_NAME);
|
||||
} catch (Exception e) {
|
||||
log.trace("Parameter [{}] not found in [{}]:[{}]"
|
||||
, ObjectConfig.DEFAULT_FIELDS_CONFIGURABLE_ATTRIBUTE_NAME
|
||||
, factory.getId()
|
||||
, outputType);
|
||||
}
|
||||
|
||||
result.configurations = new ArrayList<>();
|
||||
|
||||
Object configuration = outputConfig.get(ObjectConfig.CONFIGURABLE_FIELDS_ATTRIBUTE_NAME);
|
||||
if (configuration != null) {
|
||||
if (configuration instanceof List) {
|
||||
List configList = (List)configuration;
|
||||
for (Object configItem: configList) {
|
||||
if (configItem instanceof Map) {
|
||||
ObjectConfig.ConfigurableFieldsConfiguration cnf =
|
||||
ObjectConfig.ConfigurableFieldsConfiguration.read((Map)configItem);
|
||||
result.configurations.add(cnf);
|
||||
}
|
||||
}
|
||||
} else
|
||||
if (configuration instanceof Map) {
|
||||
ObjectConfig.ConfigurableFieldsConfiguration cnf =
|
||||
ObjectConfig.ConfigurableFieldsConfiguration.read((Map)configuration);
|
||||
result.configurations.add(cnf);
|
||||
}
|
||||
} else {
|
||||
result.configurations.add(new ObjectConfig.ConfigurableFieldsConfiguration());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean isConfigurable;
|
||||
boolean defaultFieldsConfigurable;
|
||||
List<ConfigurableFieldsConfiguration> configurations;
|
||||
|
||||
}
|
||||
|
||||
public static class ConfigurableFieldsConfiguration {
|
||||
|
||||
public static ConfigurableFieldsConfiguration read(Map parameters) {
|
||||
JsonElement obj = GSON.toJsonTree(parameters);
|
||||
if (obj.isJsonObject()) {
|
||||
ConfigurableFieldsConfiguration result = GSON.fromJson(obj, ConfigurableFieldsConfiguration.class);
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
List<String> includeNames = new ArrayList<>();
|
||||
List<String> includePatterns = new ArrayList<>();
|
||||
List<String> excludeNames = new ArrayList<>();
|
||||
List<String> excludePatterns = new ArrayList<>();
|
||||
|
||||
List<String> includeTypes = new ArrayList<>();
|
||||
List<String> excludeTypes = new ArrayList<>();
|
||||
|
||||
public ConfigurableFieldsConfiguration() {
|
||||
includeTypes.add("string");
|
||||
includeTypes.add("boolean");
|
||||
includeTypes.add("number");
|
||||
includePatterns.add("*");
|
||||
}
|
||||
|
||||
|
||||
public boolean isConfigurable(EntaxyFactory factory, String outputType, String fieldName) {
|
||||
Optional<FieldInfo> fi = factory.getOutputByType(outputType).getFields().stream().filter(f -> f.getName().equals(fieldName)).findFirst();
|
||||
if (!fi.isPresent())
|
||||
return false;
|
||||
|
||||
String fieldType = fi.get().getType().toLowerCase();
|
||||
|
||||
|
||||
boolean fieldIsExcluded = false;
|
||||
for (String name: excludeNames)
|
||||
if (fieldName.equals(name)) {
|
||||
fieldIsExcluded = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!fieldIsExcluded) {
|
||||
for (String pattern: excludePatterns) {
|
||||
if (Pattern.matches(EntaxyProducerUtils.toRegexPattern(pattern), fieldName)) {
|
||||
fieldIsExcluded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!fieldIsExcluded) {
|
||||
for (String type: excludeTypes)
|
||||
if (type.equals(fieldType)) {
|
||||
fieldIsExcluded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldIsExcluded)
|
||||
return false;
|
||||
|
||||
boolean fieldIsIncluded = false;
|
||||
|
||||
// first we check types
|
||||
if (!fieldIsIncluded) {
|
||||
for (String type: includeTypes)
|
||||
if (type.equals(fieldType)) {
|
||||
fieldIsIncluded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!fieldIsIncluded)
|
||||
return false;
|
||||
|
||||
if (!includeNames.isEmpty() || !includePatterns.isEmpty())
|
||||
fieldIsIncluded = false;
|
||||
|
||||
for (String name: includeNames)
|
||||
if (fieldName.equals(name)) {
|
||||
fieldIsIncluded = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!fieldIsIncluded) {
|
||||
for (String pattern: includePatterns) {
|
||||
if (Pattern.matches(EntaxyProducerUtils.toRegexPattern(pattern), fieldName)) {
|
||||
fieldIsIncluded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fieldIsIncluded;
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user