From 38814e02d9b91cf80148524de24bef80f155f3b2 Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Mon, 21 Nov 2022 13:07:09 +0100
Subject: [PATCH] MAINT: clean-up CaosDBToGrpcConverters

---
 caosdb-proto                                  |   2 +-
 .../server/grpc/CaosDBToGrpcConverters.java   | 199 ++++++++----------
 2 files changed, 90 insertions(+), 111 deletions(-)

diff --git a/caosdb-proto b/caosdb-proto
index 96e7a1fb..13d083b8 160000
--- a/caosdb-proto
+++ b/caosdb-proto
@@ -1 +1 @@
-Subproject commit 96e7a1fb667ed1bb3b2602af6c69724519bf5118
+Subproject commit 13d083b84400507f6f1967a099e2af006af2a231
diff --git a/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java b/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java
index 75abb312..6fef5907 100644
--- a/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java
+++ b/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java
@@ -617,34 +617,49 @@ public class CaosDBToGrpcConverters {
     return result;
   }
 
-  private org.caosdb.api.entity.v1.Value.Builder getSelectedValue(Selection s, EntityInterface e) {
-    org.caosdb.api.entity.v1.Value.Builder result = org.caosdb.api.entity.v1.Value.newBuilder();
-    String selector = s.getSelector();
+  /**
+   * Handle special selectors like "id", "name", "value", "parent",...
+   *
+   * @return a {@link org.caosdb.api.entity.v1.Value.Builder}, if the selector has been handled.
+   *     Return null when the caller must handle the selector otherwise.
+   */
+  private org.caosdb.api.entity.v1.Value.Builder handleSpecialSelectors(
+      String selector, EntityInterface e) {
+    org.caosdb.api.entity.v1.Value.Builder result = null;
     switch (selector) {
       case "value":
+        try {
+          e.parseValue();
+        } catch (Message m) {
+          throw new TransactionException(m);
+        }
         if (e.hasValue()) {
           return convert(e.getValue());
         }
         break;
       case "version":
         if (e.hasVersion()) {
+          result = org.caosdb.api.entity.v1.Value.newBuilder();
           result.setScalarValue(convertStringValue(e.getVersion().getId()));
           return result;
         }
         break;
       case "name":
         if (e.hasName()) {
+          result = org.caosdb.api.entity.v1.Value.newBuilder();
           result.setScalarValue(convertStringValue(e.getName()));
           return result;
         }
         break;
 
       case "id":
+        result = org.caosdb.api.entity.v1.Value.newBuilder();
         result.setScalarValue(convertStringValue(e.getId().toString()));
         return result;
 
       case "description":
         if (e.hasDescription()) {
+          result = org.caosdb.api.entity.v1.Value.newBuilder();
           result.setScalarValue(convertStringValue(e.getDescription()));
           return result;
         }
@@ -653,24 +668,28 @@ public class CaosDBToGrpcConverters {
       case "unit":
         final String unit = getStringUnit(e);
         if (unit != null) {
+          result = org.caosdb.api.entity.v1.Value.newBuilder();
           result.setScalarValue(convertStringValue(unit));
           return result;
         }
         break;
       case "datatype":
         if (e.hasDatatype()) {
+          result = org.caosdb.api.entity.v1.Value.newBuilder();
           result.setScalarValue(convertStringValue(e.getDatatype().toString()));
           return result;
         }
         break;
       case "path":
         if (e.hasFileProperties() && e.getFileProperties().hasPath()) {
+          result = org.caosdb.api.entity.v1.Value.newBuilder();
           result.setScalarValue(convertStringValue(e.getFileProperties().getPath()));
           return result;
         }
         break;
       case "parent":
         if (e.hasParents()) {
+          result = org.caosdb.api.entity.v1.Value.newBuilder();
           CollectionValues.Builder parents = CollectionValues.newBuilder();
           for (org.caosdb.server.entity.wrapper.Parent p : e.getParents()) {
             parents.addValues(ScalarValue.newBuilder().setStringValue(p.getName()));
@@ -680,127 +699,87 @@ public class CaosDBToGrpcConverters {
         }
         break;
       default:
-        // selector for a normal property
-        List<org.caosdb.api.entity.v1.Value.Builder> results = new LinkedList<>();
-        for (Property p : e.getProperties()) {
-          if (p.getName() != null && p.getName().equals(selector)) {
-            if (s.getSubselection() == null) {
-              // no subselection -> just return the actual value
-              try {
-                p.parseValue();
-              } catch (Message m) {
-                throw new TransactionException(m);
-              }
-
-              results.add(convert(p.getValue()));
-            } else {
-              // with subselection, e.g. p1.unit, site.geolocation.longitude
-              switch (s.getSubselection().getSelector()) {
-                case "name":
-                  if (p.hasName()) {
-                    result = org.caosdb.api.entity.v1.Value.newBuilder();
-                    result.setScalarValue(convertStringValue(p.getName()));
-                    results.add(result);
-                  }
-                  break;
-
-                case "id":
-                  result = org.caosdb.api.entity.v1.Value.newBuilder();
-                  result.setScalarValue(convertStringValue(p.getId().toString()));
-                  results.add(result);
-                  break;
-
-                case "version":
-                  if (p.hasVersion()) {
-                    result.setScalarValue(convertStringValue(p.getVersion().getId()));
-                    return result;
-                  }
-                  break;
-
-                case "description":
-                  if (p.hasDescription()) {
-                    result = org.caosdb.api.entity.v1.Value.newBuilder();
-                    result.setScalarValue(convertStringValue(p.getDescription()));
-                    results.add(result);
-                  }
-                  break;
-
-                case "unit":
-                  final String property_unit = getStringUnit(p);
-                  if (property_unit != null) {
-                    result = org.caosdb.api.entity.v1.Value.newBuilder();
-                    result.setScalarValue(convertStringValue(property_unit));
-                    results.add(result);
-                  }
-                  break;
+        break;
+    }
+    return null;
+  }
 
-                case "datatype":
-                  if (p.hasDatatype()) {
-                    result = org.caosdb.api.entity.v1.Value.newBuilder();
-                    result.setScalarValue(convertStringValue(p.getDatatype().toString()));
-                    results.add(result);
-                  }
-                  break;
-                case "value":
-                  if (p.hasValue()) {
-                    try {
-                      p.parseValue();
-                    } catch (Message m) {
-                      throw new TransactionException(m);
-                    }
-                    result = org.caosdb.api.entity.v1.Value.newBuilder();
-                    result = convert(p.getValue());
-                    results.add(result);
-                  }
-                  break;
-                default:
-                  // normal property
-                  Value v = p.getValue();
+  private org.caosdb.api.entity.v1.Value.Builder getSelectedValue(Selection s, EntityInterface e) {
+    org.caosdb.api.entity.v1.Value.Builder result = null;
+    String selector = s.getSelector();
+    result = handleSpecialSelectors(selector, e);
+    if (result == null) {
+      // selector for a normal property
+      List<org.caosdb.api.entity.v1.Value.Builder> results = new LinkedList<>();
+      for (Property p : e.getProperties()) {
+        if (p.getName() != null && p.getName().equals(selector)) {
+          if (s.getSubselection() == null) {
+            // no subselection -> just return the actual value
+            try {
+              p.parseValue();
+            } catch (Message m) {
+              throw new TransactionException(m);
+            }
 
-                  if (v instanceof ReferenceValue) {
-                    EntityInterface referenced_entity = ((ReferenceValue) v).getEntity();
+            results.add(convert(p.getValue()));
+          } else {
+            // with subselection, e.g. p1.unit, site.geolocation.longitude
+            String subselection = s.getSubselection().getSelector();
+            result = handleSpecialSelectors(subselection, p);
+            if (result == null) {
+              // normal property
+              Value v = p.getValue();
+
+              if (v instanceof ReferenceValue) {
+                EntityInterface referenced_entity = ((ReferenceValue) v).getEntity();
+                result = getSelectedValue(s.getSubselection(), referenced_entity);
+              } else if (v instanceof CollectionValue) {
+                for (Value i : (CollectionValue) v) {
+                  if (i instanceof ReferenceValue) {
+                    EntityInterface referenced_entity = ((ReferenceValue) i).getEntity();
                     result = getSelectedValue(s.getSubselection(), referenced_entity);
                     results.add(result);
-                  } else if (v instanceof CollectionValue) {
-                    for (Value i : (CollectionValue) v) {
-                      if (i instanceof ReferenceValue) {
-                        EntityInterface referenced_entity = ((ReferenceValue) i).getEntity();
-                        result = getSelectedValue(s.getSubselection(), referenced_entity);
-                        results.add(result);
-                      } else {
-                        // Non-reference scalar value
-                        result = getSelectedValue(s.getSubselection(), p);
-                        results.add(result);
-                      }
-                    }
                   } else {
-                    // Actual sub-property
+                    // Non-reference scalar value
                     result = getSelectedValue(s.getSubselection(), p);
                     results.add(result);
                   }
-                  break;
+                }
+              } else {
+                // Actual sub-property
+                result = getSelectedValue(s.getSubselection(), p);
+                results.add(result);
               }
+
+            } else {
+              results.add(result);
             }
           }
         }
-        if (results.size() > 1) {
-          // There have been multiple matching properties
-          CollectionValues.Builder values = CollectionValues.newBuilder();
-          for (org.caosdb.api.entity.v1.Value.Builder v : results) {
-            // Concatenate all found values to a list
-            if (v.hasScalarValue()) {
-              values.addValues(v.getScalarValueBuilder());
-            } else {
-              values.addAllValues(v.getListValuesBuilder().getValuesList());
-            }
+      }
+
+      if (results.size() > 1) {
+        // There have been multiple matching properties
+        CollectionValues.Builder values = CollectionValues.newBuilder();
+        for (org.caosdb.api.entity.v1.Value.Builder v : results) {
+          // Concatenate all found values to a list
+          if (v.hasScalarValue()) {
+            values.addValues(v.getScalarValueBuilder());
+          } else {
+            values.addAllValues(v.getListValuesBuilder().getValuesList());
           }
-          result = org.caosdb.api.entity.v1.Value.newBuilder();
-          result.setListValues(values);
-        } else if (results.size() == 1) {
-          // There has been exactly one matching property
-          result = results.get(0);
         }
-        return result;
+        result = org.caosdb.api.entity.v1.Value.newBuilder();
+        result.setListValues(values);
+      } else if (results.size() == 1) {
+        // There has been exactly one matching property
+        result = results.get(0);
+      }
+    }
+
+    if (result == null) {
+      // no matching property found
+      result = org.caosdb.api.entity.v1.Value.newBuilder();
     }
     return result;
   }
-- 
GitLab