use of org.apache.cayenne.ObjectId in project cayenne by apache.
the class ObjectContextQueryAction method interceptRelationshipQuery.
protected boolean interceptRelationshipQuery() {
if (query instanceof RelationshipQuery) {
RelationshipQuery relationshipQuery = (RelationshipQuery) query;
if (!relationshipQuery.isRefreshing()) {
if (targetContext == null && relationshipQuery.getRelationship(actingContext.getEntityResolver()).isToMany()) {
return !DONE;
}
ObjectId id = relationshipQuery.getObjectId();
Object object = actingContext.getGraphManager().getNode(id);
if (object != null) {
ClassDescriptor descriptor = actingContext.getEntityResolver().getClassDescriptor(id.getEntityName());
if (!descriptor.isFault(object)) {
ArcProperty property = (ArcProperty) descriptor.getProperty(relationshipQuery.getRelationshipName());
if (!property.isFault(object)) {
Object related = property.readPropertyDirectly(object);
List result;
// null to-one
if (related == null) {
result = new ArrayList(1);
} else // to-many List
if (related instanceof List) {
result = (List) related;
} else // to-many Set
if (related instanceof Set) {
result = new ArrayList((Set) related);
} else // to-many Map
if (related instanceof Map) {
result = new ArrayList(((Map) related).values());
} else // non-null to-one
{
result = new ArrayList(1);
result.add(related);
}
this.response = new ListResponse(result);
return DONE;
}
/**
* Workaround for CAY-1183. If a Relationship query is being sent
* from child context, we assure that local object is not NEW and
* relationship - unresolved (this way exception will occur). This
* helps when faulting objects that were committed to parent
* context (this), but not to database. Checking type of context's
* channel is the only way to ensure that we are on the top level
* of context hierarchy (there might be more than one-level-deep
* nested contexts).
*/
if (((Persistent) object).getPersistenceState() == PersistenceState.NEW && !(actingContext.getChannel() instanceof BaseContext)) {
this.response = new ListResponse();
return DONE;
}
}
}
}
}
return !DONE;
}
use of org.apache.cayenne.ObjectId 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.ObjectId in project cayenne by apache.
the class ShallowMergeOperation method merge.
public <T extends Persistent> T merge(T peerInParentContext) {
if (peerInParentContext == null) {
throw new IllegalArgumentException("Null peerInParentContext");
}
// handling of HOLLOW peer state is here for completeness... Wonder if we ever
// have a case where it is applicable.
int peerState = peerInParentContext.getPersistenceState();
ObjectId id = peerInParentContext.getObjectId();
ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(id.getEntityName());
GraphManager graphManager = context.getGraphManager();
// messing up dataobjects per CAY-845.
synchronized (graphManager) {
T object = (T) graphManager.getNode(id);
// merge into an existing object
if (object == null) {
object = (T) descriptor.createObject();
object.setObjectContext(context);
object.setObjectId(id);
if (peerState == PersistenceState.HOLLOW) {
object.setPersistenceState(PersistenceState.HOLLOW);
} else {
object.setPersistenceState(PersistenceState.COMMITTED);
}
graphManager.registerNode(id, object);
}
// TODO: Andrus, 1/24/2006 implement smart merge for modified objects...
if (peerState != PersistenceState.HOLLOW && object.getPersistenceState() != PersistenceState.MODIFIED && object.getPersistenceState() != PersistenceState.DELETED) {
descriptor.shallowMerge(peerInParentContext, object);
if (object.getPersistenceState() == PersistenceState.HOLLOW) {
object.setPersistenceState(PersistenceState.COMMITTED);
}
}
return object;
}
}
use of org.apache.cayenne.ObjectId in project cayenne by apache.
the class SimpleNode method encodeScalarAsEJBQL.
/**
* <p>
* This is a utility method that can represent the supplied scalar as either
* an EJBQL literal into the supplied {@link java.io.PrintWriter} or is able
* to add the scalar to the parameters and to instead write a positional
* parameter to the EJBQL written to the {@link java.io.PrintWriter}. If the
* parameters are null and the scalar object is not able to be represented
* as an EJBQL literal then the method will throw a runtime exception to
* indicate that it has failed to produce valid EJBQL.
* </p>
*/
protected static void encodeScalarAsEJBQL(List<Object> parameterAccumulator, Appendable out, Object scalar) throws IOException {
if (null == scalar) {
out.append("null");
return;
}
if (scalar instanceof Boolean) {
if ((Boolean) scalar) {
out.append("true");
} else {
out.append("false");
}
return;
}
if (null != parameterAccumulator) {
parameterAccumulator.add(scalar);
out.append('?');
// parameters start at 1
out.append(Integer.toString(parameterAccumulator.size()));
return;
}
if (scalar instanceof Integer || scalar instanceof Long || scalar instanceof Float || scalar instanceof Double) {
out.append(scalar.toString());
return;
}
if (scalar instanceof Persistent) {
ObjectId id = ((Persistent) scalar).getObjectId();
Object encode = (id != null) ? id : scalar;
appendAsEscapedString(out, String.valueOf(encode));
return;
}
if (scalar instanceof Enum<?>) {
Enum<?> e = (Enum<?>) scalar;
out.append("enum:");
out.append(e.getClass().getName()).append(".").append(e.name());
return;
}
if (scalar instanceof String) {
out.append('\'');
appendAsEscapedString(out, scalar.toString());
out.append('\'');
return;
}
throw new IllegalStateException("the scalar type '" + scalar.getClass().getSimpleName() + "' is not supported as a scalar type in EJBQL");
}
use of org.apache.cayenne.ObjectId in project cayenne by apache.
the class SimpleNode method appendScalarAsString.
/**
* Utility method that encodes an object that is not an expression Node to
* String.
*/
protected static void appendScalarAsString(Appendable out, Object scalar, char quoteChar) throws IOException {
boolean quote = scalar instanceof String;
if (quote) {
out.append(quoteChar);
}
// TODO: should we use UUID here?
if (scalar instanceof Persistent) {
ObjectId id = ((Persistent) scalar).getObjectId();
Object encode = (id != null) ? id : scalar;
appendAsEscapedString(out, String.valueOf(encode));
} else if (scalar instanceof Enum<?>) {
Enum<?> e = (Enum<?>) scalar;
out.append("enum:");
out.append(e.getClass().getName()).append(".").append(e.name());
} else {
appendAsEscapedString(out, String.valueOf(scalar));
}
if (quote) {
out.append(quoteChar);
}
}
Aggregations