use of org.apache.cayenne.reflect.ClassDescriptor in project cayenne by apache.
the class CayenneContext method registerNewObject.
/**
* @since 3.0
*/
@Override
public void registerNewObject(Object object) {
if (object == null) {
throw new NullPointerException("An attempt to register null object.");
}
ObjEntity entity = getEntityResolver().getObjEntity(object.getClass());
ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(entity.getName());
registerNewObject((Persistent) object, entity.getName(), descriptor);
}
use of org.apache.cayenne.reflect.ClassDescriptor in project cayenne by apache.
the class CayenneContextChildDiffLoader method arcCreated.
@Override
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());
property.visit(new PropertyVisitor() {
public boolean visitAttribute(AttributeProperty property) {
return false;
}
public boolean visitToMany(ToManyProperty property) {
property.addTargetDirectly(source, target);
return false;
}
public boolean visitToOne(ToOneProperty property) {
property.setTarget(source, target, false);
return false;
}
});
context.propertyChanged(source, (String) arcId, null, target);
}
use of org.apache.cayenne.reflect.ClassDescriptor in project cayenne by apache.
the class CayenneContextGraphManager method remapTargets.
/**
* Remaps keys in to-many map relationships that contain dirty objects with
* potentially modified properties.
*/
private void remapTargets() {
Iterator<Object> it = stateLog.dirtyIds().iterator();
EntityResolver resolver = context.getEntityResolver();
while (it.hasNext()) {
ObjectId id = (ObjectId) it.next();
ClassDescriptor descriptor = resolver.getClassDescriptor(id.getEntityName());
Collection<ArcProperty> mapArcProperties = descriptor.getMapArcProperties();
if (!mapArcProperties.isEmpty()) {
Object object = getNode(id);
for (ArcProperty arc : mapArcProperties) {
ToManyMapProperty reverseArc = (ToManyMapProperty) arc.getComplimentaryReverseArc();
Object source = arc.readPropertyDirectly(object);
if (source != null && !reverseArc.isFault(source)) {
remapTarget(reverseArc, source, object);
}
}
}
}
}
use of org.apache.cayenne.reflect.ClassDescriptor in project cayenne by apache.
the class CayenneContextQueryAction method invalidateLocally.
private void invalidateLocally(CayenneContextGraphManager graphManager, Iterator<?> it) {
if (!it.hasNext()) {
return;
}
EntityResolver resolver = actingContext.getEntityResolver();
while (it.hasNext()) {
final Persistent object = (Persistent) it.next();
// present
if (object.getPersistenceState() == PersistenceState.NEW) {
continue;
}
ObjectId id = object.getObjectId();
// per CAY-1082 ROP objects (unlike CayenneDataObject) require all
// relationship faults invalidation.
ClassDescriptor descriptor = resolver.getClassDescriptor(id.getEntityName());
PropertyVisitor arcInvalidator = new PropertyVisitor() {
public boolean visitAttribute(AttributeProperty property) {
return true;
}
public boolean visitToMany(ToManyProperty property) {
property.invalidate(object);
return true;
}
public boolean visitToOne(ToOneProperty property) {
property.invalidate(object);
return true;
}
};
descriptor.visitProperties(arcInvalidator);
object.setPersistenceState(PersistenceState.HOLLOW);
// remove cached changes
graphManager.changeLog.unregisterNode(id);
graphManager.stateLog.unregisterNode(id);
}
}
use of org.apache.cayenne.reflect.ClassDescriptor in project cayenne by apache.
the class DefaultSelectTranslator method appendOverriddenColumns.
/**
* If query contains explicit column list, use only them
*/
<T> List<ColumnDescriptor> appendOverriddenColumns(List<ColumnDescriptor> columns, SelectQuery<T> query) {
groupByColumns = new HashMap<>();
QualifierTranslator qualifierTranslator = adapter.getQualifierTranslator(this);
AccumulatingBindingListener bindingListener = new AccumulatingBindingListener();
final String[] joinTableAliasForProperty = { null };
// capture last alias for joined table, will use it to resolve object columns
joinListener = () -> joinTableAliasForProperty[0] = getCurrentAlias();
setAddBindingListener(bindingListener);
for (Property<?> property : query.getColumns()) {
joinTableAliasForProperty[0] = null;
int expressionType = property.getExpression().getType();
// forbid direct selection of toMany relationships columns
if (property.getType() != null && (expressionType == Expression.OBJ_PATH || expressionType == Expression.DB_PATH) && (Collection.class.isAssignableFrom(property.getType()) || Map.class.isAssignableFrom(property.getType()))) {
throw new CayenneRuntimeException("Can't directly select toMany relationship columns. " + "Either select it with aggregate functions like count() or with flat() function to select full related objects.");
}
// evaluate ObjPath with Persistent type as toOne relations and use it as full object
boolean objectProperty = expressionType == Expression.FULL_OBJECT || (property.getType() != null && expressionType == Expression.OBJ_PATH && Persistent.class.isAssignableFrom(property.getType()));
// Qualifier Translator in case of Object Columns have side effect -
// it will create required joins, that we catch with listener above.
// And we force created join alias for all columns of Object we select.
qualifierTranslator.setQualifier(property.getExpression());
qualifierTranslator.setForceJoinForRelations(objectProperty);
StringBuilder builder = qualifierTranslator.appendPart(new StringBuilder());
if (objectProperty) {
// If we want full object, use appendQueryColumns method, to fully process class descriptor
List<ColumnDescriptor> classColumns = new ArrayList<>();
ObjEntity entity = entityResolver.getObjEntity(property.getType());
if (getQueryMetadata().getPageSize() > 0) {
appendIdColumns(classColumns, entity);
} else {
ClassDescriptor classDescriptor = entityResolver.getClassDescriptor(entity.getName());
appendQueryColumns(classColumns, query, classDescriptor, joinTableAliasForProperty[0]);
}
for (ColumnDescriptor descriptor : classColumns) {
columns.add(descriptor);
groupByColumns.put(descriptor, Collections.<DbAttributeBinding>emptyList());
}
} else {
// This property will go as scalar value
String alias = property.getAlias();
if (alias != null) {
builder.append(" AS ").append(alias);
}
int type = getJdbcTypeForProperty(property);
ColumnDescriptor descriptor;
if (property.getType() != null) {
descriptor = new ColumnDescriptor(builder.toString(), type, property.getType().getCanonicalName());
} else {
descriptor = new ColumnDescriptor(builder.toString(), type);
}
descriptor.setDataRowKey(alias);
descriptor.setIsExpression(true);
columns.add(descriptor);
if (isAggregate(property)) {
haveAggregate = true;
} else {
groupByColumns.put(descriptor, bindingListener.getBindings());
}
bindingListener.reset();
}
}
setAddBindingListener(null);
qualifierTranslator.setForceJoinForRelations(false);
joinListener = null;
return columns;
}
Aggregations