package jane.core;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import jane.core.SContext.Rec;
import jane.core.SContext.Safe;
/**
* Set类型的安全修改类
*/
public class SSet<V, S> implements Set<S>, Cloneable
{
public interface SSetListener<V>
{
/**
* 增删统一一个回调接口
* @param rec 对应table及记录键值的封装
* @param added 所有已增加的元素
* @param removed 所有已删除的元素
*/
void onChanged(Rec rec, Set<V> added, Set<V> removed);
}
protected final Safe<?> _owner;
protected final Set<V> _set;
private SContext _sctx;
protected Set<V> _added;
protected Set<V> _removed;
public SSet(Safe<?> owner, Set<V> set, final SSetListener<V> listener)
{
_owner = owner;
_set = set;
if(listener != null)
{
final Rec rec = owner.record();
if(rec != null)
{
_added = new HashSet<>();
_removed = new HashSet<>();
SContext.current().addOnCommit(new Runnable()
{
@Override
public void run()
{
if(!_added.isEmpty() || !_removed.isEmpty())
listener.onChanged(rec, _added, _removed);
}
});
}
}
}
protected SContext sContext()
{
_owner.checkLock();
if(_sctx != null) return _sctx;
_owner.dirty();
return _sctx = SContext.current();
}
@SuppressWarnings("unchecked")
protected S safe(V v)
{
return (S)(v instanceof Bean ? ((Bean<?>)v).safe(_owner) : v);
}
@SuppressWarnings("unchecked")
protected S safeAlone(V v)
{
return (S)(v instanceof Bean ? ((Bean<?>)v).safe(null) : v);
}
@SuppressWarnings({ "unchecked", "deprecation" })
protected V unsafe(Object v)
{
return (V)(v instanceof Safe ? ((Safe<?>)v).unsafe() : v);
}
protected void addUndoAdd(SContext ctx, final V v)
{
if(_added != null) _added.add(v);
ctx.addOnRollback(new Runnable()
{
@Override
public void run()
{
_set.remove(v);
}
});
}
protected void addUndoRemove(SContext ctx, final V v)
{
if(_removed != null) _removed.add(v);
ctx.addOnRollback(new Runnable()
{
@Override
public void run()
{
_set.add(v);
}
});
}
@Override
public int size()
{
return _set.size();
}
@Override
public boolean isEmpty()
{
return _set.isEmpty();
}
@Override
public boolean contains(Object o)
{
return _set.contains(unsafe(o));
}
@Override
public boolean containsAll(Collection<?> c)
{
return _set.containsAll(c);
}
@Deprecated
@Override
public Object[] toArray()
{
return _set.toArray();
}
@Deprecated
@Override
public <T> T[] toArray(T[] a)
{
return _set.toArray(a);
}
public boolean addDirect(V v)
{
SContext ctx = sContext();
if(!_set.add(v)) return false;
addUndoAdd(ctx, v);
return true;
}
@Override
public boolean add(S s)
{
return addDirect(unsafe(s));
}
public boolean addAllDirect(Collection<? extends V> c)
{
boolean r = false;
for(V v : c)
if(addDirect(v)) r = true;
return r;
}
@Override
public boolean addAll(Collection<? extends S> c)
{
boolean r = false;
for(S s : c)
if(add(s)) r = true;
return r;
}
@Override
public boolean remove(Object s)
{
SContext ctx = sContext();
V v = unsafe(s);
if(!_set.remove(v)) return false;
addUndoRemove(ctx, v);
return true;
}
@Override
public boolean removeAll(Collection<?> c)
{
if(_set.isEmpty()) return false;
if(_set == c || this == c)
{
clear();
return true;
}
boolean r = false;
for(Object o : c)
if(remove(o)) r = true;
return r;
}
@Override
public boolean retainAll(Collection<?> c)
{
if(_set.isEmpty() || _set == c || this == c) return false;
boolean r = false;
for(SIterator it = iterator(); it.hasNext();)
{
if(!c.contains(it.nextUnsafe()))
{
it.remove();
r = true;
}
}
return r;
}
@SuppressWarnings("unchecked")
@Override
public void clear()
{
SContext ctx = sContext();
if(_set.isEmpty()) return;
ctx.addOnRollback(new Runnable()
{
private final Set<V> _saved;
{
try
{
_saved = _set.getClass().newInstance();
_saved.addAll(_set);
}
catch(Exception e)
{
throw new Error(e);
}
}
@Override
public void run()
{
_set.clear();
_set.addAll(_saved);
_saved.clear();
}
});
if(_removed != null)
{
for(V v : _set)
_removed.add(v);
}
_set.clear();
}
public final class SIterator implements Iterator<S>
{
private final Iterator<V> _it;
private V _cur;
protected SIterator(Iterator<V> it)
{
_it = it;
}
@Override
public boolean hasNext()
{
return _it.hasNext();
}
@Deprecated
public V nextUnsafe()
{
return _cur = _it.next();
}
@Override
public S next()
{
return safe(_cur = _it.next());
}
@Override
public void remove()
{
SContext ctx = sContext();
_it.remove();
addUndoRemove(ctx, _cur);
}
}
@Override
public SIterator iterator()
{
return new SIterator(_set.iterator());
}
public SSet<V, S> append(Set<V> set)
{
Util.appendDeep(set, _set);
return this;
}
public SSet<V, S> assign(Set<V> set)
{
clear();
Util.appendDeep(set, _set);
return this;
}
public void appendTo(Set<V> set)
{
Util.appendDeep(_set, set);
}
public void cloneTo(Set<V> set)
{
set.clear();
Util.appendDeep(_set, set);
}
@SuppressWarnings("unchecked")
@Override
public final Set<V> clone()
{
try
{
return (Set<V>)Util.appendDeep(_set, _set.getClass().newInstance());
}
catch(Exception e)
{
throw new Error(e);
}
}
@Override
public int hashCode()
{
return _set.hashCode();
}
@Override
public boolean equals(Object o)
{
return this == o || _set.equals(o);
}
@Override
public String toString()
{
return _set.toString();
}
}