package com.aionemu.packetsamurai.parser.datatree;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.aionemu.packetsamurai.parser.PartType;
import com.aionemu.packetsamurai.parser.DataStructure.DataPacketMode;
import com.aionemu.packetsamurai.parser.formattree.ForPart;
import com.aionemu.packetsamurai.parser.formattree.Part;
import com.aionemu.packetsamurai.parser.formattree.PartContainer;
/**
*
* @author Gilles Duboscq
*
*/
public class DataTreeNodeContainer extends DataTreeNode
{
private Map<Integer, ValuePart> _partIdMap = new HashMap<Integer, ValuePart>();
private List<DataTreeNode> _nodes = new LinkedList<DataTreeNode>();
private boolean _isRoot;
// can not intantiate non-root container
protected DataTreeNodeContainer(DataTreeNodeContainer container, Part part)
{
super(container, part);
if(!(part instanceof PartContainer || part instanceof ForPart))
{
System.out.println("Class: "+part.getClass().getName());
throw new IllegalArgumentException("The model of a packet node container must be a blockpart/switchcase/forpart");
}
_isRoot = false;
}
public DataTreeNodeContainer()
{
super();
_isRoot = true;
}
public DataTreeNodeContainer(DataPacketMode mode)
{
super(mode);
_isRoot = true;
}
public boolean isRoot()
{
return _isRoot;
}
public void addNode(DataTreeNode node)
{
_nodes.add(node);
if(node instanceof ValuePart && node.getModelPart().getId() != -1)
_partIdMap.put(node.getModelPart().getId(), (ValuePart) node);
}
/**
* Searches into parent containers until the part is found or the top level container is reached.
* @param id The Id of the PacketPart to be retrieved
* @return The PacketPart with the given Id if found, null otherwise
*/
public ValuePart getPacketValuePartById(int id)
{
ValuePart vp = _partIdMap.get(id);
if (vp == null && !this.isRoot())
return this.getParentContainer().getPacketValuePartById(id);
return vp;
}
public Map<Integer, ValuePart> getPartIdMap()
{
return Collections.unmodifiableMap(_partIdMap);
}
public List<? extends DataTreeNode> getNodes()
{
return _nodes;
}
public DataTreeNode getPartByName(String name)
{
return getPartByName(name, false);
}
public DataTreeNode getPartByName(String name, boolean enterSwitch)
{
for (DataTreeNode node : this.getNodes())
{
if (name.equals(node.getModelPart().getName()))
return node;
if(enterSwitch && node instanceof DataTreeNodeContainer && node.getModelPart().getType() == PartType.swicthBlock)
{
((DataTreeNodeContainer)node).getPartByName(name, true);
}
}
return null;
}
public DataTreeNode getPartById(int id)
{
return getPartById(id, false);
}
public DataTreeNode getPartById(int id, boolean enterSwitch)
{
for (DataTreeNode node : this.getNodes())
{
if (node.getModelPart().getId() == id)
return node;
if(enterSwitch && node instanceof DataTreeNodeContainer && node.getModelPart().getType() == PartType.swicthBlock)
{
((DataTreeNodeContainer)node).getPartById(id, true);
}
}
return null;
}
public DataTreeNode getPartByAnalyserName(String analyserName)
{
return getPartByAnalyserName(analyserName, false);
}
public DataTreeNode getPartByAnalyserName(String analyserName, boolean enterSwitch)
{
for (DataTreeNode node : this.getNodes())
{
if (analyserName.equals(node.getModelPart().getAnalyzerName()))
return node;
if(enterSwitch && node instanceof DataTreeNodeContainer && node.getModelPart().getType() == PartType.swicthBlock)
{
DataTreeNode part = ((DataTreeNodeContainer)node).getPartByAnalyserName(analyserName, true);
if (part != null)
{
return part;
}
}
}
return null;
}
public String getValueByAnalyzerName(String string)
{
DataTreeNode part = getPartByAnalyserName(string);
if(part != null && part instanceof ValuePart)
{
return ((ValuePart)part).getValueAsString();
}
return null;
}
public int getBytesSize()
{
int size = 0;
for (DataTreeNode dpn : this.getNodes())
{
size += dpn.getBytesSize();
}
return size;
}
}