public code v1

This commit is contained in:
2026-05-22 11:14:29 +02:00
parent 427197ec5a
commit b8141736eb
28859 changed files with 575079 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>
+1
View File
@@ -0,0 +1 @@
/bin/
+39
View File
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>afryca.behavior</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ds.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
line.separator=\n
@@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8
@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
@@ -0,0 +1,29 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: afryca.behavior;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: %Bundle-Vendor
Export-Package: afryca.behavior,
afryca.behavior.command,
afryca.behavior.definition,
afryca.behavior.provider,
afryca.behavior.service,
afryca.behavior.service.events
Require-Bundle: afryca.ase,
afryca.parametervalueconverterhelper,
javax.inject,
org.apache.commons.io,
org.eclipse.core.runtime,
org.eclipse.e4.core.di,
org.eclipse.e4.core.services,
org.eclipse.e4.core.contexts,
org.eclipse.e4.ui.workbench,
org.eclipse.e4.ui.model.workbench,
org.eclipse.ui
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Service-Component: OSGI-INF/behavior_service_context_function.xml,
OSGI-INF/attitude_provider_context_function.xml,
OSGI-INF/behavior_provider_context_function.xml
Bundle-ActivationPolicy: lazy
Automatic-Module-Name: afryca.behavior
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="IAttitudeProvider context function">
<implementation class="afryca.behavior.provider.internal.AttitudeProviderContextFunction"/>
<property
name="service.context.key"
type="String"
value="afryca.behavior.provider.IAttitudeProvider"/>
<service>
<provide
interface="org.eclipse.e4.core.contexts.IContextFunction"/>
</service>
</scr:component>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="IBehaviorProvider context function">
<implementation class="afryca.behavior.provider.internal.BehaviorProviderContextFunction"/>
<property
name="service.context.key"
type="String"
value="afryca.behavior.provider.IBehaviorProvider"/>
<service>
<provide
interface="org.eclipse.e4.core.contexts.IContextFunction"/>
</service>
</scr:component>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="IBehaviorService context function">
<implementation class="afryca.behavior.service.provider.BehaviorServiceContextFunction"/>
<property
name="service.context.key"
type="String"
value="afryca.behavior.service.IBehaviorService"/>
<service>
<provide
interface="org.eclipse.e4.core.contexts.IContextFunction"/>
</service>
</scr:component>
@@ -0,0 +1,8 @@
#Properties file for afryca.behavior
afryca.behavior.command.open_attitude.description = Open attitude
afryca.behavior.command.open_attitude.name = &Open attitude
afryca.behavior.command.save_attitude.description = Save attitude
afryca.behavior.command.save_attitude.name = &Save attitude
behavior.extension-point.name = Behavior
Bundle-Name = Behavior
Bundle-Vendor = Sinbad\u00B2
@@ -0,0 +1,8 @@
#Archivo de propiedades para afryca.behavior
afryca.behavior.command.open_attitude.description = Abrir actitud
afryca.behavior.command.open_attitude.name = &Abrir actitud
afryca.behavior.command.save_attitude.description = Guardar actitud
afryca.behavior.command.save_attitude.name = &Guardar actitud
behavior.extension-point.name = Comportamiento
Bundle-Name = Comportamiento
Bundle-Vendor = Sinbad\u00B2
+7
View File
@@ -0,0 +1,7 @@
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.xml,\
OSGI-INF/,\
fragment.e4xmi
source.. = src/
+15
View File
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="ASCII"?>
<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:commands="http://www.eclipse.org/ui/2010/UIModel/application/commands" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_xSb34LuXEeaP98ekhgsgKg">
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_1X__ELuXEeaP98ekhgsgKg" featurename="commands" parentElementId="afryca.rcp.application">
<elements xsi:type="commands:Command" xmi:id="_5rfNgLuXEeaP98ekhgsgKg" elementId="afryca.behavior.command.save_attitude" commandName="%afryca.behavior.command.save_attitude.name" description="%afryca.behavior.command.save_attitude.description">
<parameters xmi:id="_dwTfkLuYEeaP98ekhgsgKg" elementId="attitude" name="attitude" typeId="afryca.behavior.command.parameter.attitude" optional="false"/>
</elements>
<elements xsi:type="commands:Command" xmi:id="_sPHyMLubEea0fscCNN1udA" elementId="afryca.behavior.command.open_attitude" commandName="%afryca.behavior.command.open_attitude.name" description="%afryca.behavior.command.open_attitude.description">
<parameters xmi:id="_9KNaULubEea0fscCNN1udA" elementId="file" name="file" optional="false"/>
</elements>
</fragments>
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_2_bP4LuXEeaP98ekhgsgKg" featurename="handlers" parentElementId="afryca.rcp.application">
<elements xsi:type="commands:Handler" xmi:id="__lCa0LuXEeaP98ekhgsgKg" elementId="afryca.behavior.command.save_attitude" contributionURI="bundleclass://afryca.behavior/afryca.behavior.command.SaveAttitude" command="_5rfNgLuXEeaP98ekhgsgKg"/>
<elements xsi:type="commands:Handler" xmi:id="_wMnigLubEea0fscCNN1udA" elementId="afryca.behavior.handler.open_attitude" contributionURI="bundleclass://afryca.behavior/afryca.behavior.command.OpenAttitude" command="_sPHyMLubEea0fscCNN1udA"/>
</fragments>
</fragment:ModelFragments>
+19
View File
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension-point id="afryca.behavior" name="%behavior.extension-point.name" schema="schema/afryca.behavior.exsd"/>
<extension
point="org.eclipse.ui.commands">
<commandParameterType
converter="afryca.behavior.command.parameter.AttitudeParameterValueConverter"
id="afryca.behavior.command.parameter.attitude">
</commandParameterType>
</extension>
<extension
id="afryca.behavior.fragment"
point="org.eclipse.e4.workbench.model">
<fragment
uri="fragment.e4xmi">
</fragment>
</extension>
</plugin>
@@ -0,0 +1,195 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="afryca" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appinfo>
<meta.schema plugin="afryca" id="behavior" name="Behavior"/>
</appinfo>
<documentation>
[Enter description of this extension point.]
</documentation>
</annotation>
<element name="extension">
<annotation>
<appinfo>
<meta.element />
</appinfo>
</annotation>
<complexType>
<choice minOccurs="1" maxOccurs="unbounded">
<element ref="Behavior"/>
</choice>
<attribute name="point" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="id" type="string">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="name" type="string">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute translatable="true"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<element name="Behavior">
<complexType>
<sequence minOccurs="0" maxOccurs="unbounded">
<choice minOccurs="0" maxOccurs="unbounded">
<element ref="Parameter" minOccurs="0" maxOccurs="unbounded"/>
</choice>
</sequence>
<attribute name="id" type="string" use="required">
<annotation>
<documentation>
Behavior unique identifier
</documentation>
<appinfo>
<meta.attribute kind="identifier"/>
</appinfo>
</annotation>
</attribute>
<attribute name="Behavior" type="string" use="required">
<annotation>
<documentation>
The class that implement the behavior
</documentation>
<appinfo>
<meta.attribute kind="java" basedOn="afryca.behavior.Behavior:"/>
</appinfo>
</annotation>
</attribute>
<attribute name="description" type="string" use="default" value="Behavior description">
<annotation>
<documentation>
Behavior description
</documentation>
<appinfo>
<meta.attribute translatable="true"/>
</appinfo>
</annotation>
</attribute>
<attribute name="name" type="string" use="required">
<annotation>
<documentation>
Behavior name (the value to be displayed in the interface)
</documentation>
<appinfo>
<meta.attribute translatable="true"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<element name="Parameter">
<complexType>
<attribute name="id" type="string" use="required">
<annotation>
<documentation>
Parameter id
</documentation>
</annotation>
</attribute>
<attribute name="type" use="required">
<annotation>
<documentation>
Parameter type
</documentation>
</annotation>
<simpleType>
<restriction base="string">
<enumeration value="Integer">
</enumeration>
<enumeration value="Float">
</enumeration>
</restriction>
</simpleType>
</attribute>
<attribute name="description" type="string">
<annotation>
<documentation>
Parameter type
</documentation>
<appinfo>
<meta.attribute translatable="true"/>
</appinfo>
</annotation>
</attribute>
<attribute name="default_value" type="string" use="required">
<annotation>
<documentation>
Parameter default value
</documentation>
</annotation>
</attribute>
<attribute name="lower_limit" type="string">
<annotation>
<documentation>
Parameter lower limit
</documentation>
</annotation>
</attribute>
<attribute name="upper_limit" type="string">
<annotation>
<documentation>
Parameter upper limit
</documentation>
</annotation>
</attribute>
</complexType>
</element>
<annotation>
<appinfo>
<meta.section type="since"/>
</appinfo>
<documentation>
[Enter the first release in which this extension point appears.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="examples"/>
</appinfo>
<documentation>
[Enter extension point usage example here.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="apiinfo"/>
</appinfo>
<documentation>
[Enter API information here.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="implementation"/>
</appinfo>
<documentation>
[Enter information about supplied implementation of this extension point.]
</documentation>
</annotation>
</schema>
@@ -0,0 +1,364 @@
package afryca.behavior;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import org.eclipse.core.commands.ParameterValueConversionException;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import afryca.behavior.command.parameter.AttitudeParameterValueConverter;
/**
* Behavior's parameters
*
* @author Sinbad²
* @version 3.0
*/
public class Attitude {
public final static String ID = "attitude"; //$NON-NLS-1$
public final static String FIELD_FILE = "file"; //$NON-NLS-1$
public final static String FIELD_BEHAVIOR = "behavior"; //$NON-NLS-1$
public final static String FIELD_PARAMETERS = "parameters"; //$NON-NLS-1$
public final static String ATTITUDE_EXTENSION = ".attitude"; //$NON-NLS-1$
@Inject
public static AttitudeParameterValueConverter converter;
@Inject
private IEclipseContext context;
private PropertyChangeSupport changes = new PropertyChangeSupport(this);
private String file;
private String behavior;
private Map<String, Parameter> parameters;
@Inject
public Attitude() {
super();
file = ""; //$NON-NLS-1$
behavior = null;
parameters = new HashMap<>();
}
/**
* Return file name
*
* @return File name
*/
public String getFile() {
return file;
}
/**
* Set file name
*
* @param file
* File name
*/
public void setFile(String file) {
changes.firePropertyChange(FIELD_FILE, this.file, this.file = file);
}
/**
* Return behavior id
*
* @return Behavior id
*/
public String getBehavior() {
return behavior;
}
/**
* Set behavior id
*
* @param behavior
* Behavior id
*/
public void setBehavior(String behavior) {
changes.firePropertyChange(FIELD_BEHAVIOR, this.behavior, this.behavior = behavior);
}
/**
* Add parameter
*
* @param parameter
* Parameter to add
*/
public void addParameter(Parameter parameter) {
parameters.put(parameter.getId(), parameter);
}
/**
* Get parameter by identifier
*
* @param id
* Parameter's identifier
* @return Parameter with id identifier
*/
public Parameter getParameter(String id) {
return parameters.get(id);
}
/**
* Set map of parameters by identifiers
*
* @param parameters
* Map of parameters by identifiers
*/
public void setParameters(Map<String, Parameter> parameters) {
this.parameters = parameters;
}
/**
* Return map of parameters by identifiers
*
* @return Parameters Map of parameters by identifiers
*/
public Map<String, Parameter> getParameters() {
return parameters;
}
/**
* Return all parameters' identifiers
*
* @return Array with all parameters' identifiers
*/
public String[] getParametersIDs() {
return parameters.keySet().toArray(new String[0]);
}
/**
* Extract value from float parameter
*
* @param id
* Parameter's identifier
* @return Parameter value
* @throws NumberFormatException
* if parameter is not float
*/
public Float extractFloatParameter(String id) {
Float result = null;
Parameter parameter = parameters.get(id);
result = (Float) ((parameter.getValue() == null) ? parameter.getDefaultValue() : parameter.getValue());
return result;
}
/**
* Extract value from integer parameter
*
* @param id
* Parameter's identifier
* @return Parameter value
* @throws NumberFormatException
* if parameter is not integer
*/
public Integer extractIntegerParameter(String id) {
Integer result = null;
Parameter parameter = parameters.get(id);
result = (Integer) ((parameter.getValue() == null) ? parameter.getDefaultValue() : parameter.getValue());
return result;
}
public Attitude copy() {
Attitude copy = ContextInjectionFactory.make(Attitude.class, context);
copy.file = (file != null) ? new String(file) : null;
copy.behavior = (behavior != null) ? new String(behavior) : behavior;
parameters.forEach((K, V) -> copy.parameters.put(new String(K), V.copy()));
return copy;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((parameters == null) ? 0 : parameters.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Attitude other = (Attitude) obj;
return mapDeepEquals(parameters, other.parameters);
}
private static boolean mapDeepEquals(Map<?, ?> m1, Map<?, ?> m2) {
if (m1.size() != m2.size()) {
return false;
}
Set<?> allKeys = m1.keySet();
if (!linearDeepEquals(allKeys, m2.keySet())) {
return false;
}
for (Object key : allKeys) {
if (!deepEquals(m1.get(key), m2.get(key))) {
return false;
}
}
return true;
}
private static <T> boolean deepEquals(T t1, T t2) {
if (t1 == t2) {
return true;
}
if (t1 == null || t2 == null) {
return false;
}
if (t1 instanceof Map && t2 instanceof Map) {
return mapDeepEquals((Map<?, ?>) t1, (Map<?, ?>) t2);
} else if (t1 instanceof List && t2 instanceof List) {
return linearDeepEquals((List<?>) t1, (List<?>) t2);
} else if (t1 instanceof Set && t2 instanceof Set) {
return linearDeepEquals((Set<?>) t1, (Set<?>) t2);
} else if (t1 instanceof Object[] && t2 instanceof Object[]) {
return linearDeepEquals((Object[]) t1, (Object[]) t2);
} else {
return t1.equals(t2);
}
}
private static boolean linearDeepEquals(Collection<?> s1, Collection<?> s2) {
if (s1.size() != s2.size()) {
return false;
}
for (Object s1Item : s1) {
boolean found = false;
for (Object s2Item : s2) {
if (deepEquals(s2Item, s1Item)) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
private static boolean linearDeepEquals(Object[] s1, Object[] s2) {
if (s1.length != s2.length) {
return false;
}
for (Object s1Item : s1) {
boolean found = false;
for (Object s2Item : s2) {
if (deepEquals(s2Item, s1Item)) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
/**
* Add property change listener
*
* @param listener
* Property change listener
*/
public void addPropertyChangeListener(PropertyChangeListener listener) {
changes.addPropertyChangeListener(listener);
}
/**
* Remove property change listener
*
* @param listener
* Property change listener
*/
public void removePropertyChangeListener(PropertyChangeListener listener) {
changes.removePropertyChangeListener(listener);
}
@Override
public String toString() {
try {
return converter.convertToString(this);
} catch (ParameterValueConversionException e) {
e.printStackTrace();
return null;
}
}
/**
* Parse attitude from string value
*
* @param value
* Attitude string value
* @return Attitude
*/
public static Attitude parseAttitude(String value) {
try {
return (Attitude) converter.convertToObject(value);
} catch (ParameterValueConversionException e) {
e.printStackTrace();
return null;
}
}
/**
* Return attitude simple name
*
* @return attitude simple name
*/
public String getSimpleName() {
return getSimpleName(file);
}
/**
* Return file simple name
*
* @param file
* File name
* @return File simple name
*/
public static String getSimpleName(String file) {
if (file != null) {
String simpleName = new File(file).getName();
return simpleName.contains(ATTITUDE_EXTENSION)
? simpleName.substring(0, simpleName.length() - ATTITUDE_EXTENSION.length())
: simpleName;
}
return file;
}
}
@@ -0,0 +1,156 @@
package afryca.behavior;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import javax.inject.Inject;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Optional;
import afryca.ase.service.IASEService;
/**
* Interface for behaviors
*
* @author Sinbad²
* @version 3.0
*/
public abstract class Behavior {
// Extension point id
public static final String EXTENSION_POINT = "afryca.behavior"; //$NON-NLS-1$
protected static final int CACHE_SIZE = 1000;
protected static Map<String, List<Double>> behaviorCache;
static {
behaviorCache = new HashMap<>();
}
protected Attitude attitude;
@Inject
protected IASEService aseService;
@Inject
protected IEclipseContext context;
@Inject
private void setAttitude(@Optional Attitude attitude) {
if (isNewAttitude(attitude)) {
removeOldAttitude();
this.attitude = attitude;
setNewAttitude();
}
}
private boolean isNewAttitude(Attitude attitude) {
if ((this.attitude == null) && (attitude == null)) {
return false;
}
if ((this.attitude == null) || (attitude == null)) {
return true;
}
return !this.attitude.equals(attitude);
}
private void removeOldAttitude() {
if (attitude != null) {
attitude.getParameters().forEach((K, V) -> context.remove(K));
}
}
private void setNewAttitude() {
if (attitude != null) {
attitude.getParameters().forEach((K, V) -> context.set(K, V.getCurrentValue()));
}
}
/**
* Return behavior attitude
*
* @return Behavior attitude
*/
public Attitude getAttitude() {
return attitude;
}
/**
* Return behavior context
*
* @return Behavior context
*/
public IEclipseContext getContext() {
return context;
}
/**
* Return n changes
*
* @param numberOfChanges
* Number of changes to obtain
* @return N changes
*/
public abstract double[] getNChanges(int numberOfChanges);
protected static double enforceValueRange(double value, double lowerLimit, double upperLimit) {
if (value < lowerLimit) {
return lowerLimit;
}
if (value > upperLimit) {
return upperLimit;
}
return value;
}
protected static double[] getNChangesFromCache(String key, int numberOfChanges, Function<Integer, Double[]> generator) {
int available = cacheSize(key);
if (available < numberOfChanges) {
storeInCache(key, generator.apply((numberOfChanges - available) + CACHE_SIZE));
}
return getNChangesFromCache(key, numberOfChanges);
}
protected static int cacheSize(String key) {
List<Double> changes = behaviorCache.get(key);
return changes != null
? changes.size()
: 0;
}
protected static double[] getNChangesFromCache(String key, int numberOfChanges) {
List<Double> result;
if (behaviorCache.containsKey(key)) {
List<Double> changes = behaviorCache.get(key);
if (numberOfChanges < changes.size()) {
result = changes.subList(0, numberOfChanges);
behaviorCache.put(key, changes.subList(numberOfChanges, changes.size()));
} else {
result = new ArrayList<>(changes);
changes.clear();
}
} else {
result = new ArrayList<>();
}
return result.stream().mapToDouble(Double::doubleValue).toArray();
}
protected static void storeInCache(String key, Double[] changes) {
List<Double> changesInCache = behaviorCache.get(key);
if (changesInCache == null) {
changesInCache = new ArrayList<>();
behaviorCache.put(key, changesInCache);
}
changesInCache.addAll(Arrays.asList(changes));
}
}
@@ -0,0 +1,389 @@
package afryca.behavior;
import javax.inject.Inject;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.EclipseContextFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.services.nls.Translation;
import afryca.behavior.definition.EParameterElements;
import afryca.behavior.definition.EParameterTypes;
import afryca.behavior.definition.ParameterRegistry;
import afryca.behavior.l10n.Messages;
/**
* Behavior parameter
*
* @author Sinbad²
* @version 3.0
*/
public class Parameter {
private String id;
private String description;
private EParameterTypes type;
private Object defaultValue;
private Object lowerLimit;
private Object upperLimit;
private Object value;
@Inject
private ParameterRegistry registry;
@Inject
@Translation
private Messages messages;
@Inject
private IEclipseContext context;
private Parameter() {
id = null;
description = null;
type = null;
defaultValue = null;
lowerLimit = null;
upperLimit = null;
value = null;
}
private Parameter(String id, String description, String type, String defaultValue, String lowerLimit,
String upperLimit, Messages messages) {
this();
if (!validate(type, defaultValue, lowerLimit, upperLimit)) {
throw new IllegalArgumentException(messages.invalid_arguments);
}
setId(id);
setDescription(description);
setType(type);
setDefaultValue(defaultValue);
setLowerLimit(lowerLimit);
setUpperLimit(upperLimit);
}
@Inject
public Parameter(ParameterRegistry registry, @Translation Messages messages) {
this(registry.getElement(EParameterElements.id), registry.getElement(EParameterElements.description),
registry.getElement(EParameterElements.type), registry.getElement(EParameterElements.default_value),
registry.getElement(EParameterElements.lower_limit),
registry.getElement(EParameterElements.upper_limit), messages);
}
private static boolean validate(String type, String defaultValue, String lowerLimit, String upperLimit) {
try {
EParameterTypes parameterType = extractParameterType(type);
if (parameterType == null) {
return false;
}
Object value = extractDefaultValue(parameterType, defaultValue);
if (value == null) {
return false;
}
if (notIsEmpty(lowerLimit)) {
if(value instanceof Float) {
if (((float) EParameterTypes.parseValue(parameterType, lowerLimit)) > ((float) value)) {
return false;
}
} else if(value instanceof Integer) {
if (((int) EParameterTypes.parseValue(parameterType, lowerLimit)) > ((int) value)) {
return false;
}
}
}
if (notIsEmpty(upperLimit)) {
if(value instanceof Float) {
if (((float) EParameterTypes.parseValue(parameterType, upperLimit)) < ((float) value)) {
return false;
}
} else if(value instanceof Integer) {
if (((int) EParameterTypes.parseValue(parameterType, upperLimit)) < ((int) value)) {
return false;
}
}
}
} catch (Exception e) {
return false;
}
return true;
}
private static EParameterTypes extractParameterType(String type) {
return notIsEmpty(type) ? EParameterTypes.valueOf(type) : null;
}
private static Object extractDefaultValue(EParameterTypes type, String defaultValue) {
return notIsEmpty(defaultValue) ? EParameterTypes.parseValue(type, defaultValue) : null;
}
private static boolean notIsEmpty(String value) {
return (value != null) ? !value.isEmpty() : false;
}
private void setId(String id) {
this.id = id;
}
/**
* Return identifier
*
* @return identifier
*/
public String getId() {
return id;
}
private void setDescription(String description) {
this.description = description;
}
/**
* Return description
*
* @return Description
*/
public String getDescription() {
return description;
}
private void setType(String type) {
setType(EParameterTypes.valueOf(type));
}
private void setType(EParameterTypes type) {
this.type = type;
}
/**
* Return type
*
* @param type
* Type
*/
public EParameterTypes getType() {
return type;
}
private void setDefaultValue(String defaultValue) {
this.defaultValue = (defaultValue != null) ? EParameterTypes.parseValue(type, defaultValue) : null;
}
/**
* Return default value
*
* @return Default value
*/
public Object getDefaultValue() {
return defaultValue;
}
private void setLowerLimit(String lowerLimit) {
if (notIsEmpty(lowerLimit)) {
this.lowerLimit = EParameterTypes.parseValue(type, lowerLimit);
}
}
/**
* Return lower limit
*
* @return Lower limit
*/
public Object getLowerLimit() {
return lowerLimit;
}
private void setUpperLimit(String upperLimit) {
if (notIsEmpty(upperLimit)) {
this.upperLimit = EParameterTypes.parseValue(type, upperLimit);
}
}
/**
* Return upper limit
*
* @return Upper limit
*/
public Object getUpperLimit() {
return upperLimit;
}
/**
* Set parameter value
*
* @param value
* Parameter value
*
* @throws IllegalArgumentException
* if value is invalid
*/
public void setValue(Object value) {
String message = computeValidateMessage(value);
if (message == null) {
this.value = !defaultValue.equals(value) ? value : null;
} else {
throw new IllegalArgumentException(message);
}
}
private String computeValidateMessage(Object value) {
if (isNull(value)) {
// The null value is used to clear the parameter value and it's a
// valid value
return null;
}
if (invalidType(value)) {
return messages.invalid_type;
}
if (lowerThanLowerLimit(value)) {
return messages.value_is_lower_than_lower_limit;
}
if (greaterThanLowerLimit(value)) {
return messages.value_is_greater_than_lower_limit;
}
return null;
}
private static boolean isNull(Object value) {
return (value == null);
}
private boolean invalidType(Object value) {
return !EParameterTypes.getClass(type).isInstance(value);
}
private boolean lowerThanLowerLimit(Object value) {
if(value instanceof Float) {
return (lowerLimit != null) ? ((float) value) < ((float) lowerLimit) : false;
} else if(value instanceof Integer) {
return (lowerLimit != null) ? ((int) value) < ((int) lowerLimit) : false;
} else {
return false;
}
}
private boolean greaterThanLowerLimit(Object value) {
if(value instanceof Float) {
return (upperLimit != null) ? ((float) value) > ((float) upperLimit) : false;
} else if(value instanceof Integer) {
return (upperLimit != null) ? ((int) value) > ((int) upperLimit) : false;
} else {
return false;
}
}
/**
* Return value
*
* @return value
*/
public Object getValue() {
return value;
}
/**
* Return current value
*
* @return <b>value</b> if it is not null. <b>defaultValue</b> otherwise
*/
public Object getCurrentValue() {
return (value != null) ? value : defaultValue;
}
/**
* Copy parameter
*
* @return Parameter copy
*/
public Parameter copy() {
IEclipseContext staticContext = EclipseContextFactory.create();
injectAndSetInContext(registry, staticContext);
injectAndSetInContext(messages, staticContext);
injectAndSetInContext(context, staticContext);
Parameter copy = ContextInjectionFactory.make(Parameter.class, context, staticContext);
copy.value = copyValue(value);
staticContext.dispose();
return copy;
}
private void injectAndSetInContext(Object element, IEclipseContext context) {
ContextInjectionFactory.inject(element, context);
context.set(element.getClass().getName(), element);
}
private static Object copyValue(Object value) {
if (value instanceof Integer) {
return Integer.valueOf((int) value);
} else if (value instanceof Float) {
return Float.valueOf((float) value);
} else {
return null;
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((defaultValue == null) ? 0 : defaultValue.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((lowerLimit == null) ? 0 : lowerLimit.hashCode());
result = prime * result + ((upperLimit == null) ? 0 : upperLimit.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Parameter other = (Parameter) obj;
if (defaultValue == null) {
if (other.defaultValue != null)
return false;
} else if (!defaultValue.equals(other.defaultValue))
return false;
if (description == null) {
if (other.description != null)
return false;
} else if (!description.equals(other.description))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (lowerLimit == null) {
if (other.lowerLimit != null)
return false;
} else if (!lowerLimit.equals(other.lowerLimit))
return false;
if (upperLimit == null) {
if (other.upperLimit != null)
return false;
} else if (!upperLimit.equals(other.upperLimit))
return false;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
}
@@ -0,0 +1,104 @@
package afryca.behavior.command;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.commons.io.IOUtils;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.core.services.log.ILoggerProvider;
import org.eclipse.e4.core.services.log.Logger;
import org.eclipse.e4.core.services.nls.Translation;
import afryca.behavior.Attitude;
import afryca.behavior.l10n.Messages;
/**
* Command for open behavior's attitude
*
* @author Sinbad²
* @version 3.0
*/
@SuppressWarnings("restriction")
public class OpenAttitude {
public static final String ID = "afryca.behavior.command.open_attitude"; //$NON-NLS-1$
public static final String FILE_PARAMETER = "file"; //$NON-NLS-1$
private Logger logger;
@Inject
@Translation
Messages messages;
@Inject
public void instantiateLogger(ILoggerProvider loggerProvider) {
logger = loggerProvider.getClassLogger(this.getClass());
}
@Execute
public Attitude execute(@Named(FILE_PARAMETER) String file) throws Exception {
logger.info(messages.command_executed, ID);
return readAttitude(file);
}
private Attitude readAttitude(String file) throws ExecutionException {
Attitude attitude = null;
if (file != null) {
InputStream inputStream = null;
try {
if (isValidFile(file)) {
inputStream = new FileInputStream(file);
} else if (isValidURL(file)) {
inputStream = new URL(file).openStream();
} else {
throw new ExecutionException(messages.wrong_file);
}
attitude = Attitude.parseAttitude(IOUtils.toString(inputStream, "UTF-8")); //$NON-NLS-1$
attitude.setFile(file);
inputStream.close();
} catch (IOException es) {
if (inputStream != null) {
try {
inputStream.close();
} catch (Exception e) {
}
}
throw new ExecutionException(messages.wrong_file);
}
}
return attitude;
}
private static boolean isValidFile(String fileName) {
File file = new File(fileName);
return (file.exists() && file.canRead());
}
private static boolean isValidURL(String url) {
URL u = null;
try {
u = new URL(url);
} catch (MalformedURLException e) {
return false;
}
try {
u.toURI();
} catch (URISyntaxException e) {
return false;
}
return true;
}
}
@@ -0,0 +1,50 @@
package afryca.behavior.command;
import java.io.File;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.commons.io.FileUtils;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.core.services.log.ILoggerProvider;
import org.eclipse.e4.core.services.log.Logger;
import org.eclipse.e4.core.services.nls.Translation;
import afryca.behavior.Attitude;
import afryca.behavior.l10n.Messages;
/**
* Command for save behavior's attitude
*
* @author Sinbad²
* @version 3.0
*/
@SuppressWarnings("restriction")
public class SaveAttitude {
public static final String ID = "afryca.behavior.command.save_attitude"; //$NON-NLS-1$
private Logger logger;
@Inject
@Translation
private Messages messages;
@Inject
public void instantiateLogger(ILoggerProvider loggerProvider) {
logger = loggerProvider.getClassLogger(this.getClass());
}
@Execute
public void execute(@Named(Attitude.ID) Attitude attitude) throws Exception {
logger.info(messages.command_executed, ID);
try {
Attitude copy = attitude.copy();
copy.setFile(null);
FileUtils.writeStringToFile(new File(attitude.getFile()), copy.toString(), "UTF-8"); //$NON-NLS-1$
} catch (Exception e) {
throw new Exception(messages.wrong_file);
}
}
}
@@ -0,0 +1,34 @@
package afryca.behavior.command.parameter;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.e4.core.di.annotations.Creatable;
import afryca.parametervalueconverterhelper.AbstractParameterValueConverterHelper;
/**
* Attitude parameter value converter
*
* @author Sinbad²
* @version 3.0
*/
@Creatable
@Singleton
public class AttitudeParameterValueConverter extends AbstractParameterValueConverterHelper {
@Inject
private static AttitudeParameterValueConverterHelper attitudeHelper;
public AttitudeParameterValueConverter() {
helper = attitudeHelper;
}
@PostConstruct
private void initHelper() {
if (helper == null) {
helper = attitudeHelper;
}
}
}
@@ -0,0 +1,111 @@
package afryca.behavior.command.parameter;
import afryca.behavior.Attitude;
import afryca.behavior.Parameter;
import afryca.behavior.definition.BehaviorRegistry;
import afryca.behavior.definition.ParameterRegistry;
import afryca.behavior.service.IBehaviorService;
import afryca.parametervalueconverterhelper.ParameterValueConverterHelper;
import afryca.parametervalueconverterhelper.ParameterValueConverterHelperException;
import static afryca.behavior.Attitude.*;
import java.util.Arrays;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Creatable;
/**
* Attitude parameter value converter helper
*
* @author Sinbad²
* @version 3.0
*/
@Creatable
@Singleton
public class AttitudeParameterValueConverterHelper extends ParameterValueConverterHelper {
public static final String KEY_MARK = "parameterValueKey"; //$NON-NLS-1$
public static final String VALUE_MARK = "parameterValueValue"; //$NON-NLS-1$
@Inject
private IBehaviorService behaviorService;
@Inject
private IEclipseContext context;
@Override
public Object convertToObject(String parameterValue) throws ParameterValueConverterHelperException {
IEclipseContext attitudeContext = context.createChild();
Attitude result = ContextInjectionFactory.make(Attitude.class, attitudeContext);
setElements(result, parameterValue, attitudeContext);
return result;
}
private void setElements(Attitude attitude, String parameterValue, IEclipseContext context) throws ParameterValueConverterHelperException {
Map<String, String> fields = extractFieldsValue(parameterValue,
new String[] { FIELD_FILE, FIELD_BEHAVIOR, FIELD_PARAMETERS });
attitude.setFile(getString(fields, FIELD_FILE));
attitude.setBehavior(getString(fields, FIELD_BEHAVIOR));
extractAttitudeParameters(attitude, fields, context);
}
private void extractAttitudeParameters(Attitude attitude, Map<String, String> fields, IEclipseContext context)
throws ParameterValueConverterHelperException {
Map<String, Object> parametersValues = getObjectMap(
fields,
FIELD_PARAMETERS,
singular(FIELD_PARAMETERS),
KEY_MARK,
VALUE_MARK,
ParameterParameterValueConverterHelper.class,
Object.class);
setDefaultAttitude(attitude, context);
parametersValues.forEach((K, V) -> {
if (V != null) {
attitude.getParameter(K).setValue(V);
}
});
}
private void setDefaultAttitude(Attitude attitude, IEclipseContext context) {
BehaviorRegistry behaviorRegistry = behaviorService.getRegistry(attitude.getBehavior());
Arrays.stream(behaviorRegistry.getParametersIDs())
.map(behaviorRegistry::getParameterRegistry)
.forEach(parameterRegistry -> addParameter(attitude, parameterRegistry, context));
}
private void addParameter(Attitude attitude, ParameterRegistry parameterRegistry, IEclipseContext context) {
Parameter parameter = ContextInjectionFactory.make(Parameter.class, injectInChildContext(parameterRegistry, context));
attitude.addParameter(parameter);
}
private IEclipseContext injectInChildContext(Object element, IEclipseContext context) {
IEclipseContext childContext = context.createChild();
ContextInjectionFactory.inject(element, childContext);
childContext.set(element.getClass().getName(), element);
return childContext;
}
@Override
public String convertToString(Object parameterValue) throws ParameterValueConverterHelperException {
Attitude attitude = (Attitude) parameterValue;
String file = marker(attitude.getFile(), FIELD_FILE);
String behavior = marker(attitude.getBehavior(), FIELD_BEHAVIOR);
String parameters = markMap(attitude.getParameters(),
FIELD_PARAMETERS,
singular(FIELD_PARAMETERS),
KEY_MARK,
VALUE_MARK,
ParameterParameterValueConverterHelper.class);
return marker(new String[] { file, behavior, parameters }, ID);
}
}
@@ -0,0 +1,15 @@
package afryca.behavior.command.parameter;
import afryca.parametervalueconverterhelper.AbstractParameterValueConverterHelper;
/**
* Parameter value converter
*
* @author Sinbad²
* @version 3.0
*/
public class ParameterParameterValueConverter extends AbstractParameterValueConverterHelper {
public ParameterParameterValueConverter() {
helper = new ParameterParameterValueConverterHelper();
}
}
@@ -0,0 +1,67 @@
package afryca.behavior.command.parameter;
import java.util.Map;
import afryca.behavior.Parameter;
import afryca.parametervalueconverterhelper.ParameterValueConverterHelper;
import afryca.parametervalueconverterhelper.ParameterValueConverterHelperException;
/**
* Parameter value converter helper
*
* @author Sinbad²
* @version 3.0
*/
public class ParameterParameterValueConverterHelper extends ParameterValueConverterHelper {
public static final String PARAMETER_MARK = "parameter"; // $NON-NLS-1
public static final String TYPE_MARK = "type"; //$NON-NLS-1$
public static final String VALUE_MARK = "value"; //$NON-NLS-1$
@Override
public Object convertToObject(String parameterValue) throws ParameterValueConverterHelperException {
Map<String, String> fields = extractFieldsValue(parameterValue, new String[] { TYPE_MARK, VALUE_MARK });
String type = getString(fields, TYPE_MARK);
if (type == null || type.isEmpty()) {
return null;
}
if (Integer.class.getName().equals(type)) {
return getInteger(fields, VALUE_MARK);
}
if (Float.class.getName().equals(type)) {
return Float.parseFloat(getString(fields, VALUE_MARK));
}
return null;
}
@Override
public String convertToString(Object parameterValue) throws ParameterValueConverterHelperException {
Parameter parameter = (Parameter) parameterValue;
Object value = parameter.getCurrentValue();
String type = null;
String stringValue = null;
if (value == null) {
type = marker(TYPE_MARK);
stringValue = marker(VALUE_MARK);
}
if (value instanceof Integer) {
type = marker(Integer.class.getName(), TYPE_MARK);
stringValue = marker(Integer.toString((Integer) value), VALUE_MARK);
}
if (value instanceof Float) {
type = marker(Float.class.getName(), TYPE_MARK);
stringValue = marker(Float.toString((Float) value), VALUE_MARK);
}
return marker(new String[] { type, stringValue }, PARAMETER_MARK);
}
}
@@ -0,0 +1,94 @@
package afryca.behavior.definition;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.IConfigurationElement;
/**
* Registry for the extension point of Behavior
*
* @author Sinbad²
* @version 3.0
*/
public class BehaviorRegistry {
private IConfigurationElement configuration;
private Map<String, ParameterRegistry> parameters;
private BehaviorRegistry() {
configuration = null;
parameters = new HashMap<>();
}
/**
* Builder
*
* @param element
* behavior configuration element
*/
public BehaviorRegistry(IConfigurationElement element) {
this();
configuration = element;
loadParameters();
}
/**
* Return behavior configuration
*
* @return Behavior configuration
*/
public IConfigurationElement getConfiguration() {
return configuration;
}
/**
* Return behavior element value
*
* @param element
* element key
* @return element value
*/
public String getElement(EElements element) {
String result = null;
if (configuration != null) {
result = configuration.getAttribute(element.toString());
}
return result;
}
private void loadParameters() {
IConfigurationElement[] configurations = configuration.getChildren();
ParameterRegistry registry;
for (IConfigurationElement configurationElement : configurations) {
registry = new ParameterRegistry(configurationElement);
parameters.put(registry.getElement(EParameterElements.id), registry);
}
}
/**
* Return all parameter registers
*
* @return Parameters registers IDs
*/
public String[] getParametersIDs() {
return parameters.keySet().toArray(new String[0]);
}
/**
* Return a ParameterRegistry
*
* @param ID
* ID of the ParameterRegistry
* @return ParameterRegistry
*/
public ParameterRegistry getParameterRegistry(String ID) {
return parameters.get(ID);
}
}
@@ -0,0 +1,22 @@
package afryca.behavior.definition;
/**
* Behavior elements
*
* @author Sinbad²
* @version 3.0
*/
public enum EElements {
// Behavior id
id,
// Behavior class
Behavior,
// Behavior name
description,
// Behavior name
name
}
@@ -0,0 +1,28 @@
package afryca.behavior.definition;
/**
* Parameter's elements
*
* @author Sinbad²
* @version 3.0
*/
public enum EParameterElements {
// Parameter id
id,
// Parameter type
type,
// Parameter default value
default_value,
// Parameter description
description,
// Parameter lower limit
lower_limit,
// Parameter upper limit
upper_limit;
}
@@ -0,0 +1,68 @@
package afryca.behavior.definition;
/**
* Types of parameters
*
* @author Sinbad²
* @version 3.0
*/
public enum EParameterTypes {
// Integer
Integer,
// Float
Float;
/**
* Return Class of EParameterTypes
*
* @param type
* EParameterTypes
* @return Class of EParameterTypes
*/
public static Class<?> getClass(EParameterTypes type) {
switch (type) {
case Integer:
return Integer.class;
case Float:
return Float.class;
default:
break;
}
return null;
}
/**
* Return Class of string value of EParameterType
*
* @param type
* String value of EParameterType
* @return Class of string value of EParameterType
*/
public static Class<?> getClass(String type) {
return getClass(valueOf(type));
}
/**
* Parse a variable
*
* @param type
* Variable type
* @param value
* String value of variable
* @return Variable value
*/
public static Object parseValue(EParameterTypes type, String value) {
switch (type) {
case Integer:
return java.lang.Integer.parseInt(value);
case Float:
return java.lang.Float.parseFloat(value);
default:
break;
}
return null;
}
}
@@ -0,0 +1,57 @@
package afryca.behavior.definition;
import org.eclipse.core.runtime.IConfigurationElement;
/**
* Registry for parameter of Behavior
*
* @author Sinbad²
* @version 3.0
*/
public class ParameterRegistry {
private IConfigurationElement parameterConfiguration;
private ParameterRegistry() {
parameterConfiguration = null;
}
/**
* Builder
*
* @param element
* Parameter configuration element
*/
public ParameterRegistry(IConfigurationElement element) {
this();
parameterConfiguration = element;
}
/**
* Return parameter element value
*
* @param element
* element key
* @return element value
*/
public String getElement(EParameterElements element) {
String result = null;
if (parameterConfiguration != null) {
result = parameterConfiguration.getAttribute(element.toString());
}
return result;
}
/**
* Return parameter configuration
*
* @return parameter configuration
*/
public IConfigurationElement getConfiguration() {
return parameterConfiguration;
}
}
@@ -0,0 +1,20 @@
package afryca.behavior.l10n;
/**
* Localization messages
*
* @author Sinbad²
* @version 3.0
*/
public class Messages {
public String behavior_attitude_updated;
public String behavior_loaded_x;
public String behavior_selected_x;
public String command_executed;
public String invalid_arguments;
public String invalid_type;
public String value_is_greater_than_lower_limit;
public String value_is_lower_than_lower_limit;
public String wrong_file;
public String x_defined_behaviors;
}
@@ -0,0 +1,10 @@
behavior_attitude_updated=Behavior attitude updated
behavior_loaded_x=Behavior loaded {0}
behavior_selected_x=Behavior selected {0}
command_executed={0} executed
invalid_arguments=Invalid arguments
invalid_type=Invalid type
value_is_greater_than_lower_limit=Value is greater than upper limit
value_is_lower_than_lower_limit=Value is lower than lower limit
wrong_file=wrong file
x_defined_behaviors={0} defined behaviors
@@ -0,0 +1,10 @@
behavior_attitude_updated=Actitud de comportamiento actualizada
behavior_loaded_x=Comportamiento cargado {0}
behavior_selected_x=Comportamiento seleccionado {0}
command_executed={0} ejecutado
invalid_arguments=Argumentos inválidos
invalid_type=Tipo inválido
value_is_greater_than_lower_limit=El valor es mayor que el límite superior
value_is_lower_than_lower_limit=El valor es menor que el límite inferior
wrong_file=archivo inválido
x_defined_behaviors={0} comportamientos definidos
@@ -0,0 +1,25 @@
package afryca.behavior.provider;
import java.util.Map;
import afryca.behavior.Attitude;
/**
* Attitude provider
*
* @author Sinbad²
* @version 3.0
*/
public interface IAttitudeProvider {
/**
* Create attitude using map of values
*
* @param file
* Attitude file name
* @param values
* Map of values
* @return Attitude
*/
Attitude createAttitude(String file, Map<String, String> values);
}
@@ -0,0 +1,21 @@
package afryca.behavior.provider;
import afryca.behavior.Behavior;
/**
* Behavior provider
*
* @author Sinbad²
* @version 3.0
*/
public interface IBehaviorProvider {
/**
* Create behavior
*
* @param behaviorId
* Behavior id
* @return Behavior
*/
Behavior createBehavior(String behaviorId);
}
@@ -0,0 +1,97 @@
package afryca.behavior.provider.internal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.EclipseContextFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import afryca.behavior.Attitude;
import afryca.behavior.Parameter;
import afryca.behavior.definition.BehaviorRegistry;
import afryca.behavior.definition.EParameterTypes;
import afryca.behavior.definition.ParameterRegistry;
import afryca.behavior.provider.IAttitudeProvider;
import afryca.behavior.service.IBehaviorService;
/**
* Attitude default provider
*
* @author Sinbad²
* @version 3.0
*/
public class AttitudeDefaultProvider implements IAttitudeProvider {
@Inject
private IBehaviorService behaviorService;
@Inject
private IEclipseContext context;
private Map<String, Attitude> templates;
@PostConstruct
private void initialize() {
templates = new HashMap<>();
}
@Override
public Attitude createAttitude(String file, Map<String, String> values) {
String selection = behaviorService.getSelection();
Attitude attitude = templates.get(selection);
if (attitude == null) {
attitude = generateBehaviorDefaultAttitude(selection);
templates.put(selection, attitude);
}
if (attitude != null) {
attitude = attitude.copy();
setAttitudeValues(attitude, values);
attitude.setFile(file);
}
return attitude;
}
private Attitude generateBehaviorDefaultAttitude(String selection) {
return (selection != null)
? createAttitude(selection, context.createChild())
: null;
}
private void setAttitudeValues(Attitude attitude, Map<String, String> values) {
values.forEach((K, V) -> {
Parameter parameter = attitude.getParameter(K);
Object value = EParameterTypes.parseValue(parameter.getType(), V);
attitude.getParameter(K).setValue(value);
});
}
private Attitude createAttitude(String behaviorId, IEclipseContext context) {
BehaviorRegistry behaviorRegistry = behaviorService.getRegistry(behaviorId);
Attitude attitude = ContextInjectionFactory.make(Attitude.class, context);
attitude.setBehavior(behaviorId);
Arrays.stream(behaviorRegistry.getParametersIDs())
.map(behaviorRegistry::getParameterRegistry)
.forEach(parameterRegistry -> addParameter(attitude, parameterRegistry, context));
return attitude;
}
private void addParameter(Attitude attitude, ParameterRegistry parameterRegistry, IEclipseContext context) {
IEclipseContext staticContext = EclipseContextFactory.create();
injectAndSetInContext(parameterRegistry, staticContext);
Parameter parameter = ContextInjectionFactory.make(Parameter.class,
context, staticContext);
staticContext.dispose();
attitude.addParameter(parameter);
}
private void injectAndSetInContext(Object element, IEclipseContext context) {
ContextInjectionFactory.inject(element, context);
context.set(element.getClass().getName(), element);
}
}
@@ -0,0 +1,27 @@
package afryca.behavior.provider.internal;
import org.eclipse.e4.core.contexts.ContextFunction;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.model.application.MApplication;
import afryca.behavior.provider.IAttitudeProvider;
/**
* Attitude provider context function
*
* @author Sinbad²
* @version 3.0
*/
public class AttitudeProviderContextFunction extends ContextFunction {
@Override
public Object compute(IEclipseContext context, String contextKey) {
IAttitudeProvider attitudeProvider = ContextInjectionFactory.make(AttitudeDefaultProvider.class,
context);
MApplication application = context.get(MApplication.class);
IEclipseContext applicationContext = application.getContext();
applicationContext.set(IAttitudeProvider.class, attitudeProvider);
return attitudeProvider;
}
}
@@ -0,0 +1,53 @@
/**
*
*/
package afryca.behavior.provider.internal;
import javax.inject.Inject;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import afryca.behavior.Behavior;
import afryca.behavior.definition.BehaviorRegistry;
import afryca.behavior.definition.EElements;
import afryca.behavior.provider.IBehaviorProvider;
import afryca.behavior.service.IBehaviorService;
/**
* Behavior default provider
*
* @author Sinbad²
* @version 3.0
*/
public class BehaviorDefaultProvider implements IBehaviorProvider {
@Inject
private IBehaviorService behaviorService;
@Inject
private IEclipseContext context;
@Override
public Behavior createBehavior(String behaviorId) {
Behavior behavior = buildBehavior(behaviorId);
if (behavior != null) {
ContextInjectionFactory.inject(behavior, context);
}
return behavior;
}
public Behavior buildBehavior(String behaviorId) {
Behavior result = null;
try {
BehaviorRegistry behaviorRegistry = behaviorService.getRegistry(behaviorId);
IConfigurationElement configuration = behaviorRegistry.getConfiguration();
String className = EElements.Behavior.toString();
result = (Behavior) configuration.createExecutableExtension(className);
} catch (Exception e) {
result = null;
}
return result;
}
}
@@ -0,0 +1,27 @@
package afryca.behavior.provider.internal;
import org.eclipse.e4.core.contexts.ContextFunction;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.model.application.MApplication;
import afryca.behavior.provider.IBehaviorProvider;
/**
* Behavior provider context function
*
* @author Sinbad²
* @version 3.0
*/
public class BehaviorProviderContextFunction extends ContextFunction {
@Override
public Object compute(IEclipseContext context, String contextKey) {
IBehaviorProvider behaviorProvider = ContextInjectionFactory.make(BehaviorDefaultProvider.class,
context);
MApplication application = context.get(MApplication.class);
IEclipseContext applicationContext = application.getContext();
applicationContext.set(IBehaviorProvider.class, behaviorProvider);
return behaviorProvider;
}
}
@@ -0,0 +1,104 @@
package afryca.behavior.service;
import java.util.Map;
import afryca.behavior.Attitude;
import afryca.behavior.Behavior;
import afryca.behavior.definition.BehaviorRegistry;
/**
* Behavior service interface
*
* @author Sinbad²
* @version 3.0
*/
public interface IBehaviorService {
public static final String CONTEXT = "behavior.service.context"; //$NON-NLS-1$
public static final String ATTITUDES = "behavior.service.attitudes"; //$NON-NLS-1$
// Selected behavior
public static final String SELECTED_BEHAVIOR = "SELECTED BEHAVIOR"; //$NON-NLS-1$
/**
* Return all registers Ids
*
* @return Registers Ids
*/
String[] getIds();
/**
* Return a BehaviorRegistry
*
* @param id
* Id of the BehaviorRegistry
* @return BehaviorRegistry
*/
BehaviorRegistry getRegistry(String id);
/**
* Set behavior selection id
*
* @param id
* Behavior selection id
*/
void setSelection(String id);
/**
* Return behavior selection id
*
* @return Behavior selection id
*/
String getSelection();
/**
* Get a behavior
*
* @param id
* Behavior id
* @return The behavior
*/
Behavior getBehavior(String id);
/**
* Return attitudes
*
* @return Attitudes
*/
public Map<String, Attitude> getAttitudes();
/**
* Set behavior attitude
*
* @param attitude
* Behavior attitude
*/
void setAttitude(Attitude attitude);
/**
* Return current attitude
*
* @return current attitude
*/
Attitude getAttitude();
/**
* Return n changes
*
* @param behaviorId
* Behavior id
* @param numberOfchanges
* Number of changes to obtain
* @return N changes
*/
double[] getNChanges(String behaviorId, int numberOfChanges);
/**
* Return n changes
*
* @param numberOfChanges
* Number of changes to obtain
* @return N changes
*/
double[] getNChanges(int numberOfChanges);
}
@@ -0,0 +1,29 @@
package afryca.behavior.service.events;
import afryca.behavior.definition.EElements;
/**
* IBehaviorService events
*
* @author Sinbad²
* @version 3.0
*
* @noimplement Only used for constant definition
*/
public interface IBehaviorServiceEvents {
String TOPIC_BASE = "BEHAVIORS"; //$NON-NLS-1$
String BEHAVIOR_GROUP_UPDATES = TOPIC_BASE + "/GROUP_UPDATES"; //$NON-NLS-1$
String TOPIC_BEHAVIOR = "BEHAVIOR"; //$NON-NLS-1$
String BEHAVIORS_ALL = TOPIC_BASE + "/*"; //$NON-NLS-1$
String BEHAVIOR_SELECTION_UPDATED = TOPIC_BASE + "/" + TOPIC_BEHAVIOR + "/SELECTION"; //$NON-NLS-1$ //$NON-NLS-2$
String BEHAVIOR_ATTITUDE_UPDATED = TOPIC_BASE + "/" + TOPIC_BEHAVIOR + "/ATTITUDE"; //$NON-NLS-1$ //$NON-NLS-2$
String BEHAVIORS_UPDATED = TOPIC_BASE + "/UPDATED"; //$NON-NLS-1$
String FIELD_ID = EElements.id.name();
String FIELD_GROUPED = "grouped"; //$NON-NLS-1$
}
@@ -0,0 +1,25 @@
package afryca.behavior.service.provider;
import org.eclipse.e4.core.contexts.ContextFunction;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.model.application.MApplication;
import afryca.behavior.service.IBehaviorService;
/**
* Behavior service context function
*
* @author Sinbad²
* @version 3.0
*/
public class BehaviorServiceContextFunction extends ContextFunction {
@Override
public Object compute(IEclipseContext context, String contextKey) {
IBehaviorService behaviorService = ContextInjectionFactory.make(BehaviorServiceProvider.class, context);
MApplication application = context.get(MApplication.class);
IEclipseContext applicationContext = application.getContext();
applicationContext.set(IBehaviorService.class, behaviorService);
return behaviorService;
}
}
@@ -0,0 +1,284 @@
package afryca.behavior.service.provider;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.core.services.log.ILoggerProvider;
import org.eclipse.e4.core.services.log.Logger;
import org.eclipse.e4.core.services.nls.Translation;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.workbench.UIEvents;
import afryca.behavior.Behavior;
import afryca.behavior.Attitude;
import afryca.behavior.definition.BehaviorRegistry;
import afryca.behavior.definition.EElements;
import afryca.behavior.l10n.Messages;
import afryca.behavior.provider.IAttitudeProvider;
import afryca.behavior.provider.IBehaviorProvider;
import afryca.behavior.service.IBehaviorService;
import afryca.behavior.service.events.IBehaviorServiceEvents;
/**
* Behavior service provider
*
* @author Sinbad²
* @version 3.0
*/
@SuppressWarnings("restriction")
public class BehaviorServiceProvider implements IBehaviorService {
private Logger logger;
private Map<String, Attitude> attitudes;
private Map<String, BehaviorRegistry> registers;
private Map<String, Behavior> behaviors;
private IBehaviorProvider behaviorProvider;
private boolean groupUpdates;
private boolean needEnablementUpdate;
@Inject
private IEclipseContext context;
@Inject
private IEventBroker eventBroker;
@Inject
@Translation
private Messages messages;
@Inject
public void instantiateLogger(ILoggerProvider loggerProvider) {
logger = loggerProvider.getClassLogger(this.getClass());
}
@Inject
private void setAttitudes(@Optional @Named(ATTITUDES) Map<String, Attitude> attitudes) {
this.attitudes = attitudes;
}
@Inject
public BehaviorServiceProvider() {
registers = new HashMap<>();
behaviors = new HashMap<>();
groupUpdates = false;
needEnablementUpdate = false;
}
@PostConstruct
private void initialize() {
loadProviders();
loadRegisters();
setEclipseContext();
}
private void loadProviders() {
// It's not set until @PostConstruct does not end
context.set(IBehaviorService.class, this);
// Force providers' context function invoked in this context
behaviorProvider = context.get(IBehaviorProvider.class);
context.get(IAttitudeProvider.class);
}
private void loadRegisters() {
IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
IConfigurationElement[] extensionElements = extensionRegistry
.getConfigurationElementsFor(Behavior.EXTENSION_POINT);
logger.info(messages.x_defined_behaviors, extensionElements.length);
Arrays.stream(extensionElements).forEach(this::loadRegistry);
eventBroker.post(IBehaviorServiceEvents.BEHAVIORS_UPDATED, new HashMap<String, String>());
}
private void loadRegistry(IConfigurationElement extensionElement) {
BehaviorRegistry registry = new BehaviorRegistry(extensionElement);
String id = registry.getElement(EElements.id);
registers.put(id, registry);
logger.info(messages.behavior_loaded_x, id);
}
private void setEclipseContext() {
adaptContextForTracking();
getApplicationContext().set(CONTEXT, context);
}
private void adaptContextForTracking() {
context.declareModifiable(ATTITUDES);
}
@Override
public String[] getIds() {
return registers.keySet().toArray(new String[0]);
}
@Override
public BehaviorRegistry getRegistry(String id) {
return registers.get(id);
}
@Override
public void setSelection(String id) {
if (isNewSelection(id)) {
doGroupUpdateStep(() -> {
getApplicationContext().set(SELECTED_BEHAVIOR, id);
logger.info(messages.behavior_selected_x, id);
eventBroker.send(
IBehaviorServiceEvents.BEHAVIOR_SELECTION_UPDATED,
createEventData(
IBehaviorServiceEvents.BEHAVIOR_SELECTION_UPDATED,
IBehaviorServiceEvents.FIELD_ID,
id));
needEnablementUpdate = true;
});
}
}
private boolean isNewSelection(String newSelection) {
String oldSelection = getSelection();
if ((oldSelection == null) && (newSelection == null)) {
return false;
}
if ((oldSelection == null) || (newSelection == null)) {
return true;
}
return (!oldSelection.equals(newSelection));
}
private IEclipseContext getApplicationContext() {
MApplication application = context.get(MApplication.class);
return application.getContext();
}
private void doGroupUpdateStep(Runnable step) {
if (groupUpdates) {
step.run();
} else {
groupUpdatesActive(true);
step.run();
groupUpdatesActive(false);
}
}
private void groupUpdatesActive(boolean active) {
if (groupUpdates != active) {
groupUpdates = active;
eventBroker.send(
IBehaviorServiceEvents.BEHAVIOR_GROUP_UPDATES,
createEventData(
IBehaviorServiceEvents.BEHAVIOR_GROUP_UPDATES,
IBehaviorServiceEvents.FIELD_GROUPED,
Boolean.toString(groupUpdates)));
updateEnablement();
}
}
private Map<String, String> createEventData(String topic, String field, String value) {
Map<String, String> map = new HashMap<>();
map.put(IBehaviorServiceEvents.TOPIC_BASE, topic);
map.put(field, value);
return map;
}
private void updateEnablement() {
if (!groupUpdates && needEnablementUpdate) {
eventBroker.send(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC, UIEvents.ALL_ELEMENT_ID);
needEnablementUpdate = false;
}
}
@Override
public String getSelection() {
try {
return (String) getApplicationContext().get(SELECTED_BEHAVIOR);
} catch (Exception e) {
return null;
}
}
@Override
public Behavior getBehavior(String id) {
return behaviors.containsKey(id) ? behaviors.get(id) : initBehavior(id);
}
private Behavior initBehavior(String id) {
Behavior behavior = behaviorProvider.createBehavior(id);
if (behavior != null) {
behaviors.put(id, behavior);
}
return behavior;
}
@Override
public Map<String, Attitude> getAttitudes() {
return attitudes;
}
@Override
public void setAttitude(Attitude attitude) {
if (isNewAttitude(attitude)) {
doGroupUpdateStep(() -> {
getApplicationContext().set(Attitude.class, attitude);
logger.info(messages.behavior_attitude_updated);
eventBroker.send(
IBehaviorServiceEvents.BEHAVIOR_ATTITUDE_UPDATED,
createEventData(
IBehaviorServiceEvents.BEHAVIOR_ATTITUDE_UPDATED,
null,
null));
needEnablementUpdate = true;
});
}
}
private boolean isNewAttitude(Attitude newAttitude) {
Attitude currentAttitude = getAttitude();
if ((currentAttitude == null) && (newAttitude == null)) {
return false;
}
if ((currentAttitude == null) || (newAttitude == null)) {
return true;
}
return !currentAttitude.equals(newAttitude);
}
@Override
public Attitude getAttitude() {
try {
return (Attitude) getApplicationContext().get(Attitude.class);
} catch (Exception e) {
return null;
}
}
@Override
public double[] getNChanges(String behaviorId, int numberOfChanges) {
Behavior behavior = getBehavior(behaviorId);
IEclipseContext behaviorContext = behavior.getContext();
behaviorContext.set(Attitude.class, getAttitude());
return behavior.getNChanges(numberOfChanges);
}
@Override
public double[] getNChanges(int numberOfChanges) {
return getNChanges(getSelection(), numberOfChanges);
}
}
@@ -0,0 +1,20 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: afryca.behavior;singleton:=true
Bundle-Version: 1.0.0.202101221157
Bundle-Vendor: %Bundle-Vendor
Export-Package: afryca.behavior,afryca.behavior.command,afryca.behavior.
definition,afryca.behavior.provider,afryca.behavior.service,afryca.beha
vior.service.events
Require-Bundle: afryca.ase,afryca.parametervalueconverterhelper,javax.in
ject,org.apache.commons.io,org.eclipse.core.runtime,org.eclipse.e4.core
.di,org.eclipse.e4.core.services,org.eclipse.e4.core.contexts,org.eclip
se.e4.ui.workbench,org.eclipse.e4.ui.model.workbench,org.eclipse.ui
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Service-Component: OSGI-INF/behavior_service_context_function.xml,OSGI-I
NF/attitude_provider_context_function.xml,OSGI-INF/behavior_provider_co
ntext_function.xml
Bundle-ActivationPolicy: lazy
Automatic-Module-Name: afryca.behavior
@@ -0,0 +1,10 @@
behavior_attitude_updated=Behavior attitude updated
behavior_loaded_x=Behavior loaded {0}
behavior_selected_x=Behavior selected {0}
command_executed={0} executed
invalid_arguments=Invalid arguments
invalid_type=Invalid type
value_is_greater_than_lower_limit=Value is greater than upper limit
value_is_lower_than_lower_limit=Value is lower than lower limit
wrong_file=wrong file
x_defined_behaviors={0} defined behaviors
@@ -0,0 +1,10 @@
behavior_attitude_updated=Actitud de comportamiento actualizada
behavior_loaded_x=Comportamiento cargado {0}
behavior_selected_x=Comportamiento seleccionado {0}
command_executed={0} ejecutado
invalid_arguments=Argumentos inválidos
invalid_type=Tipo inválido
value_is_greater_than_lower_limit=El valor es mayor que el límite superior
value_is_lower_than_lower_limit=El valor es menor que el límite inferior
wrong_file=archivo inválido
x_defined_behaviors={0} comportamientos definidos
@@ -0,0 +1,4 @@
#Fri Jan 22 13:00:22 CET 2021
artifact.main=C\:\\Users\\\u00C1lvaro\\Workspaces\\afryca_2020\\afryca\\plugins\\afryca.behavior\\target\\afryca.behavior-1.0.0-SNAPSHOT.jar
artifact.attached.p2artifacts=C\:\\Users\\\u00C1lvaro\\Workspaces\\afryca_2020\\afryca\\plugins\\afryca.behavior\\target\\p2artifacts.xml
artifact.attached.p2metadata=C\:\\Users\\\u00C1lvaro\\Workspaces\\afryca_2020\\afryca\\plugins\\afryca.behavior\\target\\p2content.xml
@@ -0,0 +1,3 @@
artifactId=afryca.behavior
groupId=afryca.group
version=1.0.0-SNAPSHOT
@@ -0,0 +1,13 @@
<?xml version='1.0' encoding='UTF-8'?>
<?artifactRepository version='1.1.0'?>
<artifacts size='1'>
<artifact classifier='osgi.bundle' id='afryca.behavior' version='1.0.0.202101221157'>
<properties size='5'>
<property name='artifact.size' value='44848'/>
<property name='download.size' value='44848'/>
<property name='maven-groupId' value='afryca.group'/>
<property name='maven-artifactId' value='afryca.behavior'/>
<property name='maven-version' value='1.0.0-SNAPSHOT'/>
</properties>
</artifact>
</artifacts>
@@ -0,0 +1,64 @@
<?xml version='1.0' encoding='UTF-8'?>
<units size='1'>
<unit id='afryca.behavior' version='1.0.0.202101221157' generation='2'>
<update id='afryca.behavior' range='[0.0.0,1.0.0.202101221157)' severity='0'/>
<properties size='9'>
<property name='es.Bundle-Name' value='Comportamiento'/>
<property name='es.Bundle-Vendor' value='Sinbad²'/>
<property name='df_LT.Bundle-Name' value='Behavior'/>
<property name='df_LT.Bundle-Vendor' value='Sinbad²'/>
<property name='org.eclipse.equinox.p2.name' value='%Bundle-Name'/>
<property name='org.eclipse.equinox.p2.provider' value='%Bundle-Vendor'/>
<property name='maven-groupId' value='afryca.group'/>
<property name='maven-artifactId' value='afryca.behavior'/>
<property name='maven-version' value='1.0.0-SNAPSHOT'/>
</properties>
<provides size='12'>
<provided namespace='org.eclipse.equinox.p2.iu' name='afryca.behavior' version='1.0.0.202101221157'/>
<provided namespace='osgi.bundle' name='afryca.behavior' version='1.0.0.202101221157'/>
<provided namespace='java.package' name='afryca.behavior' version='0.0.0'/>
<provided namespace='java.package' name='afryca.behavior.command' version='0.0.0'/>
<provided namespace='java.package' name='afryca.behavior.definition' version='0.0.0'/>
<provided namespace='java.package' name='afryca.behavior.provider' version='0.0.0'/>
<provided namespace='java.package' name='afryca.behavior.service' version='0.0.0'/>
<provided namespace='java.package' name='afryca.behavior.service.events' version='0.0.0'/>
<provided namespace='osgi.identity' name='afryca.behavior' version='1.0.0.202101221157'>
<properties size='1'>
<property name='type' value='osgi.bundle'/>
</properties>
</provided>
<provided namespace='org.eclipse.equinox.p2.eclipse.type' name='bundle' version='1.0.0'/>
<provided namespace='org.eclipse.equinox.p2.localization' name='es' version='1.0.0'/>
<provided namespace='org.eclipse.equinox.p2.localization' name='df_LT' version='1.0.0'/>
</provides>
<requires size='12'>
<required namespace='osgi.bundle' name='afryca.ase' range='0.0.0'/>
<required namespace='osgi.bundle' name='afryca.parametervalueconverterhelper' range='0.0.0'/>
<required namespace='osgi.bundle' name='javax.inject' range='0.0.0'/>
<required namespace='osgi.bundle' name='org.apache.commons.io' range='0.0.0'/>
<required namespace='osgi.bundle' name='org.eclipse.core.runtime' range='0.0.0'/>
<required namespace='osgi.bundle' name='org.eclipse.e4.core.di' range='0.0.0'/>
<required namespace='osgi.bundle' name='org.eclipse.e4.core.services' range='0.0.0'/>
<required namespace='osgi.bundle' name='org.eclipse.e4.core.contexts' range='0.0.0'/>
<required namespace='osgi.bundle' name='org.eclipse.e4.ui.workbench' range='0.0.0'/>
<required namespace='osgi.bundle' name='org.eclipse.e4.ui.model.workbench' range='0.0.0'/>
<required namespace='osgi.bundle' name='org.eclipse.ui' range='0.0.0'/>
<requiredProperties namespace='osgi.ee' match='(&amp;(osgi.ee=JavaSE)(version=1.8))'>
<description>
afryca.behavior
</description>
</requiredProperties>
</requires>
<artifacts size='1'>
<artifact classifier='osgi.bundle' id='afryca.behavior' version='1.0.0.202101221157'/>
</artifacts>
<touchpoint id='org.eclipse.equinox.p2.osgi' version='1.0.0'/>
<touchpointData size='1'>
<instructions size='1'>
<instruction key='manifest'>
Bundle-SymbolicName: afryca.behavior;singleton:=true&#xA;Bundle-Version: 1.0.0.202101221157&#xA;
</instruction>
</instructions>
</touchpointData>
</unit>
</units>