This is an automated email from the ASF dual-hosted git repository.

ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git


The following commit(s) were added to refs/heads/master by this push:
     new 3b0d1440b CAY-2833 Unify code related to the Cayenne model paths 
processing
3b0d1440b is described below

commit 3b0d1440b375da35437c25b2a1cfa2b13aaaabb9
Author: Nikita Timofeev <stari...@gmail.com>
AuthorDate: Tue Feb 27 15:49:29 2024 +0400

    CAY-2833 Unify code related to the Cayenne model paths processing
---
 .../access/HierarchicalObjectResolverNode.java     |  3 ++-
 .../access/JoinedIdParentAttachmentStrategy.java   |  6 ++---
 .../org/apache/cayenne/access/ObjectResolver.java  | 26 +++++++++-------------
 .../org/apache/cayenne/access/ObjectStore.java     |  9 ++++----
 .../access/flush/ArcValuesCreationHandler.java     | 12 +++-------
 .../cayenne/access/flush/operation/Values.java     |  9 ++++----
 .../apache/cayenne/reflect/ClassDescriptor.java    |  3 ++-
 .../reflect/LazyClassDescriptorDecorator.java      |  3 ++-
 .../cayenne/reflect/PersistentDescriptor.java      |  7 +++---
 .../reflect/PersistentDescriptorFactory.java       | 19 ++++++----------
 10 files changed, 43 insertions(+), 54 deletions(-)

diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolverNode.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolverNode.java
index b3de306ed..acc6c1f76 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolverNode.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolverNode.java
@@ -22,6 +22,7 @@ import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.Persistent;
+import org.apache.cayenne.exp.path.CayennePath;
 import org.apache.cayenne.reflect.ClassDescriptor;
 
 import java.util.ArrayList;
