Skip to content

Commit

Permalink
getService and getServiceEClass to provider models (eclipse#382)
Browse files Browse the repository at this point in the history
* getService and getServiceEClass to provider model

Signed-off-by: Guido Grune <g.grune@datainmotion.com>

* Fix spaces

Signed-off-by: Guido Grune <g.grune@datainmotion.com>

---------

Signed-off-by: Guido Grune <g.grune@datainmotion.com>
  • Loading branch information
gg-dim committed Apr 16, 2024
1 parent 86b14ca commit 28e77ce
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ public void unlinkProviders(String parentProvider, String childProvider, Instant
public void handleDataUpdate(Provider provider, String serviceName, EStructuralFeature resourceFeature, Object data,
Instant timestamp) {

Service service = getServiceFromProvider(serviceName, provider);
Service service = provider.getService(serviceName);
if (service == null) {
Optional<EReference> serviceFeature = getServiceReferencesForModel(provider.eClass())
.filter(ref -> serviceName.equals(ref.getName())).findFirst();
Expand Down Expand Up @@ -690,7 +690,7 @@ public Map<String, Object> getResourceMetadata(Service svc, final ETypedElement

public Map<String, Object> getResourceMetadata(Provider provider, String serviceName,
final ETypedElement rcFeature) {
Service svc = getServiceFromProvider(serviceName, provider);
Service svc = provider.getService(serviceName);
return getResourceMetadata(svc, rcFeature);
}

Expand All @@ -702,7 +702,7 @@ private Map<String, Object> toMetadataMap(final ETypedElement rcFeature, final R

public TimedValue<Object> getResourceMetadataValue(Provider provider, String serviceName,
final ETypedElement rcFeature, String key) {
final Service svc = getServiceFromProvider(serviceName, provider);
final Service svc = provider.getService(serviceName);
if (svc == null) {
return null;
}
Expand Down Expand Up @@ -897,9 +897,7 @@ public EOperation createActionResource(EClass serviceEClass, String name, Class<
List<ActionParameter> params = namedParameterTypes.stream().map(EMFUtil::createActionParameter)
.collect(Collectors.toList());

Action action = EMFUtil.createAction(serviceEClass, name, type, params);

return action;
return EMFUtil.createAction(serviceEClass, name, type, params);
}

/**
Expand Down Expand Up @@ -1151,7 +1149,6 @@ private String validateAndGetName(Provider provider) {
}

return id;

}

public Provider getProvider(EClass model, String id) {
Expand Down Expand Up @@ -1204,19 +1201,4 @@ public void removeEPackage(EPackage ePackage) {
.forEach(p -> doDeleteProvider(ePackage.getNsURI(), EMFUtil.getModelName(p.eClass()), p.getId()));
}
}

/**
* @return the Service either from a Reference or from the dynamic service list.
*/
public Service getServiceFromProvider(String serviceName, Provider provider) {

EStructuralFeature eStructuralFeature = provider.eClass().getEStructuralFeature(serviceName);
if (eStructuralFeature == null) {
if (provider instanceof DynamicProvider) {
return ((DynamicProvider) provider).getServices().get(serviceName);
}
return null;
}
return (Service) provider.eGet(eStructuralFeature);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import java.util.stream.Stream;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.emf.ecore.EcorePackage;
Expand All @@ -37,7 +36,6 @@
import org.eclipse.sensinact.core.snapshot.ProviderSnapshot;
import org.eclipse.sensinact.core.snapshot.ResourceSnapshot;
import org.eclipse.sensinact.core.snapshot.ServiceSnapshot;
import org.eclipse.sensinact.core.twin.SensinactProvider;
import org.eclipse.sensinact.core.twin.SensinactResource;
import org.eclipse.sensinact.core.twin.SensinactService;
import org.eclipse.sensinact.core.twin.TimedValue;
Expand Down Expand Up @@ -161,18 +159,16 @@ public SensinactService getService(String model, String providerName, String ser
return getService(null, model, providerName, service);
}

private SensinactServiceImpl getService(Provider provider, String model, String service) {
private SensinactServiceImpl getService(Provider provider, String model, String serviceName) {
if (provider == null) {
return null;
}

final EStructuralFeature svcFeature = provider.eClass().getEStructuralFeature(service);
if (svcFeature == null) {
EClass serviceType = provider.getServiceEClass(serviceName);
if (serviceType == null) {
return null;
}

final SensinactProviderImpl snProvider = toProvider(provider);
return toService(snProvider, provider, (EReference) svcFeature);
return toService(provider, serviceName, serviceType, snProvider);
}

/*
Expand Down Expand Up @@ -200,18 +196,15 @@ public SensinactResourceImpl getResource(String providerName, String service, St
return getResource(provider, nexusImpl.getProviderModel(providerName), service, resource);
}

private SensinactResourceImpl getResource(Provider provider, String model, String service, String resource) {
private SensinactResourceImpl getResource(Provider provider, String model, String serviceName, String resource) {
if (provider == null) {
return null;
}

final EReference svcFeature = (EReference) provider.eClass().getEStructuralFeature(service);
if (svcFeature == null) {
final EClass serviceEClass = provider.getServiceEClass(serviceName);
if (serviceEClass == null) {
return null;
}

final EClass serviceEClass = svcFeature.getEReferenceType();

final ETypedElement rcFeature = Optional.ofNullable(serviceEClass.getEStructuralFeature(resource))
.map(ETypedElement.class::cast)
.or(() -> serviceEClass.getEOperations().stream()
Expand All @@ -224,8 +217,8 @@ private SensinactResourceImpl getResource(Provider provider, String model, Strin

// Construct the resource
final SensinactProviderImpl snProvider = toProvider(provider);
final SensinactServiceImpl snSvc = toService(snProvider, provider, svcFeature);
return toResource(snSvc, provider, svcFeature, rcFeature);
final SensinactServiceImpl snService = toService(provider, serviceName, serviceEClass, snProvider);
return toResource(snService, provider, serviceName, rcFeature);
}

public <T> TimedValue<T> getResourceValue(String modelPackageUri, String model, String providerName, String service,
Expand All @@ -239,7 +232,7 @@ public <T> TimedValue<T> getResourceValue(String providerName, String service, S
return getResourceValue(nexusImpl.getProvider(providerName), service, resource, type);
}

private <T> TimedValue<T> getResourceValue(Provider provider, String service, String resource, Class<T> type) {
private <T> TimedValue<T> getResourceValue(Provider provider, String serviceName, String resource, Class<T> type) {
if (type == null) {
throw new IllegalArgumentException("Resource type must not be null");
}
Expand All @@ -248,14 +241,12 @@ private <T> TimedValue<T> getResourceValue(Provider provider, String service, St
return null;
}

final EStructuralFeature svcFeature = provider.eClass().getEStructuralFeature(service);
if (svcFeature == null) {
final Service svc = provider.getService(serviceName);
if (svc == null) {
return null;
}
final Service svc = (Service) provider.eGet(svcFeature);

final EStructuralFeature rcFeature = svc.eClass().getEStructuralFeature(resource);

if (rcFeature == null) {
return null;
}
Expand Down Expand Up @@ -285,15 +276,15 @@ private SensinactProviderImpl toProvider(final Provider modelProvider) {
return new SensinactProviderImpl(active, modelProvider, nexusImpl, pf);
}

private SensinactServiceImpl toService(final SensinactProvider parent, Provider provider, EReference ref) {
return new SensinactServiceImpl(active, parent, provider, ref.getName(), ref.getEReferenceType(), nexusImpl,
pf);
private SensinactResourceImpl toResource(final SensinactService parent, Provider provider, String serviceName,
final ETypedElement rcFeature) {
return new SensinactResourceImpl(active, parent, provider, serviceName, rcFeature,
rcFeature.getEType().getInstanceClass(), nexusImpl, pf);
}

private SensinactResourceImpl toResource(final SensinactService parent, Provider provider, EReference svcFeature,
final ETypedElement rcFeature) {
return new SensinactResourceImpl(active, parent, provider, svcFeature.getName(),
rcFeature, rcFeature.getEType().getInstanceClass(), nexusImpl, pf);
private SensinactServiceImpl toService(Provider provider, String serviceName, final EClass serviceEClass,
final SensinactProviderImpl snProvider) {
return new SensinactServiceImpl(active, snProvider, provider, serviceName, serviceEClass, nexusImpl, pf);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public String getName() {
private <T> TimedValue<T> getValueFromTwin(final Class<T> type) {
final Instant currentTimestamp;
final T currentValue;
final Service svc = modelNexus.getServiceFromProvider(serviceName, provider);
final Service svc = provider.getService(serviceName);
if (svc != null) {
// Service is there
final Object rawValue = svc.eGet((EAttribute) resource);
Expand Down
24 changes: 24 additions & 0 deletions core/models/provider/src/main/resources/model/sensinact.ecore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@
<details key="ecore" value="http://www.eclipse.org/emf/2002/Ecore"/>
</eAnnotations>
<eClassifiers xsi:type="ecore:EClass" name="Provider">
<eOperations name="getService" eType="#//Service">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="body" value="EStructuralFeature serviceFeature = eClass().getEStructuralFeature(serviceName);&#xA;if (serviceFeature instanceof &lt;%org.eclipse.emf.ecore.EReference%>) {&#xA;&#x9;EClass refEClass = ((EReference) serviceFeature).getEReferenceType();&#xA;&#x9;return ProviderPackage.Literals.SERVICE.isSuperTypeOf(refEClass) ? (Service) eGet(serviceFeature) : null;&#xA;}&#xA;return null;"/>
</eAnnotations>
<eParameters name="serviceName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eOperations>
<eOperations name="getServiceEClass" eType="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EClass">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="body" value="&lt;%org.eclipse.emf.ecore.EStructuralFeature%> serviceFeature = eClass().getEStructuralFeature(serviceName);&#xA;if (serviceFeature instanceof &lt;%org.eclipse.emf.ecore.EReference%>) {&#xA;&#x9;&lt;%org.eclipse.emf.ecore.EClass%> refEClass = ((EReference) serviceFeature).getEReferenceType();&#xA;&#x9;return ProviderPackage.Literals.SERVICE.isSuperTypeOf(refEClass) ? refEClass : null;&#xA;}&#xA;return null;"/>
</eAnnotations>
<eParameters name="serviceName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eOperations>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="id" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
unsettable="true" iD="true"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="admin" eType="#//Admin"
Expand Down Expand Up @@ -67,6 +79,18 @@
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="To achieve a good Model, concrete EClasses that inherit from Provider should &#xA;use References for predefined Services.&#xA;Sometimes however you can't know how many Services a Provider can have. &#xA;In such a case, this Map can be used in addtion to directly Referenced Services.&#xA;&#xA;As an example: Such a Provider can be a Camera that can detect Objects like cars, &#xA;bikes or pedestriance in configureable zones. Each zone can in this case be a &#xA;Service with defined Resources. How may zones exist however, depdends on the &#xA;configuration. Thus our camera model can benefit from service map in addition&#xA;some predefined fix services it might have.&#xA;&#xA;Service names must still be unique and must not collide with existing References.&#xA;"/>
</eAnnotations>
<eOperations name="getService" eType="#//Service">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="body" value="Service service = super.getService(serviceName);&#xA;return service != null ? service : getServices().get(serviceName);"/>
</eAnnotations>
<eParameters name="serviceName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eOperations>
<eOperations name="getServiceEClass" eType="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EClass">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="body" value="EClass serviceType = super.getServiceEClass(serviceName);&#xA;return serviceType != null ? serviceType : getServices().get(serviceName).eClass();"/>
</eAnnotations>
<eParameters name="serviceName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eOperations>
<eStructuralFeatures xsi:type="ecore:EReference" name="services" upperBound="-1"
eType="#//ServiceMap" containment="true">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
Expand Down
21 changes: 21 additions & 0 deletions core/models/provider/src/main/resources/model/sensinact.genmodel
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,19 @@
<genDataTypes ecoreDataType="sensinact.ecore#//EInstant" create="return Instant.parse(it);"
convert="return it.toString();"/>
<genClasses ecoreClass="sensinact.ecore#//Provider">
<genAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="body" value="org.eclipse.emf.ecore.EStructuralFeature serviceFeature = eClass().getEStructuralFeature(service);\nreturn serviceFeature != null ? (Service) eGet(serviceFeature) : null;"/>
</genAnnotations>
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute sensinact.ecore#//Provider/id"/>
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference sensinact.ecore#//Provider/admin"/>
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference sensinact.ecore#//Provider/linkedProviders"/>
<genOperations ecoreOperation="sensinact.ecore#//Provider/getService" body="EStructuralFeature serviceFeature = eClass().getEStructuralFeature(serviceName);&#xA;if (serviceFeature instanceof &lt;%org.eclipse.emf.ecore.EReference%>) {&#xA;&#x9;EClass refEClass = ((EReference) serviceFeature).getEReferenceType();&#xA;&#x9;return ProviderPackage.Literals.SERVICE.isSuperTypeOf(refEClass) ? (Service) eGet(serviceFeature) : null;&#xA;}&#xA;return null;">
<genParameters ecoreParameter="sensinact.ecore#//Provider/getService/serviceName"/>
</genOperations>
<genOperations ecoreOperation="sensinact.ecore#//Provider/getServiceEClass"
body="&lt;%org.eclipse.emf.ecore.EStructuralFeature%> serviceFeature = eClass().getEStructuralFeature(serviceName);&#xA;if (serviceFeature instanceof &lt;%org.eclipse.emf.ecore.EReference%>) {&#xA;&#x9;&lt;%org.eclipse.emf.ecore.EClass%> refEClass = ((EReference) serviceFeature).getEReferenceType();&#xA;&#x9;return ProviderPackage.Literals.SERVICE.isSuperTypeOf(refEClass) ? refEClass : null;&#xA;}&#xA;return null;">
<genParameters ecoreParameter="sensinact.ecore#//Provider/getServiceEClass/serviceName"/>
</genOperations>
</genClasses>
<genClasses ecoreClass="sensinact.ecore#//Admin">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute sensinact.ecore#//Admin/friendlyName"/>
Expand Down Expand Up @@ -59,7 +69,18 @@
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute sensinact.ecore#//ServiceMap/key"/>
</genClasses>
<genClasses ecoreClass="sensinact.ecore#//DynamicProvider">
<genAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="body" value="return getServices().get(service);"/>
</genAnnotations>
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference sensinact.ecore#//DynamicProvider/services"/>
<genOperations ecoreOperation="sensinact.ecore#//DynamicProvider/getService"
body="Service service = super.getService(serviceName);&#xA;return service != null ? service : getServices().get(serviceName);">
<genParameters ecoreParameter="sensinact.ecore#//DynamicProvider/getService/serviceName"/>
</genOperations>
<genOperations ecoreOperation="sensinact.ecore#//DynamicProvider/getServiceEClass"
body="EClass serviceType = super.getServiceEClass(serviceName);&#xA;return serviceType != null ? serviceType : getServices().get(serviceName).eClass();">
<genParameters ecoreParameter="sensinact.ecore#//DynamicProvider/getServiceEClass/serviceName"/>
</genOperations>
</genClasses>
</genPackages>
</genmodel:GenModel>

0 comments on commit 28e77ce

Please sign in to comment.