org.apache.cayenne.commitlog.DeletedDiffProcessor Maven / Gradle / Ivy
/*****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
****************************************************************/
package org.apache.cayenne.commitlog;
import org.apache.cayenne.DataChannel;
import org.apache.cayenne.DataRow;
import org.apache.cayenne.ObjectId;
import org.apache.cayenne.QueryResponse;
import org.apache.cayenne.commitlog.meta.CommitLogEntity;
import org.apache.cayenne.commitlog.meta.CommitLogEntityFactory;
import org.apache.cayenne.commitlog.model.MutableChangeMap;
import org.apache.cayenne.commitlog.model.MutableObjectChange;
import org.apache.cayenne.commitlog.model.ObjectChangeType;
import org.apache.cayenne.graph.ArcId;
import org.apache.cayenne.graph.GraphChangeHandler;
import org.apache.cayenne.map.DbRelationship;
import org.apache.cayenne.query.ObjectIdQuery;
import org.apache.cayenne.reflect.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
class DeletedDiffProcessor implements GraphChangeHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(DeletedDiffProcessor.class);
private CommitLogEntityFactory entityFactory;
private MutableChangeMap changeSet;
private DataChannel channel;
DeletedDiffProcessor(MutableChangeMap changeSet, DataChannel channel, CommitLogEntityFactory entityFactory) {
this.changeSet = changeSet;
this.channel = channel;
this.entityFactory = entityFactory;
}
@Override
public void nodeRemoved(Object nodeId) {
ObjectId id = (ObjectId) nodeId;
final MutableObjectChange objectChangeSet = changeSet.getOrCreate(id, ObjectChangeType.DELETE);
// TODO: rewrite with SelectById query after Cayenne upgrade
ObjectIdQuery query = new ObjectIdQuery(id, true, ObjectIdQuery.CACHE);
QueryResponse result = channel.onQuery(null, query);
@SuppressWarnings("unchecked")
List rows = (List)result.firstList();
if (rows.isEmpty()) {
LOGGER.warn("No DB snapshot for object to be deleted, no changes will be recorded. ID: " + id);
return;
}
final DataRow row = rows.get(0);
ClassDescriptor descriptor = channel.getEntityResolver().getClassDescriptor(id.getEntityName());
final CommitLogEntity entity = entityFactory.getEntity(id);
descriptor.visitProperties(new PropertyVisitor() {
@Override
public boolean visitAttribute(AttributeProperty property) {
if (!entity.isIncluded(property.getName())) {
return true;
}
Object value;
if (entity.isConfidential(property.getName())) {
value = Confidential.getInstance();
} else {
String key = property.getAttribute().getDbAttributeName();
value = row.get(key);
}
if (value != null) {
objectChangeSet.attributeChanged(property.getName(), value, null);
}
return true;
}
@Override
public boolean visitToOne(ToOneProperty property) {
if (!entity.isIncluded(property.getName())) {
return true;
}
// TODO: is there such a thing as "confidential" relationship that we need to hide?
DbRelationship dbRelationship = property.getRelationship().getDbRelationships().get(0);
ObjectId value = row.createTargetObjectId(
property.getTargetDescriptor().getEntity().getName(),
dbRelationship);
if (value != null) {
objectChangeSet.toOneRelationshipDisconnected(property.getName(), value);
}
return true;
}
@Override
public boolean visitToMany(ToManyProperty property) {
return true;
}
});
}
@Override
public void nodeIdChanged(Object nodeId, Object newId) {
// do nothing
}
@Override
public void nodeCreated(Object nodeId) {
// do nothing
}
@Override
public void nodePropertyChanged(Object nodeId, String property, Object oldValue, Object newValue) {
// do nothing
}
@Override
public void arcCreated(Object nodeId, Object targetNodeId, ArcId arcId) {
// do nothing
}
@Override
public void arcDeleted(Object nodeId, Object targetNodeId, ArcId arcId) {
// do nothing
}
}