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 <[email protected]>
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;
}