/**
*
*/
package com.grendelscan.commons.flex;
import java.util.ArrayList;
import java.util.List;
import com.grendelscan.commons.StringUtils;
import com.grendelscan.commons.collections.BidiMap;
import com.grendelscan.commons.flex.dataTypeDefinitions.AmfDataType;
import com.grendelscan.commons.flex.interfaces.ArbitraryChildren;
import com.grendelscan.commons.http.dataHandling.containers.ExpandableDataContainer;
import com.grendelscan.commons.http.dataHandling.data.Data;
import com.grendelscan.commons.http.dataHandling.data.DataUtils;
import com.grendelscan.commons.http.dataHandling.references.DataReference;
import com.grendelscan.commons.http.dataHandling.references.NamedDataContainerDataReference;
/**
* @author david
*
*/
public abstract class AbstractAmfNamedDataContainer extends AbstractAmfDataContainer<NamedDataContainerDataReference> implements ArbitraryChildren, ExpandableDataContainer<NamedDataContainerDataReference>
{
protected BidiMap<byte[], NamedAmfDataContainer> properties;
private static final long serialVersionUID = 1L;
/**
* @param name
* @param type
* @param parent
* @param forceAmf3Code
* @param reference
* @param transactionId
*/
public AbstractAmfNamedDataContainer(final String name, final AmfDataType type, final AbstractAmfDataContainer<?> parent, final boolean forceAmf3Code, final int transactionId)
{
super(name, type, parent, forceAmf3Code, transactionId);
properties = new BidiMap<byte[], NamedAmfDataContainer>(1);
// properties = new BidiMap<byte[], NamedAmfDataContainer>(1);
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.containers.DataContainer#addChild(com.grendelscan.commons.http.dataHandling.data.Data)
*/
@Override
public void addChild(final Data child)
{
if (!(child instanceof NamedAmfDataContainer))
{
throw new IllegalArgumentException("Children must be of type NamedAmfDataContainer");
}
NamedAmfDataContainer amfChild = (NamedAmfDataContainer) child;
properties.put(DataUtils.getBytes(amfChild.getNameData()), amfChild);
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.containers.DataContainer#addChild(com.grendelscan.commons.http.dataHandling.references.DataReference,
* com.grendelscan.commons.http.dataHandling.data.Data)
*/
@Override
public void addChild(@SuppressWarnings("unused") final NamedDataContainerDataReference reference, final Data child)
{
addChild(child);
}
@Override
public String childrenDebugString()
{
StringBuilder sb = new StringBuilder();
sb.append("AMF properties:");
for (byte[] key : properties.keySet())
{
sb.append("\n\tkey: ");
sb.append(key);
sb.append("\nvalue:\n");
sb.append(StringUtils.indentLines(properties.get(key).debugString(), 2));
}
return sb.toString();
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.containers.DataContainer#getChild(com.grendelscan.commons.http.dataHandling.references.DataReference)
*/
@Override
public Data getChild(final NamedDataContainerDataReference reference)
{
return properties.get(reference.getName());
}
public AbstractAmfData getChild(final String name)
{
NamedAmfDataContainer param = properties.get(name.getBytes());
if (param == null)
{
return null;
}
return param.getValueData();
}
public List<byte[]> getChildNames()
{
return properties.getSortedKeys();
}
@Override
public ArrayList<AbstractAmfData> getChildren()
{
ArrayList<AbstractAmfData> children = new ArrayList<AbstractAmfData>(properties.size());
for (NamedAmfDataContainer data : properties.getSortedValues())
{
children.add(data.getValueData());
}
return children;
}
@Override
public NamedDataContainerDataReference getChildsReference(final Data child)
{
if (properties.containsValue(child))
{
return new NamedDataContainerDataReference(properties.getKey((NamedAmfDataContainer) child));
}
throw new IllegalArgumentException("The passed data object is not a child of this container");
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.containers.DataContainer#getChildUnsafeType(com.grendelscan.commons.http.dataHandling.references.DataReference)
*/
@Override
public Data getChildUnsafeType(final DataReference reference)
{
return getChild((NamedDataContainerDataReference) reference);
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.containers.DataContainer#getDataChildren()
*/
@Override
public Data[] getDataChildren()
{
return properties.getSortedValues().toArray(new Data[properties.size()]);
}
@Override
public int getSize()
{
return properties.size();
}
@Override
public boolean isMutable()
{
return true;
}
public Data putChild(final String name, final AbstractAmfData child)
{
child.setName(name);
NamedAmfDataContainer container = new NamedAmfDataContainer(this, getTransactionId(), name, child);
NamedAmfDataContainer oldValue = properties.put(name.getBytes(), container);
// Data oldValue = properties.put(name.getBytes(), child);
if (oldValue == null)
{
return null;
}
return oldValue;
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.containers.DataContainer#removeChild(com.grendelscan.commons.http.dataHandling.data.Data)
*/
@Override
public void removeChild(final Data child)
{
NamedAmfDataContainer amfChild = (NamedAmfDataContainer) child;
if (amfChild.getValueData().isDeletable())
{
properties.removeValue(amfChild);
}
}
public AbstractAmfData removeChild(final String name)
{
NamedAmfDataContainer oldValue = properties.remove(name.getBytes());
if (oldValue == null || oldValue.getValueData().isDeletable())
{
return null;
}
return oldValue.getValueData();
}
/*
* (non-Javadoc)
*
* @see com.grendelscan.commons.http.dataHandling.containers.DataContainer#replaceChild(com.grendelscan.commons.http.dataHandling.references.DataReference,
* com.grendelscan.commons.http.dataHandling.data.Data)
*/
@Override
public void replaceChild(@SuppressWarnings("unused") final NamedDataContainerDataReference reference, final Data child)
{
addChild(child);
}
}