use of org.apache.cayenne.reflect.ArcProperty in project cayenne by apache.
the class ObjectDiff method addDiff.
void addDiff(NodeDiff diff, ObjectStore parent) {
boolean addDiff = true;
if (diff instanceof ArcOperation) {
ArcOperation arcDiff = (ArcOperation) diff;
Object targetId = arcDiff.getTargetNodeId();
String arcId = arcDiff.getArcId().toString();
ArcProperty property = (ArcProperty) getClassDescriptor().getProperty(arcId);
if (property == null && arcId.startsWith(ASTDbPath.DB_PREFIX)) {
addPhantomFkDiff(arcDiff);
addDiff = false;
} else if (property instanceof ToManyProperty) {
// record flattened op changes
ObjRelationship relationship = property.getRelationship();
if (relationship.isFlattened()) {
if (flatIds == null) {
flatIds = new HashMap<>();
}
ArcOperation oldOp = flatIds.put(arcDiff, arcDiff);
// "delete" cancels "create" and vice versa...
if (oldOp != null && oldOp.isDelete() != arcDiff.isDelete()) {
addDiff = false;
flatIds.remove(arcDiff);
if (otherDiffs != null) {
otherDiffs.remove(oldOp);
}
}
} else if (property.getComplimentaryReverseArc() == null) {
// register complimentary arc diff
String arc = ASTDbPath.DB_PREFIX + property.getComplimentaryReverseDbRelationshipPath();
ArcOperation complimentartyOp = new ArcOperation(targetId, arcDiff.getNodeId(), arc, arcDiff.isDelete());
parent.registerDiff(targetId, complimentartyOp);
}
} else if (property instanceof ToOneProperty) {
if (currentArcSnapshot == null) {
currentArcSnapshot = new HashMap<>();
}
currentArcSnapshot.put(arcId, targetId);
} else {
String message = (property == null) ? "No property for arcId " + arcId : "Unrecognized property for arcId " + arcId + ": " + property;
throw new CayenneRuntimeException(message);
}
}
if (addDiff) {
if (otherDiffs == null) {
otherDiffs = new ArrayList<>(3);
}
otherDiffs.add(diff);
}
}
use of org.apache.cayenne.reflect.ArcProperty in project cayenne by apache.
the class PrefetchProcessorJointNode method buildRowMapping.
/**
* Configures row columns mapping for this node entity.
*/
private void buildRowMapping() {
final Map<String, ColumnDescriptor> targetSource = new TreeMap<>();
// build a DB path .. find parent node that terminates the joint group...
PrefetchTreeNode jointRoot = this;
while (jointRoot.getParent() != null && !jointRoot.isDisjointPrefetch() && !jointRoot.isDisjointByIdPrefetch()) {
jointRoot = jointRoot.getParent();
}
final String prefix;
if (jointRoot != this) {
Expression objectPath = ExpressionFactory.exp(getPath(jointRoot));
ASTPath translated = (ASTPath) ((PrefetchProcessorNode) jointRoot).getResolver().getEntity().translateToDbPath(objectPath);
// make sure we do not include "db:" prefix
prefix = translated.getOperand(0) + ".";
} else {
prefix = "";
}
if (getParent() != null && !getParent().isPhantom() && getIncoming() != null && !getIncoming().getRelationship().isFlattened()) {
DbRelationship r = getIncoming().getRelationship().getDbRelationships().get(0);
for (final DbJoin join : r.getJoins()) {
appendColumn(targetSource, join.getTargetName(), prefix + join.getTargetName());
}
}
ClassDescriptor descriptor = resolver.getDescriptor();
descriptor.visitAllProperties(new PropertyVisitor() {
public boolean visitAttribute(AttributeProperty property) {
String target = property.getAttribute().getDbAttributePath();
appendColumn(targetSource, target, prefix + target);
return true;
}
public boolean visitToMany(ToManyProperty property) {
return visitRelationship(property);
}
public boolean visitToOne(ToOneProperty property) {
return visitRelationship(property);
}
private boolean visitRelationship(ArcProperty arc) {
DbRelationship dbRel = arc.getRelationship().getDbRelationships().get(0);
for (DbAttribute attribute : dbRel.getSourceAttributes()) {
String target = attribute.getName();
appendColumn(targetSource, target, prefix + target);
}
return true;
}
});
// append id columns ... (some may have been appended already via relationships)
for (String pkName : descriptor.getEntity().getPrimaryKeyNames()) {
appendColumn(targetSource, pkName, prefix + pkName);
}
// append inheritance discriminator columns...
for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {
String target = column.getDbAttributePath();
appendColumn(targetSource, target, prefix + target);
}
int size = targetSource.size();
this.rowCapacity = (int) Math.ceil(size / 0.75);
this.columns = new ColumnDescriptor[size];
targetSource.values().toArray(columns);
}
use of org.apache.cayenne.reflect.ArcProperty in project cayenne by apache.
the class PrefetchProcessorTreeBuilder method addNode.
boolean addNode(PrefetchProcessorNode node) {
List rows;
ArcProperty arc;
ClassDescriptor descriptor;
PrefetchProcessorNode currentNode = getParent();
if (currentNode != null) {
rows = (List) extraResultsByPath.get(node.getPath());
arc = (ArcProperty) currentNode.getResolver().getDescriptor().getProperty(node.getName());
if (arc == null) {
throw new CayenneRuntimeException("No relationship with name '%s' found in entity '%s'", node.getName(), currentNode.getResolver().getEntity().getName());
}
descriptor = arc.getTargetDescriptor();
} else {
arc = null;
if (this.descriptor != null) {
descriptor = this.descriptor;
} else {
descriptor = queryMetadata.getClassDescriptor();
}
rows = mainResultRows;
}
node.setDataRows(rows);
node.setIncoming(arc);
if (node.getParent() != null && !node.isJointPrefetch()) {
node.setResolver(new HierarchicalObjectResolverNode(node, context, descriptor, queryMetadata.isRefreshingObjects(), seen));
} else {
node.setResolver(new PrefetchObjectResolver(context, descriptor, queryMetadata.isRefreshingObjects(), seen));
}
if (node.getParent() == null || node.getParent().isPhantom()) {
node.setParentAttachmentStrategy(new NoopParentAttachmentStrategy());
} else if (node.isJointPrefetch()) {
node.setParentAttachmentStrategy(new StackLookupParentAttachmentStrategy(node));
} else if (node.getIncoming().getRelationship().isSourceIndependentFromTargetChange()) {
node.setParentAttachmentStrategy(new JoinedIdParentAttachementStrategy(context.getGraphManager(), node));
} else {
node.setParentAttachmentStrategy(new ResultScanParentAttachmentStrategy(node));
}
if (currentNode != null) {
currentNode.addChild(node);
}
node.afterInit();
// push node on stack
if (nodeStack.isEmpty()) {
root = node;
}
nodeStack.addLast(node);
return true;
}
use of org.apache.cayenne.reflect.ArcProperty in project cayenne by apache.
the class EJBQLIdentifierColumnsTranslator method visitIdentifier.
@Override
public boolean visitIdentifier(EJBQLExpression expression) {
Map<String, String> xfields = null;
if (context.isAppendingResultColumns()) {
xfields = context.nextEntityResult().getFields();
}
// assign whatever we have to a final ivar so that it can be accessed
// within
// the inner class
final Map<String, String> fields = xfields;
final String idVar = expression.getText();
// append all table columns ... the trick is to follow the algorithm for
// describing the fields in the expression compiler, so that we could
// assign
// columns labels from FieldResults in the order we encounter them
// here...
// TODO: andrus 2008/02/17 - this is a bit of a hack, think of a better
// solution
ClassDescriptor descriptor = context.getEntityDescriptor(idVar);
PropertyVisitor visitor = new PropertyVisitor() {
public boolean visitAttribute(AttributeProperty property) {
ObjAttribute oa = property.getAttribute();
Iterator<?> dbPathIterator = oa.getDbPathIterator();
EJBQLJoinAppender joinAppender = null;
String marker = null;
EJBQLTableId lhsId = new EJBQLTableId(idVar);
while (dbPathIterator.hasNext()) {
Object pathPart = dbPathIterator.next();
if (pathPart == null) {
throw new CayenneRuntimeException("ObjAttribute has no component: %s", oa.getName());
} else if (pathPart instanceof DbRelationship) {
if (marker == null) {
marker = EJBQLJoinAppender.makeJoinTailMarker(idVar);
joinAppender = context.getTranslatorFactory().getJoinAppender(context);
}
DbRelationship dr = (DbRelationship) pathPart;
EJBQLTableId rhsId = new EJBQLTableId(lhsId, dr.getName());
joinAppender.appendOuterJoin(marker, lhsId, rhsId);
lhsId = rhsId;
} else if (pathPart instanceof DbAttribute) {
appendColumn(idVar, oa, (DbAttribute) pathPart, fields, oa.getType());
}
}
return true;
}
public boolean visitToMany(ToManyProperty property) {
visitRelationship(property);
return true;
}
public boolean visitToOne(ToOneProperty property) {
visitRelationship(property);
return true;
}
private void visitRelationship(ArcProperty property) {
ObjRelationship rel = property.getRelationship();
DbRelationship dbRel = rel.getDbRelationships().get(0);
for (DbJoin join : dbRel.getJoins()) {
DbAttribute src = join.getSource();
appendColumn(idVar, null, src, fields);
}
}
};
// EJBQL queries are polymorphic by definition - there is no distinction
// between
// inheritance/no-inheritance fetch
descriptor.visitAllProperties(visitor);
// append id columns ... (some may have been appended already via
// relationships)
DbEntity table = descriptor.getEntity().getDbEntity();
for (DbAttribute pk : table.getPrimaryKeys()) {
appendColumn(idVar, null, pk, fields);
}
// append inheritance discriminator columns...
for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {
appendColumn(idVar, column, column.getDbAttribute(), fields);
}
addPrefetchedColumnsIfAny(idVar);
return false;
}
use of org.apache.cayenne.reflect.ArcProperty in project cayenne by apache.
the class CayenneContextMergeHandler method arcCreated.
public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
// null source or target likely means the object is not faulted yet... Faults
// shouldn't get disturbed by adding/removing arcs
Object source = context.internalGraphManager().getNode(nodeId);
if (source == null) {
// no need to connect non-existent object
return;
}
// TODO (Andrus, 10/17/2005) - check for local modifications to avoid
// overwriting...
ArcProperty p = (ArcProperty) propertyForId(nodeId, arcId.toString());
if (p.isFault(source)) {
return;
}
Object target = context.internalGraphManager().getNode(targetNodeId);
if (target == null) {
target = context.createFault((ObjectId) targetNodeId);
}
if (p instanceof ToManyProperty) {
((ToManyProperty) p).addTargetDirectly(source, target);
} else {
p.writePropertyDirectly(source, null, target);
}
}
Aggregations