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; } }