use of org.apache.cayenne.reflect.ToOneProperty in project cayenne by apache.
the class ObjectDetachOperation method detach.
/**
* "Detaches" an object from its context by creating an unattached copy. The copy is
* created using target descriptor of this operation that may be different from the
* object descriptor passed to this method.
*/
public Object detach(Object object, ClassDescriptor descriptor, final PrefetchTreeNode prefetchTree) {
if (!(object instanceof Persistent)) {
throw new CayenneRuntimeException("Expected Persistent, got: %s", object);
}
final Persistent source = (Persistent) object;
ObjectId id = source.getObjectId();
// sanity check
if (id == null) {
throw new CayenneRuntimeException("Server returned an object without an id: %s", source);
}
Object seenTarget = seen.get(id);
if (seenTarget != null) {
return seenTarget;
}
descriptor = descriptor.getSubclassDescriptor(source.getClass());
// presumably id's entity name should be of the right subclass.
final ClassDescriptor targetDescriptor = targetResolver.getClassDescriptor(id.getEntityName());
final Persistent target = (Persistent) targetDescriptor.createObject();
target.setObjectId(id);
seen.put(id, target);
descriptor.visitProperties(new PropertyVisitor() {
private void fillReverseRelationship(Object destinationTarget, ArcProperty property) {
ArcProperty clientProperty = (ArcProperty) targetDescriptor.getProperty(property.getName());
if (clientProperty != null) {
ArcProperty clientReverse = clientProperty.getComplimentaryReverseArc();
if (clientReverse instanceof ToOneProperty) {
clientReverse.writeProperty(destinationTarget, null, target);
}
}
}
public boolean visitToOne(ToOneProperty property) {
if (prefetchTree != null) {
PrefetchTreeNode child = prefetchTree.getNode(property.getName());
if (child != null) {
Object destinationSource = property.readProperty(source);
Object destinationTarget = destinationSource != null ? detach(destinationSource, property.getTargetDescriptor(), child) : null;
if (destinationTarget != null) {
fillReverseRelationship(destinationTarget, property);
}
ToOneProperty targetProperty = (ToOneProperty) targetDescriptor.getProperty(property.getName());
Object oldTarget = targetProperty.isFault(target) ? null : targetProperty.readProperty(target);
targetProperty.writeProperty(target, oldTarget, destinationTarget);
}
}
return true;
}
public boolean visitToMany(ToManyProperty property) {
if (prefetchTree != null) {
PrefetchTreeNode child = prefetchTree.getNode(property.getName());
if (child != null) {
Object value = property.readProperty(source);
Object targetValue;
if (property instanceof ToManyMapProperty) {
Map<?, ?> map = (Map) value;
Map targetMap = new HashMap();
for (Entry entry : map.entrySet()) {
Object destinationSource = entry.getValue();
Object destinationTarget = destinationSource != null ? detach(destinationSource, property.getTargetDescriptor(), child) : null;
if (destinationTarget != null) {
fillReverseRelationship(destinationTarget, property);
}
targetMap.put(entry.getKey(), destinationTarget);
}
targetValue = targetMap;
} else {
Collection collection = (Collection) value;
Collection targetCollection = new ArrayList(collection.size());
for (Object destinationSource : collection) {
Object destinationTarget = destinationSource != null ? detach(destinationSource, property.getTargetDescriptor(), child) : null;
if (destinationTarget != null) {
fillReverseRelationship(destinationTarget, property);
}
targetCollection.add(destinationTarget);
}
targetValue = targetCollection;
}
ToManyProperty targetProperty = (ToManyProperty) targetDescriptor.getProperty(property.getName());
targetProperty.writeProperty(target, null, targetValue);
}
}
return true;
}
public boolean visitAttribute(AttributeProperty property) {
PropertyDescriptor targetProperty = targetDescriptor.getProperty(property.getName());
targetProperty.writeProperty(target, null, property.readProperty(source));
return true;
}
});
return target;
}
use of org.apache.cayenne.reflect.ToOneProperty in project cayenne by apache.
the class Util method setReverse.
static void setReverse(final Persistent sourceObject, String propertyName, final Persistent targetObject) {
ArcProperty property = (ArcProperty) Cayenne.getClassDescriptor(sourceObject).getProperty(propertyName);
ArcProperty reverseArc = property.getComplimentaryReverseArc();
if (reverseArc != null) {
reverseArc.visit(new PropertyVisitor() {
public boolean visitToMany(ToManyProperty property) {
property.addTargetDirectly(targetObject, sourceObject);
return false;
}
public boolean visitToOne(ToOneProperty property) {
property.setTarget(targetObject, sourceObject, false);
return false;
}
public boolean visitAttribute(AttributeProperty property) {
return false;
}
});
sourceObject.getObjectContext().getGraphManager().arcCreated(targetObject.getObjectId(), sourceObject.getObjectId(), reverseArc.getName());
markAsDirty(targetObject);
}
}
use of org.apache.cayenne.reflect.ToOneProperty in project cayenne by apache.
the class ChildDiffLoader method arcDeleted.
public void arcDeleted(Object nodeId, final Object targetNodeId, Object arcId) {
final Persistent source = findObject(nodeId);
// changing their relationships
if (source == null) {
return;
}
ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(((ObjectId) nodeId).getEntityName());
PropertyDescriptor property = descriptor.getProperty(arcId.toString());
setExternalChange(Boolean.TRUE);
try {
property.visit(new PropertyVisitor() {
public boolean visitAttribute(AttributeProperty property) {
return false;
}
public boolean visitToMany(ToManyProperty property) {
// connect reverse arc if the relationship is marked as
// "runtime"
ArcProperty reverseArc = property.getComplimentaryReverseArc();
boolean autoConnectReverse = reverseArc != null && reverseArc.getRelationship().isRuntime();
Persistent target = findObject(targetNodeId);
if (target == null) {
// this is usually the case when a NEW object was
// deleted and then
// its
// relationships were manipulated; so try to locate the
// object in
// the
// collection ...
// the performance of this is rather dubious of
// course...
target = findObjectInCollection(targetNodeId, property.readProperty(source));
}
if (target == null) {
// ignore?
} else {
property.removeTarget(source, target, autoConnectReverse);
}
return false;
}
public boolean visitToOne(ToOneProperty property) {
property.setTarget(source, null, false);
return false;
}
});
} finally {
setExternalChange(Boolean.FALSE);
}
}
use of org.apache.cayenne.reflect.ToOneProperty in project cayenne by apache.
the class ChildDiffLoader method arcCreated.
public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
final Persistent source = findObject(nodeId);
final Persistent target = findObject(targetNodeId);
// can result in NULL target here.
if (target == null) {
return;
}
ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(((ObjectId) nodeId).getEntityName());
ArcProperty property = (ArcProperty) descriptor.getProperty(arcId.toString());
setExternalChange(Boolean.TRUE);
try {
property.visit(new PropertyVisitor() {
public boolean visitAttribute(AttributeProperty property) {
return false;
}
public boolean visitToMany(ToManyProperty property) {
// connect reverse arc if the relationship is marked as
// "runtime"
ArcProperty reverseArc = property.getComplimentaryReverseArc();
boolean autoConnectReverse = reverseArc != null && reverseArc.getRelationship().isRuntime();
property.addTarget(source, target, autoConnectReverse);
return false;
}
public boolean visitToOne(ToOneProperty property) {
property.setTarget(source, target, false);
return false;
}
});
} finally {
setExternalChange(Boolean.FALSE);
}
}
use of org.apache.cayenne.reflect.ToOneProperty in project cayenne by apache.
the class Compiler method compileEntityResultWithPrefetch.
private EntityResult compileEntityResultWithPrefetch(EntityResult compiledResult, EJBQLExpression prefetchExpression) {
final EntityResult result = compiledResult;
String id = prefetchExpression.getText().toLowerCase();
ClassDescriptor descriptor = descriptorsById.get(id);
if (descriptor == null) {
descriptor = descriptorsById.get(prefetchExpression.getText());
}
final String prefix = prefetchExpression.getText().substring(prefetchExpression.getText().indexOf(".") + 1);
final Set<String> visited = new HashSet<String>();
PropertyVisitor visitor = new PropertyVisitor() {
public boolean visitAttribute(AttributeProperty property) {
ObjAttribute oa = property.getAttribute();
if (visited.add(oa.getDbAttributePath())) {
result.addObjectField(oa.getEntity().getName(), "fetch." + prefix + "." + oa.getName(), prefix + "." + oa.getDbAttributeName());
}
return true;
}
public boolean visitToMany(ToManyProperty property) {
return true;
}
public boolean visitToOne(ToOneProperty property) {
ObjRelationship rel = property.getRelationship();
DbRelationship dbRel = rel.getDbRelationships().get(0);
for (DbJoin join : dbRel.getJoins()) {
DbAttribute src = join.getSource();
if (src.isForeignKey() && visited.add(src.getName())) {
result.addDbField("fetch." + prefix + "." + src.getName(), prefix + "." + src.getName());
}
}
return true;
}
};
descriptor.visitAllProperties(visitor);
// append id columns ... (some may have been appended already via relationships)
for (String pkName : descriptor.getEntity().getPrimaryKeyNames()) {
if (visited.add(pkName)) {
result.addDbField("fetch." + prefix + "." + pkName, prefix + "." + pkName);
}
}
// append inheritance discriminator columns...
for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {
if (visited.add(column.getName())) {
result.addDbField("fetch." + prefix + "." + column.getDbAttributePath(), prefix + "." + column.getDbAttributePath());
}
}
return result;
}
Aggregations