@@ -55,7 +56,7 @@ class HierarchicalObjectResolverNode extends 
PrefetchObjectResolver {
             // not using DataRow.createObjectId for performance reasons -
             // ObjectResolver
             // has all needed metadata already cached.
-            ObjectId anId = createObjectId(row, classDescriptor.getEntity(), 
null);
+            ObjectId anId = createObjectId(row, classDescriptor.getEntity(), 
CayennePath.EMPTY_PATH);
 
             Persistent object = objectFromDataRow(row, anId, classDescriptor);
             if (object == null) {
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/JoinedIdParentAttachmentStrategy.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/JoinedIdParentAttachmentStrategy.java
index eb15da0f5..7c6ef7ef4 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/JoinedIdParentAttachmentStrategy.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/JoinedIdParentAttachmentStrategy.java
@@ -24,6 +24,7 @@ import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.Persistent;
+import org.apache.cayenne.exp.path.CayennePath;
 import org.apache.cayenne.graph.GraphManager;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.reflect.ClassDescriptor;
@@ -34,7 +35,7 @@ import org.apache.cayenne.reflect.ClassDescriptor;
  */
 class JoinedIdParentAttachmentStrategy implements ParentAttachmentStrategy {
 
-    private final String relatedIdPrefix;
+    private final CayennePath relatedIdPrefix;
     private final Collection<ObjEntity> sourceEntities;
     private final PrefetchProcessorNode node;
     private final GraphManager graphManager;
@@ -47,8 +48,7 @@ class JoinedIdParentAttachmentStrategy implements 
ParentAttachmentStrategy {
         relatedIdPrefix = node
                 .getIncoming()
                 .getRelationship()
-                .getReverseDbRelationshipPath()
-                + ".";
+                .getReverseDbRelationshipPath();
 
         sourceEntities = 
parentDescriptor.getEntityInheritanceTree().allSubEntities();
 
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/ObjectResolver.java 
b/cayenne/src/main/java/org/apache/cayenne/access/ObjectResolver.java
index 5bdd54774..2aa9f8466 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/ObjectResolver.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/ObjectResolver.java
@@ -25,6 +25,7 @@ import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.PersistenceState;
 import org.apache.cayenne.Persistent;
+import org.apache.cayenne.exp.path.CayennePath;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.EntityResolver;
@@ -129,7 +130,7 @@ class ObjectResolver {
 
                // not using DataRow.createObjectId for performance reasons -
                // ObjectResolver has all needed metadata already cached.
-               ObjectId anId = createObjectId(row, 
classDescriptor.getEntity(), null);
+               ObjectId anId = createObjectId(row, 
classDescriptor.getEntity(), CayennePath.EMPTY_PATH);
                return objectFromDataRow(row, anId, classDescriptor);
        }
 
@@ -181,12 +182,11 @@ class ObjectResolver {
                return;
         }
 
-           for(Map.Entry<String, DbEntity> entry : 
classDescriptor.getAdditionalDbEntities().entrySet()) {
+           for(Map.Entry<CayennePath, DbEntity> entry : 
classDescriptor.getAdditionalDbEntities().entrySet()) {
             DbEntity dbEntity = entry.getValue();
-            String path = entry.getKey();
-            int lastDot = path.lastIndexOf('.');
-            String prefix = lastDot == -1 ? path : path.substring(lastDot + 1);
-            ObjectId objectId = createObjectId(row, "db:" + 
dbEntity.getName(), dbEntity.getPrimaryKeys(), prefix + '.', false);
+            CayennePath path = entry.getKey();
+            CayennePath prefix = path.length() == 1 ? path : 
path.tail(path.length() - 1);
+            ObjectId objectId = createObjectId(row, "db:" + 
dbEntity.getName(), dbEntity.getPrimaryKeys(), prefix, false);
             if(objectId != null) {
                                
context.getObjectStore().markFlattenedPath(object.getObjectId(), path, 
objectId);
             }
@@ -209,24 +209,20 @@ class ObjectResolver {
                return context;
        }
 
-       ObjectId createObjectId(DataRow dataRow, ObjEntity objEntity, String 
namePrefix) {
+       ObjectId createObjectId(DataRow dataRow, ObjEntity objEntity, 
CayennePath namePrefix) {
         Collection<DbAttribute> pk = objEntity == this.descriptor.getEntity()
                 ? this.primaryKey
                 : objEntity.getDbEntity().getPrimaryKeys();
         return createObjectId(dataRow, objEntity.getName(), pk, namePrefix, 
true);
     }
 
-    ObjectId createObjectId(DataRow dataRow, String name, 
Collection<DbAttribute> pk, String namePrefix, boolean strict) {
-               boolean prefix = namePrefix != null && !namePrefix.isEmpty();
-
+    ObjectId createObjectId(DataRow dataRow, String name, 
Collection<DbAttribute> pk, CayennePath namePrefix, boolean strict) {
                // ... handle special case - PK.size == 1
                // use some not-so-significant optimizations...
 
                if (pk.size() == 1) {
                        DbAttribute attribute = pk.iterator().next();
-
-                       String key = (prefix) ? namePrefix + 
attribute.getName() : attribute.getName();
-
+                       String key = 
namePrefix.dot(attribute.getName()).value();
                        Object val = dataRow.get(key);
 
                        // this is possible when processing left outer joint 
prefetches
@@ -245,9 +241,7 @@ class ObjectResolver {
 
                Map<String, Object> idMap = new HashMap<>(pk.size() * 2);
                for (final DbAttribute attribute : pk) {
-
-                       String key = (prefix) ? namePrefix + 
attribute.getName() : attribute.getName();
-
+                       String key = 
namePrefix.dot(attribute.getName()).value();
                        Object val = dataRow.get(key);
 
                        // this is possible when processing left outer joint 
prefetches
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/ObjectStore.java 
b/cayenne/src/main/java/org/apache/cayenne/access/ObjectStore.java
index 28c17d11b..9f886e163 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/ObjectStore.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/ObjectStore.java
@@ -28,6 +28,7 @@ import org.apache.cayenne.Persistent;
 import org.apache.cayenne.access.ObjectDiff.ArcOperation;
 import org.apache.cayenne.access.event.SnapshotEvent;
 import org.apache.cayenne.access.event.SnapshotEventListener;
+import org.apache.cayenne.exp.path.CayennePath;
 import org.apache.cayenne.graph.ArcId;
 import org.apache.cayenne.graph.ChildDiffLoader;
 import org.apache.cayenne.graph.GraphChangeHandler;
@@ -72,7 +73,7 @@ public class ObjectStore implements Serializable, 
SnapshotEventListener, GraphMa
      * Presence of path in this map is used to separate insert from update 
case of flattened records.
      * @since 4.1
      */
-    protected Map<Object, Map<String, ObjectId>> trackedFlattenedPaths;
+    protected Map<Object, Map<CayennePath, ObjectId>> trackedFlattenedPaths;
 
     // a sequential id used to tag GraphDiffs so that they can later be sorted 
in the
     // original creation order
@@ -598,7 +599,7 @@ public class ObjectStore implements Serializable, 
SnapshotEventListener, GraphMa
         }
 
         if(trackedFlattenedPaths != null) {
-            Map<String, ObjectId> paths = trackedFlattenedPaths.remove(nodeId);
+            Map<CayennePath, ObjectId> paths = 
trackedFlattenedPaths.remove(nodeId);
             if(paths != null) {
                 trackedFlattenedPaths.put(newId, paths);
             }
@@ -989,7 +990,7 @@ public class ObjectStore implements Serializable, 
SnapshotEventListener, GraphMa
     /**
      * @since 4.2
      */
-    public ObjectId getFlattenedId(ObjectId objectId, String path) {
+    public ObjectId getFlattenedId(ObjectId objectId, CayennePath path) {
         if(trackedFlattenedPaths == null) {
             return null;
         }
@@ -1014,7 +1015,7 @@ public class ObjectStore implements Serializable, 
SnapshotEventListener, GraphMa
      * Mark that flattened path for object has data row in DB.
      * @since 4.1
      */
-    public void markFlattenedPath(ObjectId objectId, String path, ObjectId id) 
{
+    public void markFlattenedPath(ObjectId objectId, CayennePath path, 
ObjectId id) {
         if(trackedFlattenedPaths == null) {
             trackedFlattenedPaths = new ConcurrentHashMap<>();
         }
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java
index f42c120ac..545fd8e69 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java
@@ -101,26 +101,20 @@ class ArcValuesCreationHandler implements 
GraphChangeHandler {
 
     ObjectId processFlattenedPath(ObjectId id, ObjectId finalTargetId, 
DbEntity entity, CayennePath dbPath, boolean add) {
         Iterator<CayenneMapEntry> dbPathIterator = 
entity.resolvePathComponents(dbPath);
-        StringBuilder path = new StringBuilder();
+        CayennePath flattenedPath = CayennePath.EMPTY_PATH;
 
         ObjectId srcId = id;
         ObjectId targetId = null;
 
         while(dbPathIterator.hasNext()) {
             CayenneMapEntry entry = dbPathIterator.next();
-            if(path.length() > 0) {
-                path.append('.');
-            }
-
-            path.append(entry.getName());
+            flattenedPath = flattenedPath.dot(entry.getName());
             if(entry instanceof DbRelationship) {
                 DbRelationship relationship = (DbRelationship)entry;
                 // intermediate db entity to be inserted
                 DbEntity target = relationship.getTargetEntity();
                 // if ID is present, just use it, otherwise create new
-                String flattenedPath = path.toString();
-
-                // if this is last segment and it's a relationship, use known 
target id from arc creation
+                // if this is last segment, and it's a relationship, use known 
target id from arc creation
                 if(!dbPathIterator.hasNext()) {
                     targetId = finalTargetId;
                 } else {
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/Values.java 
b/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/Values.java
index f893b09ba..2d5591463 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/Values.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/Values.java
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.exp.path.CayennePath;
 import org.apache.cayenne.map.DbAttribute;
 
 /**
@@ -43,7 +44,7 @@ public class Values {
 
     protected List<DbAttribute> updatedAttributes;
     // generated flattened Ids for this insert
-    protected Map<String, ObjectId> flattenedIds;
+    protected Map<CayennePath, ObjectId> flattenedIds;
 
     public Values(DbRowOp row, boolean includeId) {
         this.row = row;
@@ -116,7 +117,7 @@ public class Values {
         }
     }
 
-    public void addFlattenedId(String path, ObjectId id) {
+    public void addFlattenedId(CayennePath path, ObjectId id) {
         if(flattenedIds == null) {
             flattenedIds = new HashMap<>();
         }
@@ -146,7 +147,7 @@ public class Values {
             return attributeSnapshot;
         }
         // FK should override attribute values
-        fkSnapshot.forEach(attributeSnapshot::put);
+        attributeSnapshot.putAll(fkSnapshot);
         return attributeSnapshot;
     }
 
@@ -157,7 +158,7 @@ public class Values {
         return updatedAttributes;
     }
 
-    public Map<String, ObjectId> getFlattenedIds() {
+    public Map<CayennePath, ObjectId> getFlattenedIds() {
         if(flattenedIds == null) {
             return Collections.emptyMap();
         }
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/reflect/ClassDescriptor.java 
b/cayenne/src/main/java/org/apache/cayenne/reflect/ClassDescriptor.java
index 392e73923..763a80e18 100644
--- a/cayenne/src/main/java/org/apache/cayenne/reflect/ClassDescriptor.java
+++ b/cayenne/src/main/java/org/apache/cayenne/reflect/ClassDescriptor.java
@@ -23,6 +23,7 @@ import java.util.Collection;
 import java.util.Map;
 
 import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.path.CayennePath;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.EntityInheritanceTree;
 import org.apache.cayenne.map.ObjAttribute;
@@ -61,7 +62,7 @@ public interface ClassDescriptor {
      * @since 4.1
      * @return information about additional db entities
      */
-    Map<String, DbEntity> getAdditionalDbEntities();
+    Map<CayennePath, DbEntity> getAdditionalDbEntities();
 
     /**
      * @since 3.0
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/reflect/LazyClassDescriptorDecorator.java
 
b/cayenne/src/main/java/org/apache/cayenne/reflect/LazyClassDescriptorDecorator.java
index 9a7576e9a..826c371ac 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/reflect/LazyClassDescriptorDecorator.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/reflect/LazyClassDescriptorDecorator.java
@@ -22,6 +22,7 @@ import java.util.Collection;
 import java.util.Map;
 
 import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.path.CayennePath;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.EntityInheritanceTree;
 import org.apache.cayenne.map.ObjAttribute;
@@ -90,7 +91,7 @@ public class LazyClassDescriptorDecorator implements 
ClassDescriptor {
     }
 
     @Override
-    public Map<String, DbEntity> getAdditionalDbEntities() {
+    public Map<CayennePath, DbEntity> getAdditionalDbEntities() {
         checkDescriptorInitialized();
         return descriptor.getAdditionalDbEntities();
     }
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/reflect/PersistentDescriptor.java 
b/cayenne/src/main/java/org/apache/cayenne/reflect/PersistentDescriptor.java
index 1cac8a14e..adbb72e6d 100644
--- a/cayenne/src/main/java/org/apache/cayenne/reflect/PersistentDescriptor.java
+++ b/cayenne/src/main/java/org/apache/cayenne/reflect/PersistentDescriptor.java
@@ -22,6 +22,7 @@ import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.PersistenceState;
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.path.CayennePath;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.EntityInheritanceTree;
 import org.apache.cayenne.map.ObjAttribute;
@@ -61,7 +62,7 @@ public class PersistentDescriptor implements ClassDescriptor {
 
        protected ObjEntity entity;
        protected Collection<DbEntity> rootDbEntities;
-       protected Map<String, DbEntity> additionalDbEntities;
+       protected Map<CayennePath, DbEntity> additionalDbEntities;
 
        protected EntityInheritanceTree entityInheritanceTree;
 
@@ -127,7 +128,7 @@ public class PersistentDescriptor implements 
ClassDescriptor {
         * @param path path for entity
         * @param targetEntity additional entity
         */
-       void addAdditionalDbEntity(String path, DbEntity targetEntity) {
+       void addAdditionalDbEntity(CayennePath path, DbEntity targetEntity) {
                if(additionalDbEntities == null) {
                        additionalDbEntities = new HashMap<>();
                }
@@ -231,7 +232,7 @@ public class PersistentDescriptor implements 
ClassDescriptor {
        }
 
        @Override
-       public Map<String, DbEntity> getAdditionalDbEntities() {
+       public Map<CayennePath, DbEntity> getAdditionalDbEntities() {
                if(additionalDbEntities == null) {
                        return Collections.emptyMap();
                }
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/reflect/PersistentDescriptorFactory.java
 
b/cayenne/src/main/java/org/apache/cayenne/reflect/PersistentDescriptorFactory.java
index 103777c33..bd86793ab 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/reflect/PersistentDescriptorFactory.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/reflect/PersistentDescriptorFactory.java
@@ -27,6 +27,7 @@ import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.dba.TypesMapping;
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.TraversalHandler;
+import org.apache.cayenne.exp.path.CayennePath;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbRelationship;
@@ -303,16 +304,13 @@ public abstract class PersistentDescriptorFactory 
implements ClassDescriptorFact
                 }
 
                 Iterator<CayenneMapEntry> it = 
property.getAttribute().getDbPathIterator();
-                StringBuilder sb = new StringBuilder();
+                CayennePath path = CayennePath.EMPTY_PATH;
                 while(it.hasNext()) {
                     CayenneMapEntry next = it.next();
                     if(next instanceof DbRelationship) {
                         DbRelationship rel = (DbRelationship)next;
-                        if(sb.length() > 0) {
-                            sb.append('.');
-                        }
-                        sb.append(rel.getName());
-                        descriptor.addAdditionalDbEntity(sb.toString(), 
rel.getTargetEntity());
+                        path = path.dot(rel.getName());
+                        descriptor.addAdditionalDbEntity(path, 
rel.getTargetEntity());
                     }
                 }
                 return true;
@@ -325,15 +323,12 @@ public abstract class PersistentDescriptorFactory 
implements ClassDescriptorFact
                 }
 
                 List<DbRelationship> dbRelationships = 
property.getRelationship().getDbRelationships();
-                StringBuilder sb = new StringBuilder();
+                CayennePath path = CayennePath.EMPTY_PATH;
                 int count = dbRelationships.size();
                 for(int i=0; i<count-1; i++) {
                     DbRelationship rel = dbRelationships.get(i);
-                    if(sb.length() > 0) {
-                        sb.append('.');
-                    }
-                    sb.append(rel.getName());
-                    descriptor.addAdditionalDbEntity(sb.toString(), 
rel.getTargetEntity());
+                    path = path.dot(rel.getName());
+                    descriptor.addAdditionalDbEntity(path, 
rel.getTargetEntity());
                 }
                 return true;
             }

Reply via email to