/* Protocol Definition Language Copyright (C) 2003-2006 Marcus Andersson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.nmedit.jpdl2.impl; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import net.sf.nmedit.jpdl2.PDLPacket; import net.sf.nmedit.jpdl2.dom.PDLPacketDecl; public class PDLPacketImpl implements PDLPacket { private Map<String, PacketObject> packetObjects = new HashMap<String, PacketObject>(); private int age = 0; private PDLPacketDecl decl; private String binding; public PDLPacketImpl(PDLPacketDecl decl, String binding) { this.decl = decl; this.binding = binding; } public String getBinding() { return binding; } public String getName() { return decl.getName(); } public int getCurrentAge() { return age; } public final int incrementAge() { return age++; } public void removeItemsOlderThan(int minAge) { if (this.age>minAge) { boolean itemsRemoved = false; for (Iterator<PacketObject> iter=packetObjects.values().iterator();iter.hasNext();) { if (iter.next().age>=minAge) { iter.remove(); itemsRemoved = true; } } if (itemsRemoved) this.age = minAge+1; } } public boolean containsPacket(String packetName) { if (decl.getName().equals(packetName)) { return true; } else { for (PacketObject o: packetObjects.values()) { if (o instanceof Packet) { PDLPacket p = ((Packet)o).packet; if (p.containsPacket(packetName)) return true; } else if (o instanceof PacketList) { PDLPacket[] list = ((PacketList)o).packets; for (int i=0;i<list.length;i++) if (list[i].containsPacket(packetName)) return true; } } } return false; } protected boolean contains(String name) { return packetObjects.get(name) != null; } private boolean contains(String name, PacketObjectType type) { PacketObject o = packetObjects.get(name); return o != null && o.getType() == type; } private PacketObject getPacketObject(String name, PacketObjectType type) { PacketObject o = packetObjects.get(name); if (name != null && o != null && type == o.getType()) return o; else return null; } public boolean hasVariable(String name) { return contains(name, PacketObjectType.Variable); } public boolean hasPacket(String name) { return contains(name, PacketObjectType.Packet); } public boolean hasVariableList(String name) { return contains(name, PacketObjectType.VariableList); } public boolean hasString(String name) { return contains(name, PacketObjectType.String); } public boolean hasPacketList(String name) { return contains(name, PacketObjectType.PacketList); } private void setPacketObject(String name, PacketObject o) { packetObjects.put(name, o); } public void setVariable(String name, int value) { setPacketObject(name, new Variable(name, value)); } public void setVariableList(String name, int[] values) { if (values == null) throw new NullPointerException(); setPacketObject(name, new VariableList(name, values)); } public void setPacket(String name, PDLPacket packet) { if (packet == null) throw new NullPointerException(); setPacketObject(name, new Packet(name, packet)); } public void setPacketList(String name, PDLPacket[] packets) { if (packets == null) throw new NullPointerException(); setPacketObject(name, new PacketList(name, packets)); } public void setString(String name, String value) { if (value == null) throw new NullPointerException(); setPacketObject(name, new POString(name, value)); } public String getString(String name) { int pos = name.indexOf(":"); if (pos >= 0) { return getPacket(name.substring(0, pos)).getString(name.substring(pos+1)); } PacketObject o = getPacketObject(name, PacketObjectType.String); if (o == null) throw new IllegalArgumentException("string not defined: "+name); return ((POString)o).value; } public int getVariable(String name) { int pos = name.indexOf(":"); if (pos >= 0) { return getPacket(name.substring(0, pos)).getVariable(name.substring(pos+1)); } PacketObject o = getPacketObject(name, PacketObjectType.Variable); if (o == null) throw new IllegalArgumentException("variable not defined: "+name); return ((Variable)o).value; } public int getVariable(String name, int defaultValue) { int pos = name.indexOf(":"); if (pos >= 0) { return getPacket(name.substring(0, pos)).getVariable(name.substring(pos+1), defaultValue); } PacketObject o = getPacketObject(name, PacketObjectType.Variable); if (o == null) return defaultValue; return ((Variable)o).value; } public int[] getVariableList(String name) { int pos = name.indexOf(":"); if (pos >= 0) { return getPacket(name.substring(0, pos)).getVariableList(name.substring(pos+1)); } PacketObject o = getPacketObject(name, PacketObjectType.VariableList); if (o == null) return null; int[] list = ((VariableList)o).values; int[] copy = new int[list.length]; for (int i = 0; i < list.length; i++) copy[i] = list[i]; return copy; } public PDLPacket getPacket(String name) { int pos = name.indexOf(":"); if (pos >= 0) { String packetName = name.substring(0, pos); PacketObject o = getPacketObject(packetName, PacketObjectType.Packet); return ((Packet)o).packet.getPacket(name.substring(pos+1)); } PacketObject o = getPacketObject(name, PacketObjectType.Packet); if (o == null) return null; return ((Packet)o).packet; } public PDLPacket[] getPacketList(String name) { int pos = name.indexOf(":"); if (pos >= 0) { return getPacket(name.substring(0, pos)).getPacketList(name.substring(pos+1)); } PacketObject o = getPacketObject(name, PacketObjectType.PacketList); if (o == null) return null; PDLPacket[] list = ((PacketList)o).packets; PDLPacket[] copy = new PDLPacket[list.length]; for (int i = 0; i < list.length; i++) copy[i] = list[i]; return copy; } private static enum PacketObjectType { Variable, VariableList, Packet, PacketList, String } private List<String> getAllKeys(PacketObjectType type) { PacketObject[] items = new PacketObject[packetObjects.size()]; int size = 0; for (PacketObject po:packetObjects.values()) if (po.getType() == type) { items[size++] = po; } Arrays.sort(items, 0, size, AgeComparator.instance); List<String> names = new ArrayList<String>(size); for (int i=0;i<size;i++) names.add(items[i].name); names = Collections.unmodifiableList(names); return names; } public List<String> getAllVariables() { return getAllKeys(PacketObjectType.Variable); } private static class AgeComparator implements Comparator<PacketObject> { private static AgeComparator instance = new AgeComparator(); public int compare(PacketObject a, PacketObject b) { return a.age-b.age; } } private abstract class PacketObject { int age = PDLPacketImpl.this.incrementAge(); String name; public PacketObject(String name){this.name = name;} public abstract PacketObjectType getType(); } private class POString extends PacketObject { String value; public POString(String name, String value) { super(name); this.value = value; } public PacketObjectType getType() { return PacketObjectType.String; } } private class Variable extends PacketObject { int value; public Variable(String name, int value) { super(name); this.value = value; } public PacketObjectType getType() { return PacketObjectType.Variable; } } private class VariableList extends PacketObject { int[] values; public VariableList(String name, int[] values) { super(name); this.values = values; } public PacketObjectType getType() { return PacketObjectType.VariableList; } } private class Packet extends PacketObject { PDLPacket packet; public Packet(String name, PDLPacket packet) { super(name); this.packet = packet; } public PacketObjectType getType() { return PacketObjectType.Packet; } } private class PacketList extends PacketObject { PDLPacket[] packets; public PacketList(String name, PDLPacket[] packets) { super(name); this.packets = packets; } public PacketObjectType getType() { return PacketObjectType.PacketList; } } public String toString() { return "packet "+decl.getName(); } public List<String> getAllPacketLists() { return getAllKeys(PacketObjectType.PacketList); } public List<String> getAllPackets() { return getAllKeys(PacketObjectType.Packet); } public List<String> getAllVariableLists() { return getAllKeys(PacketObjectType.VariableList); } public List<String> getAllStrings() { return getAllKeys(PacketObjectType.String); } }