/*
* $Id$
*
* Copyright 2009 Glencoe Software, Inc. All rights reserved.
* Use is subject to license terms supplied in LICENSE.txt
*/
package ome.security.basic;
import java.util.Map;
import ome.conditions.SecurityViolation;
import ome.model.IEnum;
import ome.model.IObject;
import ome.tools.hibernate.HibernateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.Restrictions;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
import org.hibernate.event.MergeEvent;
import org.hibernate.event.SaveOrUpdateEvent;
import org.hibernate.event.def.DefaultSaveEventListener;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.ForeignKeyDirection;
import org.springframework.util.Assert;
/**
* event listener which will only handle newly created (transient) objects in
* a given graph. It will ignore unloaded and detached objects by default. This
* is primarily a performance optimization.
*
* @author Josh Moore, josh at glencoesoftware.com
* * @since 4.0
*/
public class SaveEventListener extends DefaultSaveEventListener {
public final static String SAVE_EVENT = "SaveEvent";
private static final long serialVersionUID = 1111101677298961L;
private static Logger log = LoggerFactory.getLogger(SaveEventListener.class);
private final CurrentDetails cd;
private final TokenHolder th;
/** main constructor. Requires a non-null security system */
public SaveEventListener(CurrentDetails cd, TokenHolder th) {
Assert.notNull(cd);
Assert.notNull(th);
this.cd = cd;
this.th = th;
}
@Override
public void onSaveOrUpdate(SaveOrUpdateEvent event)
throws HibernateException {
if (cd.isDisabled(SAVE_EVENT)) {
throw new SecurityViolation("The SaveOrUpdateEventListener has been disabled");
}
super.onSaveOrUpdate(event);
}
/*
protected void copyValues(EntityPersister persister, Object entity,
Object target, SessionImplementor source, Map copyCache) {
if (entity instanceof IObject) {
HibernateUtils.fixNulledOrFilteredCollections((IObject) entity,
(IObject) target, persister, source);
propagateHiddenValues((IObject) entity, (IObject) target);
}
super.copyValues(persister, entity, target, source, copyCache);
}
protected void copyValues(EntityPersister persister, Object entity,
Object target, SessionImplementor source, Map copyCache,
ForeignKeyDirection foreignKeyDirection) {
if (entity instanceof IObject) {
HibernateUtils.fixNulledOrFilteredCollections((IObject) entity,
(IObject) target, persister, source);
propagateHiddenValues((IObject) entity, (IObject) target);
}
super.copyValues(persister, entity, target, source, copyCache,
foreignKeyDirection);
}
protected void entityIsTransient(MergeEvent event, Map copyCache) {
Class cls = event.getOriginal().getClass();
IEnum extant = null;
if (IEnum.class.isAssignableFrom(cls)) {
String value = ((IEnum) event.getOriginal()).getValue();
Class type = ((IEnum) event.getOriginal()).getClass();
Criteria c = event.getSession().createCriteria(type).add(
Restrictions.eq("value", value));
extant = (IEnum) c.uniqueResult();
if (null != extant) {
log("Using existing Enum(", event.getEntityName(),
") with value:", value);
copyCache.put(event.getEntity(), extant);
event.setResult(extant);
}
}
// the above didn't succeed. process normally.
if (extant == null) {
super.entityIsTransient(event, copyCache);
}
fillReplacement(event);
}
protected void entityIsDetached(MergeEvent event, Map copyCache) {
IObject orig = (IObject) event.getOriginal();
if (HibernateUtils.isUnloaded(orig)) {
final EventSource source = event.getSession();
log("Reloading unloaded entity:", event.getEntityName(), ":", orig
.getId());
Object obj = source.load(orig.getClass(), orig.getId());
event.setResult(obj);
copyCache.put(event.getEntity(), obj);
fillReplacement(event);
return; // EARLY EXIT!
// TODO this was maybe a bug. check if findDirty is superfluous.
}
else {
super.entityIsDetached(event, copyCache);
}
fillReplacement(event);
}
// ~ Helpers
// =========================================================================
protected void fillReplacement(MergeEvent event) {
if (event.getOriginal() instanceof IObject) {
IObject obj = (IObject) event.getOriginal();
obj.getGraphHolder().setReplacement((IObject) event.getResult());
}
}
protected void propagateHiddenValues(IObject from, IObject to) {
th.copyToken(from, to);
if (from.getDetails() != null && from.getDetails().filteredSize() > 0) {
to.getDetails().addFiltered(from.getDetails().filteredSet());
}
}
private void log(Object... objects) {
if (log.isDebugEnabled() && objects != null && objects.length > 0) {
StringBuilder sb = new StringBuilder(objects.length * 16);
for (Object obj : objects) {
sb.append(obj == null ? "null" : obj.toString());
}
log.debug(sb.toString());
}
}
*/
}