use of org.apache.cayenne.reflect.ClassDescriptor 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.ClassDescriptor in project cayenne by apache.
the class EJBQLIdentifierColumnsTranslator method addPrefetchedColumnsIfAny.
private void addPrefetchedColumnsIfAny(final String visitedIdentifier) {
PrefetchTreeNode prefetchTree = context.getCompiledExpression().getPrefetchTree();
if (prefetchTree != null) {
for (PrefetchTreeNode prefetch : prefetchTree.adjacentJointNodes()) {
ClassDescriptor descriptor = context.getEntityDescriptor(prefetch.getEjbqlPathEntityId());
if (visitedIdentifier.equals(prefetch.getEjbqlPathEntityId())) {
DbEntity table = descriptor.getRootDbEntities().iterator().next();
ObjEntity objectEntity = descriptor.getEntity();
prefetch.setEntityName(objectEntity.getName());
Expression prefetchExp = ExpressionFactory.exp(prefetch.getPath());
Expression dbPrefetch = objectEntity.translateToDbPath(prefetchExp);
DbRelationship r = null;
for (PathComponent<DbAttribute, DbRelationship> component : table.resolvePath(dbPrefetch, context.getMetadata().getPathSplitAliases())) {
r = component.getRelationship();
}
if (r == null) {
throw new CayenneRuntimeException("Invalid joint prefetch '%s' for entity: %s", prefetch, objectEntity.getName());
}
for (DbAttribute attribute : r.getTargetEntity().getAttributes()) {
appendColumn(prefetch.getEjbqlPathEntityId() + "." + prefetch.getPath(), attribute, "", prefetch.getPath() + "." + attribute.getName(), null);
}
}
}
}
}
use of org.apache.cayenne.reflect.ClassDescriptor in project cayenne by apache.
the class EJBQLDbPathTranslator method visitIdentifier.
@Override
public boolean visitIdentifier(EJBQLExpression expression) {
// expression id is always rooted in an ObjEntity, even for DbPath...
ClassDescriptor descriptor = context.getEntityDescriptor(expression.getText());
if (descriptor == null) {
throw new EJBQLException("Invalid identification variable: " + expression.getText());
}
this.currentEntity = descriptor.getEntity().getDbEntity();
this.idPath = expression.getText();
this.joinMarker = EJBQLJoinAppender.makeJoinTailMarker(idPath);
this.fullPath = idPath;
return true;
}
use of org.apache.cayenne.reflect.ClassDescriptor in project cayenne by apache.
the class EJBQLIdColumnsTranslator method visitIdentifier.
@Override
public boolean visitIdentifier(EJBQLExpression expression) {
Map<String, String> fields = null;
if (context.isAppendingResultColumns()) {
fields = context.nextEntityResult().getFields();
}
String idVar = expression.getText();
ClassDescriptor descriptor = context.getEntityDescriptor(idVar);
ObjEntity oe = descriptor.getEntity();
for (ObjAttribute oa : oe.getPrimaryKeys()) {
DbAttribute t = oe.getDbEntity().getAttribute(oa.getDbAttributeName());
appendColumn(idVar, oa, t, fields, oa.getType());
}
return false;
}
use of org.apache.cayenne.reflect.ClassDescriptor in project cayenne by apache.
the class EJBQLTableId method getDbEntity.
/**
* Returns a DbEntity corresponding to the ID, that could be a root entity for the id,
* or a joined entity.
*/
DbEntity getDbEntity(EJBQLTranslationContext context) {
ClassDescriptor descriptor = context.getEntityDescriptor(entityId);
DbEntity rootEntity = descriptor.getEntity().getDbEntity();
if (dbPath == null) {
return rootEntity;
}
DbRelationship r = null;
Iterator<?> it = rootEntity.resolvePathComponents(dbPath);
while (it.hasNext()) {
r = (DbRelationship) it.next();
}
return (DbEntity) r.getTargetEntity();
}
Aggregations