use of org.apache.cayenne.map.ObjAttribute in project cayenne by apache.
the class SelectQueryMetadata method buildEntityResultForColumn.
/**
* Collect metadata for column that will be unwrapped to full entity in the final SQL
* (possibly including joint prefetch).
* This information will be used to correctly create Persistent object back from raw result.
*
* This method is actually repeating logic of
* {@link org.apache.cayenne.access.translator.select.DefaultSelectTranslator#appendQueryColumns}.
* Here we don't care about intermediate joins and few other things so it's shorter.
* Logic of these methods should be unified and simplified, possibly to a single source of metadata,
* generated only once and used everywhere.
*
* @param query original query
* @param column full object column
* @param resolver entity resolver to get ObjEntity and ClassDescriptor
* @return Entity result
*/
private EntityResult buildEntityResultForColumn(SelectQuery<?> query, Property<?> column, EntityResolver resolver) {
final EntityResult result = new EntityResult(column.getType());
// Collecting visitor for ObjAttributes and toOne relationships
PropertyVisitor visitor = new PropertyVisitor() {
public boolean visitAttribute(AttributeProperty property) {
ObjAttribute oa = property.getAttribute();
Iterator<CayenneMapEntry> dbPathIterator = oa.getDbPathIterator();
while (dbPathIterator.hasNext()) {
CayenneMapEntry pathPart = dbPathIterator.next();
if (pathPart instanceof DbAttribute) {
result.addDbField(pathPart.getName(), pathPart.getName());
}
}
return true;
}
public boolean visitToMany(ToManyProperty property) {
return true;
}
public boolean visitToOne(ToOneProperty property) {
DbRelationship dbRel = property.getRelationship().getDbRelationships().get(0);
List<DbJoin> joins = dbRel.getJoins();
for (DbJoin join : joins) {
if (!join.getSource().isPrimaryKey()) {
result.addDbField(join.getSource().getName(), join.getSource().getName());
}
}
return true;
}
};
ObjEntity oe = resolver.getObjEntity(column.getType());
DbEntity table = oe.getDbEntity();
// Additionally collect PKs
for (DbAttribute dba : table.getPrimaryKeys()) {
result.addDbField(dba.getName(), dba.getName());
}
ClassDescriptor descriptor = resolver.getClassDescriptor(oe.getName());
descriptor.visitAllProperties(visitor);
// Collection columns for joint prefetch
if (query.getPrefetchTree() != null) {
for (PrefetchTreeNode prefetch : query.getPrefetchTree().adjacentJointNodes()) {
// for each prefetch add columns from the target entity
Expression prefetchExp = ExpressionFactory.exp(prefetch.getPath());
ASTDbPath dbPrefetch = (ASTDbPath) oe.translateToDbPath(prefetchExp);
DbRelationship r = findRelationByPath(table, dbPrefetch);
if (r == null) {
throw new CayenneRuntimeException("Invalid joint prefetch '%s' for entity: %s", prefetch, oe.getName());
}
// go via target OE to make sure that Java types are mapped correctly...
ObjRelationship targetRel = (ObjRelationship) prefetchExp.evaluate(oe);
ObjEntity targetEntity = targetRel.getTargetEntity();
prefetch.setEntityName(targetRel.getSourceEntity().getName());
String labelPrefix = dbPrefetch.getPath();
Set<String> seenNames = new HashSet<>();
for (ObjAttribute oa : targetEntity.getAttributes()) {
Iterator<CayenneMapEntry> dbPathIterator = oa.getDbPathIterator();
while (dbPathIterator.hasNext()) {
Object pathPart = dbPathIterator.next();
if (pathPart instanceof DbAttribute) {
DbAttribute attribute = (DbAttribute) pathPart;
if (seenNames.add(attribute.getName())) {
result.addDbField(labelPrefix + '.' + attribute.getName(), labelPrefix + '.' + attribute.getName());
}
}
}
}
// append remaining target attributes such as keys
DbEntity targetDbEntity = r.getTargetEntity();
for (DbAttribute attribute : targetDbEntity.getAttributes()) {
if (seenNames.add(attribute.getName())) {
result.addDbField(labelPrefix + '.' + attribute.getName(), labelPrefix + '.' + attribute.getName());
}
}
}
}
return result;
}
use of org.apache.cayenne.map.ObjAttribute in project cayenne by apache.
the class PersistentDescriptor method indexAddedProperty.
void indexAddedProperty(PropertyDescriptor property) {
if (property instanceof AttributeProperty) {
AttributeProperty attributeProperty = (AttributeProperty) property;
ObjAttribute attribute = attributeProperty.getAttribute();
if (attribute.isPrimaryKey()) {
if (idProperties == null) {
idProperties = new ArrayList<>(2);
}
idProperties.add(attributeProperty);
}
} else if (property instanceof ArcProperty) {
ObjRelationship relationship = ((ArcProperty) property).getRelationship();
ObjRelationship reverseRelationship = relationship.getReverseRelationship();
if (reverseRelationship != null && "java.util.Map".equals(reverseRelationship.getCollectionType())) {
if (mapArcProperties == null) {
mapArcProperties = new ArrayList<>(2);
}
mapArcProperties.add((ArcProperty) property);
}
}
}
use of org.apache.cayenne.map.ObjAttribute in project cayenne by apache.
the class PersistentDescriptorFactory method indexQualifiers.
protected void indexQualifiers(final PersistentDescriptor descriptor, EntityInheritanceTree inheritanceTree) {
Expression qualifier;
if (inheritanceTree != null) {
qualifier = inheritanceTree.qualifierForEntityAndSubclasses();
} else {
qualifier = descriptor.getEntity().getDeclaredQualifier();
}
if (qualifier != null) {
// using map instead of a Set to collect attributes, as
// ObjEntity.getAttribute may return a decorator for attribute on
// each call, resulting in dupes
final Map<String, ObjAttribute> attributes = new HashMap<>();
final DbEntity dbEntity = descriptor.getEntity().getDbEntity();
qualifier.traverse(new TraversalHelper() {
@Override
public void startNode(Expression node, Expression parentNode) {
if (node.getType() == Expression.DB_PATH) {
String path = node.getOperand(0).toString();
final DbAttribute attribute = dbEntity.getAttribute(path);
if (attribute != null) {
ObjAttribute objectAttribute = descriptor.getEntity().getAttributeForDbAttribute(attribute);
if (objectAttribute == null) {
objectAttribute = new ObjAttribute(attribute.getName()) {
@Override
public DbAttribute getDbAttribute() {
return attribute;
}
};
// we semi-officially DO NOT support inheritance
// descriptors based on related entities, so
// here we
// assume that DbAttribute is rooted in the root
// DbEntity, and no relationship is involved.
objectAttribute.setDbAttributePath(attribute.getName());
objectAttribute.setType(TypesMapping.getJavaBySqlType(attribute.getType()));
}
attributes.put(objectAttribute.getName(), objectAttribute);
}
} else if (node.getType() == Expression.OBJ_PATH) {
String path = node.getOperand(0).toString();
ObjAttribute attribute = descriptor.getEntity().getAttribute(path);
attributes.put(path, attribute);
}
}
});
descriptor.setDiscriminatorColumns(attributes.values());
descriptor.setEntityQualifier(qualifier);
}
}
use of org.apache.cayenne.map.ObjAttribute in project cayenne by apache.
the class PersistentDescriptorTest method testCopyObjectProperties.
@Test
public void testCopyObjectProperties() {
PersistentDescriptor d1 = new PersistentDescriptor();
ObjAttribute attribute = mock(ObjAttribute.class);
FieldAccessor accessor = new FieldAccessor(TstBean.class, "string", String.class);
PropertyDescriptor property = new SimpleAttributeProperty(d1, accessor, attribute);
d1.addDeclaredProperty(property);
TstBean from = new TstBean();
from.setString("123");
TstBean to = new TstBean();
d1.shallowMerge(from, to);
assertEquals("123", to.getString());
}
use of org.apache.cayenne.map.ObjAttribute in project cayenne by apache.
the class DataObjectAttributePropertyTest method testSerialization.
@Test
public void testSerialization() throws Exception {
ObjEntity e1 = new ObjEntity("objEntityName");
ObjAttribute a1 = new ObjAttribute("aName", "aType", e1);
DataObjectAttributeProperty p1 = new DataObjectAttributeProperty(a1);
DataObjectAttributeProperty p2 = Util.cloneViaSerialization(p1);
assertNotNull(p2);
assertNotNull(p2.getAttribute());
assertEquals(p1.getAttribute().getName(), p2.getAttribute().getName());
assertEquals(p1.getName(), p2.getName());
}
Aggregations