package data.ooimpl;
import java.util.*;
import java.io.Serializable;
import data.events.*;
import data.*;
import log.*;
import util.*;
public class DataBasketImpl extends Object implements ListenableDataBasket {
protected static class SubDataBasket implements Serializable {
private Map m_mpmpldbeCategories = new HashMap();
private DataBasketImpl m_dbiOwner;
public SubDataBasket (DataBasketImpl dbiOwner) {
super();
m_dbiOwner = dbiOwner;
}
public boolean equals (Object o) {
return this == o;
}
public void commit (DataBasketCondition dbc) {
DataBasketEntry dbe = null;
for (Iterator i = iterator (dbc, true, true); i.hasNext();) {
try {
dbe = (DataBasketEntry) i.next();
if (!dbe.isHandled()) {
dbe.commit();
}
i.remove();
}
catch (Throwable t) {
System.err.println ("Exception during commit of <" + dbe + ">:");
t.printStackTrace();
System.err.println ("Continuing committing any other DataBasketEntries.");
}
}
}
public void rollback (DataBasketCondition dbc) {
DataBasketEntry dbe = null;
for (Iterator i = iterator (dbc, true, true); i.hasNext();) {
try {
dbe = (DataBasketEntry) i.next();
if (!dbe.isHandled()) {
dbe.rollback();
}
i.remove();
}
catch (Throwable t) {
System.err.println ("Exception during rollback of <" + dbe + ">:");
t.printStackTrace();
System.err.println ("Continuing rolling back any other DataBasketEntries.");
}
}
}
public Iterator iterator (final DataBasketCondition dbc,
final boolean fAllowRemove,
final boolean fShowHandled) {
class I implements Iterator {
private Map m_mpmpldbeCategories;
private Iterator m_iCategories;
private Map m_mpldbeSubCategories;
private Iterator m_iSubCategories;
private Iterator m_iItems;
private DataBasketEntry m_dbeCurrent = null;
private DataBasketEntry m_dbeNext = null;
public I (Map mpmpldbeCategories) {
super();
m_mpmpldbeCategories = mpmpldbeCategories;
m_iCategories = new TreeSet (m_mpmpldbeCategories.keySet()).iterator();
}
public boolean hasNext() {
return findNext (false);
}
public Object next() {
if (!findNext (true)) {
throw new NoSuchElementException();
}
return m_dbeCurrent;
}
public void remove() {
if (!fAllowRemove) {
throw new UnsupportedOperationException();
}
else {
if (m_iItems == null) {
throw new IllegalStateException();
}
m_iItems.remove();
m_dbeCurrent.setOwner (null);
m_dbiOwner.fireDBERemoved (m_dbeCurrent);
}
}
private boolean findNext (boolean fGet) {
do {
if (m_iSubCategories != null) {
if (checkSubCategories (fGet)) {
return true;
}
}
else {
m_iSubCategories = new Iterator() {
public boolean hasNext() { return false; }
public Object next() { return null; }
public void remove() {}
};
}
while ((m_iCategories.hasNext()) &&
(!m_iSubCategories.hasNext())) {
String sCategoryID = (String) m_iCategories.next();
if (dbc != null) {
if ((dbc.getMainKey() == null) ||
(dbc.getMainKey().equals (sCategoryID))) {
m_mpldbeSubCategories = (Map) m_mpmpldbeCategories.get (sCategoryID);
m_iSubCategories = m_mpldbeSubCategories.keySet().iterator();
}
}
else {
m_mpldbeSubCategories = (Map) m_mpmpldbeCategories.get (sCategoryID);
m_iSubCategories = m_mpldbeSubCategories.keySet().iterator();
}
}
} while (m_iSubCategories.hasNext());
return false;
}
private boolean checkSubCategories (boolean fGet) {
do {
if (m_iItems != null) {
if (checkItems (fGet)) {
return true;
}
}
else {
m_iItems = new Iterator() {
public boolean hasNext() { return false; }
public Object next() { return null; }
public void remove() {}
};
}
while ((m_iSubCategories.hasNext()) &&
(!m_iItems.hasNext())) {
String sSubCategoryID = (String) m_iSubCategories.next();
if (dbc != null) {
if ((dbc.getSecondaryKey() == null) ||
(dbc.getSecondaryKey().equals (sSubCategoryID))) {
List ldbeSubCategory = (List) m_mpldbeSubCategories.get (sSubCategoryID);
m_iItems = ldbeSubCategory.iterator();
}
}
else {
List ldbeSubCategory = (List) m_mpldbeSubCategories.get (sSubCategoryID);
m_iItems = ldbeSubCategory.iterator();
}
}
} while (m_iItems.hasNext());
return false;
}
private boolean checkItems (boolean fGet) {
if (m_dbeNext != null) {
if (fGet) {
m_dbeCurrent = m_dbeNext;
m_dbeNext = null;
}
return true;
}
while (m_iItems.hasNext()) {
DataBasketEntry dbe = (DataBasketEntry) m_iItems.next();
if ((dbe.isHandled()) &&
(!fShowHandled)) {
continue;
}
if (dbc != null) {
if ((dbc.getSource() != null) &&
(dbc.getSource() != dbe.getSource())) {
continue;
}
if ((dbc.getDestination() != null) &&
(dbc.getDestination() != dbe.getDestination())) {
continue;
}
if (((dbc.getValue() != null) &&
(dbc.getValue() == dbe.getValue())) ||
((dbc.getValue() == null) &&
(dbc.match (dbe)))) {
if (!fGet) {
m_dbeNext = dbe;
}
else {
m_dbeCurrent = dbe;
}
return true;
}
}
else {
if (!fGet) {
m_dbeNext = dbe;
}
else {
m_dbeCurrent = dbe;
}
return true;
}
}
return false;
}
}
return new I (m_mpmpldbeCategories);
}
public Value sumSubBasket (DataBasketCondition dbc, BasketEntryValue bev, Value vInit) {
for (Iterator i = iterator (dbc, false, false); i.hasNext();) {
vInit.addAccumulating ((Value) bev.getEntryValue ((DataBasketEntry) i.next()).clone());
}
return vInit;
}
public void put (DataBasketEntryImpl dbe) {
Map mpldbeCategory = (Map) m_mpmpldbeCategories.get (dbe.getMainKey());
if (mpldbeCategory == null) {
mpldbeCategory = new HashMap();
m_mpmpldbeCategories.put (dbe.getMainKey(), mpldbeCategory);
}
List ldbeSubCategory = (List) mpldbeCategory.get (dbe.getSecondaryKey());
if (ldbeSubCategory == null) {
ldbeSubCategory = new LinkedList();
mpldbeCategory.put (dbe.getSecondaryKey(), ldbeSubCategory);
}
ldbeSubCategory.add (dbe);
dbe.setOwner (m_dbiOwner);
m_dbiOwner.log (PUT_ACTION, dbe);
m_dbiOwner.fireDBEAdded (dbe);
}
public DataBasketEntry get (DataBasketCondition dbc) {
Iterator i = iterator (dbc, false, false);
if (i.hasNext()) {
return (DataBasketEntry) i.next();
}
else {
return null;
}
}
}
protected Map m_mpsdbChildren = new HashMap();
private transient Object m_oChildrenLock;
protected final Object getChildrenLock() {
if (m_oChildrenLock == null) {
m_oChildrenLock = new Object();
}
return m_oChildrenLock;
}
private SubDataBasket m_sdbCurrent;
private transient Object m_oCurrentLock;
private final Object getCurrentLock() {
if (m_oCurrentLock == null) {
m_oCurrentLock = new Object();
}
return m_oCurrentLock;
}
private LogContext m_lcLog;
private int m_nLogMode = LOG_MODE_NONE;
private transient Object m_oLogLock;
private final Object getLogLock() {
if (m_oLogLock == null) {
m_oLogLock = new Object();
}
return m_oLogLock;
}
protected ListenerHelper m_lhListeners = new ListenerHelper();
public DataBasketImpl() {
super();
setCurrentSubBasket (DEFAULTSUBBASKET_NAME);
}
public void rollback() {
rollback ((DataBasketCondition) null);
}
public void commit() {
commit ((DataBasketCondition) null);
}
public void rollback (DataBasketCondition dbc) {
synchronized (getChildrenLock()) {
synchronized (getLogLock()) {
for (Iterator i = m_mpsdbChildren.values().iterator(); i.hasNext();) {
((SubDataBasket) i.next()).rollback (dbc);
}
clean();
}
}
}
public void commit (DataBasketCondition dbc) {
synchronized (getChildrenLock()) {
synchronized (getLogLock()) {
for (Iterator i = m_mpsdbChildren.values().iterator(); i.hasNext();) {
((SubDataBasket) i.next()).commit (dbc);
}
clean();
}
}
}
public void rollbackSubBasket (String sName) {
SubDataBasket sdb = null;
synchronized (getChildrenLock()) {
sdb = (SubDataBasket) m_mpsdbChildren.get (sName);
synchronized (getLogLock()) {
if (sdb != null) {
sdb.rollback (null);
}
clean();
}
}
}
public void rollbackCurrentSubBasket() {
SubDataBasket sdbCurrent = null;
synchronized (getCurrentLock()) {
sdbCurrent = m_sdbCurrent;
}
if (sdbCurrent != null) {
synchronized (getChildrenLock()) {
synchronized (getLogLock()) {
sdbCurrent.rollback (null);
clean();
}
}
}
}
public void commitSubBasket (String sName) {
SubDataBasket sdb = null;
synchronized (getChildrenLock()) {
sdb = (SubDataBasket) m_mpsdbChildren.get (sName);
synchronized (getLogLock()) {
if (sdb != null) {
sdb.commit (null);
}
clean();
}
}
}
public void commitCurrentSubBasket() {
SubDataBasket sdbCurrent = null;
synchronized (getCurrentLock()) {
sdbCurrent = m_sdbCurrent;
}
if (sdbCurrent != null) {
synchronized (getChildrenLock()) {
synchronized (getLogLock()) {
sdbCurrent.commit (null);
clean();
}
}
}
}
public void setCurrentSubBasket(String sName) {
synchronized (getChildrenLock()) {
if (!m_mpsdbChildren.containsKey (sName)) {
SubDataBasket sdb = new SubDataBasket (this);
m_mpsdbChildren.put (sName, sdb);
}
synchronized (getCurrentLock()) {
m_sdbCurrent = (SubDataBasket) m_mpsdbChildren.get (sName);
}
}
}
public Iterator iterator (final DataBasketCondition dbc) {
class I implements Iterator {
private Iterator m_iChildKeys;
private Iterator m_iSubBasketItems;
private DataBasket m_dbSource;
public I (Iterator iChildKeys,
DataBasket dbSource) {
super();
m_iChildKeys = iChildKeys;
m_dbSource = dbSource;
}
public boolean hasNext() {
return findNextItem();
}
public Object next() {
if (!findNextItem()) {
throw new NoSuchElementException();
}
return m_iSubBasketItems.next();
}
public void remove() {
throw new UnsupportedOperationException();
}
private boolean findNextItem() {
while (((m_iSubBasketItems == null) ||
(!m_iSubBasketItems.hasNext())) &&
(m_iChildKeys.hasNext())){
String sNextBasket = (String) m_iChildKeys.next();
m_iSubBasketItems = m_dbSource.subBasketIterator (sNextBasket, dbc);
}
if ((m_iSubBasketItems == null) ||
(!m_iSubBasketItems.hasNext())) {
return false;
}
return true;
}
}
return new I (m_mpsdbChildren.keySet().iterator(), this);
}
public Iterator subBasketIterator (String sName, DataBasketCondition dbc) {
synchronized (getChildrenLock()) {
SubDataBasket sdb = (SubDataBasket) m_mpsdbChildren.get (sName);
return sdb.iterator (dbc, false, false);
}
}
public Value sumBasket (DataBasketCondition dbc, BasketEntryValue bev, Value vInit) {
synchronized (getChildrenLock()) {
for (Iterator i = m_mpsdbChildren.values().iterator(); i.hasNext();) {
SubDataBasket sdb = (SubDataBasket) i.next();
sdb.sumSubBasket (dbc, bev, vInit);
}
}
return vInit;
}
public Value sumSubBasket (String sName, DataBasketCondition dbc, BasketEntryValue bev, Value vInit) {
SubDataBasket sdb = null;
synchronized (getChildrenLock()) {
sdb = (SubDataBasket) m_mpsdbChildren.get (sName);
return sdb.sumSubBasket (dbc, bev, vInit);
}
}
public Value sumCurrentSubBasket (DataBasketCondition dbc, BasketEntryValue bev, Value vInit) {
synchronized (getCurrentLock()) {
return m_sdbCurrent.sumSubBasket (dbc, bev, vInit);
}
}
public void put (DataBasketEntry dbe) {
synchronized (getCurrentLock()) {
synchronized (getChildrenLock()) {
synchronized (getLogLock()) {
m_sdbCurrent.put ((DataBasketEntryImpl) dbe);
}
}
}
}
public void exchange (final DataBasketEntry dbeOrg, DataBasketEntry dbeNew) {
DataBasketCondition dbc = new DataBasketConditionImpl (dbeOrg.getMainKey(),
dbeOrg.getSecondaryKey(),
dbeOrg.getSource(),
dbeOrg.getDestination(),
null) {
public boolean match (DataBasketEntry dbe) {
return (dbe == dbeOrg);
}
};
synchronized (getChildrenLock()) {
synchronized (getLogLock()) {
for (Iterator i = m_mpsdbChildren.values().iterator(); i.hasNext();) {
SubDataBasket sdb = (SubDataBasket) i.next();
Iterator i1 = sdb.iterator (dbc, true, false);
if (i1.hasNext()) {
DataBasketEntryImpl dbe = (DataBasketEntryImpl) i1.next();
i1.remove();
log (EXCHANGE_REMOVE_ACTION, dbe);
sdb.put ((DataBasketEntryImpl) dbeNew);
return;
}
}
put (dbeNew);
}
}
}
public DataBasketEntry get (DataBasketCondition dbc) {
synchronized (getChildrenLock()) {
Iterator i = iterator (dbc);
if (i.hasNext()) {
return (DataBasketEntry) i.next();
}
else {
return null;
}
}
}
public boolean contains (DataBasketCondition dbc) {
synchronized (getChildrenLock()) {
return (iterator (dbc).hasNext());
}
}
public LogContext setLogContext (LogContext lcNew) {
synchronized (getLogLock()) {
LogContext lc = m_lcLog;
m_lcLog = lcNew;
return lc;
}
}
public int setLogMode (int nLogMode) {
synchronized (getLogLock()) {
int n = m_nLogMode;
m_nLogMode = nLogMode;
return n;
}
}
public int getLogMode() {
synchronized (getLogLock()) {
return m_nLogMode;
}
}
public static final int PUT_ACTION = 0;
public static final int EXCHANGE_REMOVE_ACTION = 1;
public static final int COMMIT_ACTION = 2;
public static final int ROLLBACK_ACTION = 3;
public static final LogEntryFilter LOGENTRYFILTER_DATABASKETIMPLACTIONS = new LogEntryFilter() {
public boolean accept (LogEntry le) {
return (le instanceof DataBasketImplLogEntry);
}
};
public static final LogEntryFilter LOGENTRYFILTER_NO_DATABASKETIMPLACTIONS = new LogEntryFilter() {
public boolean accept (LogEntry le) {
return !(le instanceof DataBasketImplLogEntry);
}
};
public static final LogEntryFilter LOGENTRYFILTER_PUT_ACTIONS = new LogEntryFilter() {
public boolean accept (LogEntry le) {
return ((le instanceof DataBasketImplLogEntry) &&
(((DataBasketImplLogEntry) le).getAction() == PUT_ACTION));
}
};
public static final LogEntryFilter LOGENTRYFILTER_EXCHANGE_REMOVE_ACTIONS = new LogEntryFilter() {
public boolean accept (LogEntry le) {
return ((le instanceof DataBasketImplLogEntry) &&
(((DataBasketImplLogEntry) le).getAction() == EXCHANGE_REMOVE_ACTION));
}
};
public static final LogEntryFilter LOGENTRYFILTER_COMMIT_ACTIONS = new LogEntryFilter() {
public boolean accept (LogEntry le) {
return ((le instanceof DataBasketImplLogEntry) &&
(((DataBasketImplLogEntry) le).getAction() == COMMIT_ACTION));
}
};
public static final LogEntryFilter LOGENTRYFILTER_ROLLBACK_ACTIONS = new LogEntryFilter() {
public boolean accept (LogEntry le) {
return ((le instanceof DataBasketImplLogEntry) &&
(((DataBasketImplLogEntry) le).getAction() == ROLLBACK_ACTION));
}
};
public static class DataBasketImplLogEntry extends LogEntry {
private LogEntry m_leData;
private int m_nAction;
private static String[] s_asActionNames = {"PUT_ACTION",
"EXCHANGE_REMOVE_ACTION",
"COMMIT_ACTION",
"ROLLBACK_ACTION"};
public DataBasketImplLogEntry (int nAction,
LogEntry leData) {
super();
m_nAction = nAction;
m_leData = leData;
}
public int getAction() {
return m_nAction;
}
public String getActionName() {
return s_asActionNames[getAction()];
}
public LogEntry getData() {
return m_leData;
}
public String toString() {
return getActionName() + " performed on " + getData();
}
}
public void log (int nAction,
Loggable la) {
synchronized (getLogLock()) {
if (m_lcLog != null) {
switch (m_nLogMode) {
case LOG_MODE_NONE:
return;
case LOG_MODE_COMMITS_ONLY:
if (nAction != COMMIT_ACTION) {
return;
}
break;
case LOG_MODE_ROLLBACKS_ONLY:
if (nAction != ROLLBACK_ACTION) {
return;
}
}
final DataBasketImplLogEntry dbile = new DataBasketImplLogEntry (nAction, la.getLogData());
try {
m_lcLog.log (new Loggable() {
public LogEntry getLogData() {
return dbile;
}
});
}
catch (java.io.IOException ioe) {
ioe.printStackTrace();
}
}
}
}
public Object getDBIMonitor() {
return getChildrenLock();
}
protected void clean() {
for (Iterator i = m_mpsdbChildren.values().iterator(); i.hasNext();) {
Iterator j = ((SubDataBasket) i.next()).iterator (null, true, true);
while (j.hasNext()) {
if (((DataBasketEntry) j.next()).isHandled()) {
j.remove();
}
}
}
}
public void addDataBasketListener (DataBasketListener dbl) {
m_lhListeners.add (DataBasketListener.class, dbl);
}
public void removeDataBasketListener (DataBasketListener dbl) {
m_lhListeners.remove (DataBasketListener.class, dbl);
}
public void fireDataBasketChanged() {
Object[] listeners = m_lhListeners.getListenerList();
DataBasketEvent e = null;
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i] == DataBasketListener.class) {
if (e == null) {
e = new DataBasketEvent (this, null);
}
((DataBasketListener) listeners[i+1]).dataBasketChanged (e);
}
}
}
protected void fireDBEAdded (DataBasketEntry dbe) {
Object[] listeners = m_lhListeners.getListenerList();
DataBasketEvent e = null;
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i] == DataBasketListener.class) {
if (e == null) {
e = new DataBasketEvent (this, dbe);
}
((DataBasketListener) listeners[i+1]).addedDBE (e);
}
}
}
protected void fireDBERemoved (DataBasketEntry dbe) {
Object[] listeners = m_lhListeners.getListenerList();
DataBasketEvent e = null;
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i] == DataBasketListener.class) {
if (e == null) {
e = new DataBasketEvent (this, dbe);
}
((DataBasketListener) listeners[i+1]).removedDBE (e);
}
}
}
}