Skip to content

Commit

Permalink
Move code from PersistentObject directly to BaseDataObject
Browse files Browse the repository at this point in the history
  • Loading branch information
stariy95 committed Dec 27, 2023
1 parent 3405e7f commit 4c1c90f
Show file tree
Hide file tree
Showing 60 changed files with 103 additions and 2,813 deletions.
70 changes: 59 additions & 11 deletions cayenne/src/main/java/org/apache/cayenne/BaseDataObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@
import org.apache.cayenne.map.ObjAttribute;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.ObjRelationship;
import org.apache.cayenne.reflect.ClassDescriptor;
import org.apache.cayenne.reflect.PropertyDescriptor;
import org.apache.cayenne.reflect.PropertyUtils;
import org.apache.cayenne.reflect.ToManyMapProperty;
import org.apache.cayenne.validation.BeanValidationFailure;
import org.apache.cayenne.validation.ValidationFailure;
import org.apache.cayenne.validation.ValidationResult;
Expand Down Expand Up @@ -65,11 +68,57 @@
*
* @since 4.1
*/
public abstract class BaseDataObject extends PersistentObject implements DataObject, Validating {
public abstract class BaseDataObject implements DataObject, Validating {

private static final long serialVersionUID = 4598677040697008371L;

protected ObjectId objectId;
protected int persistenceState;
protected long snapshotVersion = DEFAULT_VERSION;
protected transient ObjectContext objectContext;

/**
* Creates a new transient object.
*/
public BaseDataObject() {
this.persistenceState = PersistenceState.TRANSIENT;
}

public int getPersistenceState() {
return persistenceState;
}

public ObjectContext getObjectContext() {
return objectContext;
}

public ObjectId getObjectId() {
return objectId;
}

public void setObjectId(ObjectId objectId) {
this.objectId = objectId;
}

/**
* Returns a map key for a given to-many map relationship and a target object.
*
* @since 3.0
*/
protected Object getMapKey(String relationshipName, Object value) {
EntityResolver resolver = objectContext.getEntityResolver();
ClassDescriptor descriptor = resolver.getClassDescriptor(objectId.getEntityName());
if (descriptor == null) {
throw new IllegalStateException("DataObject's entity is unmapped, objectId: " + objectId);
}

PropertyDescriptor property = descriptor.getProperty(relationshipName);
if (property instanceof ToManyMapProperty) {
return ((ToManyMapProperty) property).getMapKey(value);
}

throw new IllegalArgumentException("Relationship '" + relationshipName + "' is not a to-many Map");
}

@Override
public Object readPropertyDirectly(String propName) {
Expand Down Expand Up @@ -325,11 +374,11 @@ public List<? extends DataObject> setToManyTarget(String relName, Collection<? e
if(property == null) {
throw new IllegalArgumentException("unknown relName " + relName);
}
Collection<DataObject> old = null;
Collection<? extends DataObject> old;
if (property instanceof Map) {
old = ((Map) property).values();
old = ((Map<?, ? extends DataObject>) property).values();
} else if (property instanceof Collection) {
old = (Collection) property;
old = (Collection<? extends DataObject>) property;
} else {
throw new UnsupportedOperationException("setToManyTarget operates only with Map or Collection types");
}
Expand All @@ -340,18 +389,17 @@ public List<? extends DataObject> setToManyTarget(String relName, Collection<? e
List<DataObject> removedObjects = new ArrayList<>();

// remove all relationships, which are missing in passed collection
Object[] oldValues = old.toArray();
for (Object obj : oldValues) {
DataObject[] oldValues = old.toArray(new DataObject[0]);
for (DataObject obj : oldValues) {
if (!values.contains(obj)) {
DataObject obj2 = (DataObject) obj;
removeToManyTarget(relName, obj2, setReverse);
removeToManyTarget(relName, obj, setReverse);
// collect objects whose relationship was removed
removedObjects.add((DataObject) obj2);
removedObjects.add(obj);
}
}

// dont add elements which are already present
for (Object obj : old) {
// don't add elements which are already present
for (DataObject obj : old) {
values.remove(obj);
}

Expand Down
40 changes: 20 additions & 20 deletions cayenne/src/main/java/org/apache/cayenne/DataObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,22 @@
*/
public interface DataObject extends Persistent {

public static final long DEFAULT_VERSION = Long.MIN_VALUE;
long DEFAULT_VERSION = Long.MIN_VALUE;

/**
* Modifies a value of a named property without altering the object state in any way,
* and without triggering any database operations. This method is intended mostly for
* internal use by Cayenne framework, and shouldn't be called from the application
* code.
*/
public void writePropertyDirectly(String propertyName, Object val);
void writePropertyDirectly(String propertyName, Object val);

/**
* Returns mapped property value as curently stored in the DataObject. Returned value
* maybe a fault or a real value. This method will not attempt to resolve faults, or
* to read unmapped properties.
*/
public Object readPropertyDirectly(String propertyName);
Object readPropertyDirectly(String propertyName);

/**
* Returns a value of the property identified by a property path. Supports reading
Expand Down Expand Up @@ -81,41 +81,41 @@ public interface DataObject extends Persistent {
* <br>
* </li>
* </ul>
*
*
* @since 1.0.5
*/
public Object readNestedProperty(String path);
Object readNestedProperty(String path);

/**
* Returns a value of the property identified by propName. Resolves faults if needed.
* This method can safely be used instead of or in addition to the auto-generated
* property accessors in subclasses of CayenneDataObject.
*/
public Object readProperty(String propName);
Object readProperty(String propName);

/**
* Sets the property to the new value. Resolves faults if needed. This method can be
* safely used instead of or in addition to the auto-generated property modifiers to
* set simple properties. Note that to set to-one relationships use
* {@link #setToOneTarget(String, DataObject, boolean)}.
*
*
* @param propertyName a name of the bean property being modified.
* @param value a new value of the property.
* @param value a new value of the property.
*/
public void writeProperty(String propertyName, Object value);
void writeProperty(String propertyName, Object value);

/**
* Adds an object to a to-many relationship.
*/
public void addToManyTarget(
void addToManyTarget(
String relationshipName,
DataObject target,
boolean setReverse);

/**
* Removes an object from a to-many relationship.
*/
public void removeToManyTarget(
void removeToManyTarget(
String relationshipName,
DataObject target,
boolean unsetReverse);
Expand All @@ -124,27 +124,27 @@ public void removeToManyTarget(
* Sets to-one relationship to a new value. Resolves faults if needed. This method can
* safely be used instead of or in addition to the auto-generated property modifiers
* to set properties that are to-one relationships.
*
*
* @param relationshipName a name of the bean property being modified - same as the
* name of ObjRelationship.
* @param value a new value of the property.
* @param setReverse whether to update the reverse relationship pointing from the old
* and new values of the property to this object.
* name of ObjRelationship.
* @param value a new value of the property.
* @param setReverse whether to update the reverse relationship pointing from the old
* and new values of the property to this object.
*/
public void setToOneTarget(
void setToOneTarget(
String relationshipName,
DataObject value,
boolean setReverse);

/**
* Returns a version of a DataRow snapshot that was used to create this object.
*
*
* @since 1.1
*/
public long getSnapshotVersion();
long getSnapshotVersion();

/**
* @since 1.1
*/
public void setSnapshotVersion(long snapshotVersion);
void setSnapshotVersion(long snapshotVersion);
}
32 changes: 12 additions & 20 deletions cayenne/src/main/java/org/apache/cayenne/PersistentObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,29 +98,21 @@ protected Object getMapKey(String relationshipName, Object value) {
return ((ToManyMapProperty) property).getMapKey(value);
}

throw new IllegalArgumentException("Relationship '"
+ relationshipName
+ "' is not a to-many Map");
throw new IllegalArgumentException("Relationship '" + relationshipName + "' is not a to-many Map");
}

@Override
public String toString() {
String state = PersistenceState.persistenceStateName(getPersistenceState());

StringBuilder buffer = new StringBuilder();
buffer
.append("<")
.append(getClass().getName())
.append("@")
.append(System.identityHashCode(this))
.append(", id=")
.append(objectId)
.append(", state=")
.append(state)
.append(", context=")
.append(objectContext)
.append(">");

return buffer.toString();
return "<" +
getClass().getName() +
"@" +
System.identityHashCode(this) +
", id=" +
objectId +
", state=" +
PersistenceState.persistenceStateName(getPersistenceState()) +
", context=" +
objectContext +
">";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void testDirtyNodesInState() {
assertTrue(recorder.dirtyNodes(PersistenceState.TRANSIENT).isEmpty());
assertTrue(recorder.dirtyNodes(PersistenceState.HOLLOW).isEmpty());

MockPersistentObject modified = new MockPersistentObject();
MockDataObject modified = new MockDataObject();
modified.setObjectId(ObjectId.of("MockPersistentObject", "key", "value1"));
modified.setPersistenceState(PersistenceState.MODIFIED);

Expand All @@ -72,7 +72,7 @@ public void testDirtyNodesInState() {
assertTrue(recorder.dirtyNodes(PersistenceState.TRANSIENT).isEmpty());
assertTrue(recorder.dirtyNodes(PersistenceState.HOLLOW).isEmpty());

MockPersistentObject deleted = new MockPersistentObject();
MockDataObject deleted = new MockDataObject();
deleted.setObjectId(ObjectId.of("MockPersistentObject", "key", "value2"));
deleted.setPersistenceState(PersistenceState.DELETED);
when(mockGraphManager.getNode(deleted.getObjectId())).thenReturn(deleted);
Expand All @@ -93,7 +93,7 @@ public void testDirtyNodes() {
assertTrue(recorder.dirtyNodes().isEmpty());

// introduce a fake dirty object
MockPersistentObject object = new MockPersistentObject();
MockDataObject object = new MockDataObject();
object.setObjectId(ObjectId.of("MockPersistentObject", "key", "value"));
object.setPersistenceState(PersistenceState.MODIFIED);

Expand All @@ -115,7 +115,7 @@ public void testHasChanges() {
assertFalse(recorder.hasChanges());

// introduce a fake dirty object
MockPersistentObject object = new MockPersistentObject();
MockDataObject object = new MockDataObject();
object.setObjectId(ObjectId.of("MockPersistentObject", "key", "value"));
object.setPersistenceState(PersistenceState.MODIFIED);
recorder.nodePropertyChanged(object.getObjectId(), "xyz", "a", "b");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class PersistentObjectIT extends RuntimeCase {
@Test
public void testObjectContext() {
ObjectContext context = mock(ObjectContext.class);
PersistentObject object = new MockPersistentObject();
Persistent object = new MockPersistentObject();

assertNull(object.getObjectContext());
object.setObjectContext(context);
Expand All @@ -44,7 +44,7 @@ public void testObjectContext() {

@Test
public void testPersistenceState() {
PersistentObject object = new MockPersistentObject();
Persistent object = new MockPersistentObject();
assertEquals(PersistenceState.TRANSIENT, object.getPersistenceState());
object.setPersistenceState(PersistenceState.DELETED);
assertEquals(PersistenceState.DELETED, object.getPersistenceState());
Expand All @@ -54,7 +54,7 @@ public void testPersistenceState() {
public void testObjectID() {
ObjectId id = ObjectId.of("test");

PersistentObject object = new MockPersistentObject();
Persistent object = new MockPersistentObject();

assertNull(object.getObjectId());
object.setObjectId(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
****************************************************************/
package org.apache.cayenne.query;

import org.apache.cayenne.MockPersistentObject;
import org.apache.cayenne.MockDataObject;
import org.apache.cayenne.Persistent;
import org.junit.Test;

Expand Down Expand Up @@ -47,7 +47,7 @@ public void testRefreshAllConstructor() {

@Test
public void testCollectionConstructor() {
Collection c = new ArrayList();
Collection<Object> c = new ArrayList<>();
c.add(new Object());
c.add(new Object());

Expand All @@ -60,7 +60,7 @@ public void testCollectionConstructor() {

@Test
public void testObjectConstructor() {
Persistent p = new MockPersistentObject();
Persistent p = new MockDataObject();

RefreshQuery q = new RefreshQuery(p);
assertNotNull(q.getObjects());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
****************************************************************/
package org.apache.cayenne.reflect;

import org.apache.cayenne.BaseDataObject;
import org.apache.cayenne.ObjectId;
import org.apache.cayenne.PersistentObject;
import org.junit.Test;

import java.util.ArrayList;
Expand Down Expand Up @@ -116,7 +116,7 @@ public void testCallbackOrderInInheritanceHierarchy() {
assertEquals("c2Callback", c.callbacks.get(1));
}

static class C1 extends PersistentObject {
static class C1 extends BaseDataObject {

protected List callbacks = new ArrayList();

Expand Down
Loading

0 comments on commit 4c1c90f

Please sign in to comment.