/*****************************************************************************
* Limpet - the Lightweight InforMation ProcEssing Toolkit
* http://limpet.info
*
* (C) 2015-2016, Deep Blue C Technologies Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html)
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*****************************************************************************/
package info.limpet.data.store;
import info.limpet.IChangeListener;
import info.limpet.ICollection;
import info.limpet.IStore;
import info.limpet.IStoreGroup;
import info.limpet.IStoreItem;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
public class StoreGroup extends ArrayList<IStoreItem> implements IStore,
IChangeListener, IStoreGroup
{
/**
*
*/
private static final long serialVersionUID = 1L;
private transient List<StoreChangeListener> _storeListeners;
private transient List<IChangeListener> _listeners;
private transient List<PropertyChangeListener> _timeListeners;
private Date _currentTime;
private UUID uuid;
private String _name;
private IStoreGroup _parent;
private static final String TOP_LEVEL_NAME = "Limpet Store";
public StoreGroup(String name)
{
_name = name;
}
private void checkListeners()
{
if(_storeListeners == null)
{
_storeListeners =
new ArrayList<StoreChangeListener>();
}
if(_listeners == null)
{
_listeners =
new ArrayList<IChangeListener>();
}
}
public StoreGroup()
{
this(TOP_LEVEL_NAME);
}
public interface StoreChangeListener
{
void changed();
}
public void addChangeListener(StoreChangeListener listener)
{
checkListeners();
_storeListeners.add(listener);
}
public void removeChangeListener(StoreChangeListener listener)
{
checkListeners();
_storeListeners.remove(listener);
}
protected void fireModified()
{
checkListeners();
Iterator<StoreChangeListener> iter = _storeListeners.iterator();
while (iter.hasNext())
{
StoreChangeListener listener =
iter.next();
listener.changed();
}
}
@Override
public void addAll(List<IStoreItem> results)
{
// add the items individually, so we can register as a listener
Iterator<IStoreItem> iter = results.iterator();
while (iter.hasNext())
{
IStoreItem iCollection = iter.next();
add(iCollection);
}
fireModified();
}
@Override
public boolean add(IStoreItem results)
{
boolean res = super.add(results);
results.setParent(this);
results.addChangeListener(this);
fireModified();
return res;
}
@Override
public IStoreItem get(String name)
{
IStoreItem res = null;
Iterator<IStoreItem> iter = iterator();
while (iter.hasNext())
{
IStoreItem item = iter.next();
if (item instanceof IStoreGroup)
{
IStoreGroup group = (IStoreGroup) item;
Iterator<IStoreItem> iter2 = group.iterator();
while (iter2.hasNext())
{
IStoreItem thisI = (IStoreItem) iter2.next();
if (name.equals(thisI.getName()))
{
res = thisI;
break;
}
}
}
if (name.equals(item.getName()))
{
res = item;
break;
}
}
return res;
}
@Override
public IStoreItem get(UUID uuid)
{
IStoreItem res = null;
Iterator<IStoreItem> iter = iterator();
while (iter.hasNext())
{
IStoreItem item = iter.next();
if (item instanceof IStoreGroup)
{
IStoreGroup group = (IStoreGroup) item;
Iterator<IStoreItem> iter2 = group.iterator();
while (iter2.hasNext())
{
IStoreItem thisI = (IStoreItem) iter2.next();
if (uuid.equals(thisI.getUUID()))
{
res = thisI;
break;
}
}
}
if (uuid.equals(item.getUUID()))
{
res = item;
break;
}
}
return res;
}
public void clear()
{
// stop listening to the collections individually
// - defer the clear until the end,
// so we don't get concurrent modification
Iterator<IStoreItem> iter = super.iterator();
while (iter.hasNext())
{
IStoreItem iC = iter.next();
if (iC instanceof ICollection)
{
ICollection coll = (ICollection) iC;
coll.removeChangeListener(this);
}
}
super.clear();
fireModified();
}
public boolean remove(Object item)
{
boolean res = super.remove(item);
// stop listening to this one
if (item instanceof ICollection)
{
ICollection collection = (ICollection) item;
collection.removeChangeListener(this);
// ok, also tell it that it's being deleted
collection.beingDeleted();
}
fireModified();
return res;
}
@Override
public void dataChanged(IStoreItem subject)
{
fireModified();
}
@Override
public void metadataChanged(IStoreItem subject)
{
dataChanged(subject);
}
@Override
public void collectionDeleted(IStoreItem subject)
{
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + getUUID().hashCode();
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
StoreGroup other = (StoreGroup) obj;
if (!getUUID().equals(other.getUUID()))
{
return false;
}
return true;
}
@Override
public boolean hasChildren()
{
return size() > 0;
}
@Override
public IStoreGroup getParent()
{
return _parent;
}
@Override
public void setParent(IStoreGroup parent)
{
_parent = parent;
}
@Override
public String getName()
{
return _name;
}
@Override
public void addChangeListener(IChangeListener listener)
{
checkListeners();
_listeners.add(listener);
}
@Override
public void removeChangeListener(IChangeListener listener)
{
checkListeners();
_listeners.add(listener);
}
@Override
public void fireDataChanged()
{
if(_listeners != null)
{
for(IChangeListener listener: _listeners)
{
listener.dataChanged(this);
}
}
}
@Override
public UUID getUUID()
{
if (uuid == null)
{
uuid = UUID.randomUUID();
}
return uuid;
}
@Override
public void setName(String value)
{
_name = value;
}
@Override
public Date getTime()
{
return _currentTime;
}
@Override
public void setTime(final Date time)
{
final Date oldTime = _currentTime;
_currentTime = time;
if(_timeListeners != null)
{
PropertyChangeEvent evt = new PropertyChangeEvent(this, "TIME", oldTime, time);
for(PropertyChangeListener thisL: _timeListeners)
{
thisL.propertyChange(evt);
}
}
}
@Override
public void addTimeChangeListener(PropertyChangeListener listener)
{
if(_timeListeners == null)
{
_timeListeners = new ArrayList<PropertyChangeListener>();
}
_timeListeners.add(listener);
}
@Override
public void removeTimeChangeListener(PropertyChangeListener listener)
{
if(_timeListeners != null)
{
_timeListeners.remove(listener);
}
}
}