diff options
Diffstat (limited to 'evc/evcbase/src/main')
5 files changed, 598 insertions, 0 deletions
diff --git a/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/client/EvcClient.java b/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/client/EvcClient.java new file mode 100644 index 0000000..25fae8b --- /dev/null +++ b/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/client/EvcClient.java @@ -0,0 +1,149 @@ +package com.cablelabs.vcpe.evc.evcbase.client; + +import com.cablelabs.vcpe.evc.evcbase.model.Evc; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.List; + +/** + * Created by steve on 6/8/15. + */ +public class EvcClient { + + private Client client; // provided by Jersey + + public EvcClient() { + client = ClientBuilder.newClient(); + } + + //-------------------------------------------------------- + public Evc create(Evc evc) + //-------------------------------------------------------- + { + WebTarget target =client.target("http://localhost:9090/evcmgr/webapi/"); + Response response = target.path("evc") + .request(MediaType.APPLICATION_JSON) + .post(Entity.entity(evc, MediaType.APPLICATION_JSON)); + + if (response.getStatus() != 200 ) // figure out how to use Status.OK + { + // in production you can be more specific based on reponse code, id, etc + throw new RuntimeException(response.getStatus() + ": there was an error on the server."); + } + return response.readEntity(Evc.class); + } + + //-------------------------------------------------------- + public Evc update(Evc evc) + //-------------------------------------------------------- + { + WebTarget target =client.target("http://localhost:9090/evcmgr/webapi/"); + Response response = target.path("evc/"+evc.getId()) + .request(MediaType.APPLICATION_JSON) + .put(Entity.entity(evc, MediaType.APPLICATION_JSON)); + + if (response.getStatus() != 200 ) // figure out how to use Status.OK + { + // in production you can be more specific based on reponse code, id, etc + throw new RuntimeException(response.getStatus() + ": there was an error on the server."); + } + return response.readEntity(Evc.class); + } + + //-------------------------------------------------------- + public Evc get(String evcId) + //-------------------------------------------------------- + // get Evc of specified ID + + { + WebTarget target = client.target("http://localhost:9090/evcmgr/webapi/"); + + Response response = target.path("evc/"+evcId).request(MediaType.APPLICATION_JSON).get(Response.class); + if (response.getStatus() != 200) // figure out how to use Status.OK + { + // in production you can be more specific based on reponse code, id, etc + throw new RuntimeException(response.getStatus() + ": there was an error on the server."); + } + + //return response; + return response.readEntity(Evc.class); + } + + //-------------------------------------------------------- + public List<Evc> getAll() + //-------------------------------------------------------- + // get a list of all Evc instances + { + + WebTarget target = client.target("http://localhost:9090/evcmgr/webapi/"); + + // Can I do this with a Response, so that I can check for errors + List<Evc> response = target.path("evc/list") + .request(MediaType.APPLICATION_JSON) + .get(new GenericType<List<Evc>>() { + }); + if (response == null) // figure out how to use Status.OK + { + // in production you can be more specific based on reponse code, id, etc + throw new RuntimeException("there was an error on the server."); + } + return response; + } + + //-------------------------------------------------------- + public void delete(String evcId) + //-------------------------------------------------------- + // delete Evc of specified ID + { + WebTarget target = client.target("http://localhost:9090/evcmgr/webapi/"); + Response response = target.path("evc/"+evcId).request(MediaType.APPLICATION_JSON).delete(); + if (response.getStatus() != 200) // figure out how to use Status.OK + { + // in production you can be more specific based on reponse code, id, etc + throw new RuntimeException(response.getStatus() + ": there was an error on the server."); + } + } + + //-------------------------------------------------------- + public Evc testGet() + //-------------------------------------------------------- + // test marshaling of Evc class from server json + + { + WebTarget target = client.target("http://localhost:9090/evcmgr/webapi/"); + + Response response = target.path("evc").request(MediaType.APPLICATION_JSON).get(Response.class); + if (response.getStatus() != 200) // figure out how to use Status.OK + { + // in production you can be more specific based on reponse code, id, etc + throw new RuntimeException(response.getStatus() + ": there was an error on the server."); + } + + //return response; + return response.readEntity(Evc.class); + } + + //-------------------------------------------------------- + public String ping() + //-------------------------------------------------------- + // test connectivity + { + + WebTarget target = client.target("http://localhost:9090/evcmgr/webapi/"); + + Response response = target.path("evc").request(MediaType.TEXT_PLAIN).get(); + if (response.getStatus() != 200) // figure out how to use Status.OK + { + // in production you can be more specific based on reponse code, id, etc + throw new RuntimeException(response.getStatus() + ": there was an error on the server."); + } + + return response.readEntity(String.class); + } +} diff --git a/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/model/Evc.java b/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/model/Evc.java new file mode 100644 index 0000000..f44af27 --- /dev/null +++ b/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/model/Evc.java @@ -0,0 +1,235 @@ +package com.cablelabs.vcpe.evc.evcbase.model; + +import com.cablelabs.vcpe.common.Dbg; + +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +/** + * Created by steve on 5/24/15. + */ + +@XmlRootElement +public class Evc +{ + // set up so that we can use the ENUM's as strings for REST calls & dbg prints + + public enum EvcType { + + UNASSIGNED ("UNASSIGNED"), + POINT_TO_POINT ("POINT_TO_POINT"), + MULTIPOINT_TO_MULTIPOINT ("MULTIPOINT_TO_MULTIPOINT"), + ROOTED_MULTIPOINT ("ROOTED_MULTIPOINT"); + private final String s; + private EvcType(final String s) {this.s = s;} + @Override public String toString() { return s; } + } + public enum FrameDelivery { // may belong in more general location eventually + + UNASSIGNED ("UNASSIGNED"), + DISCARD ("DISCARD"), + UNCONDITIONAL ("UNCONDITIONAL"), + CONDITIONAL ("CONDITIONAL"); + private final String s; + private FrameDelivery(final String s) {this.s = s;} + @Override public String toString() { return s; } + } + + private String id; + private EvcType evcType; + private long maxUnis; + private FrameDelivery unicastFrameDelivery; + private FrameDelivery multicastFrameDelivery; + private FrameDelivery broadcastFrameDelivery; + private List<String> uniIdList = null; + private List<String> uniIpList = null; + private List<String> uniMacList = null; + private boolean ceVLanIdPreservation; + private boolean ceVlanCosPreservation; + private long evcMaxSvcFrameSize; // at least 1522, should be > 1600 byte + private String cosId; // CoS Attributes serving as EVCPerformance attr for now + //private EvcPerf evcPerf = null; + + // EVC Perf params + private double oneWayFrameDelay; // milliseconds + private double oneWayFrameLossRatio; // percentage + private double oneWayAvailability; // percentage + + // zero argument constructor required for JAX-RS + public Evc() { + id = "unset"; + evcType = EvcType.UNASSIGNED; + maxUnis = -1; + unicastFrameDelivery = FrameDelivery.UNASSIGNED; + multicastFrameDelivery = FrameDelivery.UNASSIGNED;; + broadcastFrameDelivery = FrameDelivery.UNASSIGNED;; + uniIdList = null; + uniIpList = null; + uniMacList = null; + ceVLanIdPreservation = false; + ceVlanCosPreservation = false; + evcMaxSvcFrameSize = -1; + cosId = "unset"; + + //evcPerf = new EvcPerf(); + oneWayFrameDelay = -1.0; + oneWayFrameLossRatio = -1.0; + oneWayAvailability = -1.0; + } + + // Utility methods + + public void setAllNonPerfProps(String id, EvcType evcType, long maxUnis, + List<String> uniIdList, List<String> uniMacList, List<String> uniIpList, + FrameDelivery unicastFrameDelivery, + FrameDelivery multicastFrameDelivery, + FrameDelivery broadcastFrameDelivery, + boolean ceVLanIdPreservation, boolean ceVlanCosPreservation, + long evcMaxSvcFrameSize, String cosId) { + this.id = id; + this.evcType = evcType; + this.uniIdList = uniIdList; + this.uniMacList = uniMacList; + this.uniIpList = uniIpList; + this.maxUnis = maxUnis; + this.unicastFrameDelivery = unicastFrameDelivery; + this.multicastFrameDelivery = multicastFrameDelivery; + this.broadcastFrameDelivery = broadcastFrameDelivery; + this.ceVLanIdPreservation = ceVLanIdPreservation; + this.ceVlanCosPreservation = ceVlanCosPreservation; + this.evcMaxSvcFrameSize = evcMaxSvcFrameSize; + this.cosId = cosId; + } + + public void setAllPerfProps( double oneWayFrameDelay, + double oneWayFrameLossRatio, + double oneWayAvailability ) + { + this.oneWayFrameDelay = oneWayFrameDelay; + this.oneWayFrameLossRatio = oneWayFrameLossRatio; + this.oneWayAvailability = oneWayAvailability; + } + + public void dump() { dump(0); } + public void dump(int tab) { + Dbg.p(tab, "id: " + this.id); + Dbg.p(tab, "cosId: " + this.cosId); + Dbg.p(tab, "evcType: " + this.evcType); + Dbg.p(tab, "maxUnis: " + this.maxUnis); + Dbg.p(tab, "Uni ID List:"); + for (String uniId : uniIdList) + Dbg.p(tab+1, uniId); + Dbg.p(tab, "Uni Mac List:"); + for (String macId : uniMacList) + Dbg.p(tab+1, macId); + Dbg.p(tab, "Uni IP List:"); + for (String ipAddr : uniIpList) + Dbg.p(tab+1, ipAddr); + Dbg.p(tab, "UnicastFrameDelivery: " + this.unicastFrameDelivery); + Dbg.p(tab, "MulticastFrameDelivery: " + this.multicastFrameDelivery); + Dbg.p(tab, "BroadcastFrameDelivery: " + this.broadcastFrameDelivery); + Dbg.p(tab, "CeVLanIdPreservation: " + this.ceVLanIdPreservation); + Dbg.p(tab, "CeVlanCosPreservation: " + this.ceVlanCosPreservation); + Dbg.p(tab, "EvcMaxSvcFrameSize: " + this.evcMaxSvcFrameSize); + Dbg.p(tab, "--- EVC Performance Params"); + Dbg.p(tab+1, "oneWayFrameDelay: " + this.oneWayFrameDelay); + Dbg.p(tab+1, "oneWayFrameLossRatio: " + this.oneWayFrameLossRatio); + Dbg.p(tab+1, "oneWayAvailability: " + this.oneWayAvailability); + } + + public static void dumpList(List<Evc> evcList) { dumpList(0, evcList); } + public static void dumpList(int tab, List<Evc> evcList) { + int numEvc = 0; + Dbg.p("----- Evc List : [" + evcList.size() + "] elements"); + for (Evc curEvc : evcList) { + numEvc++; + Dbg.p(tab+1, "<Entry " + numEvc+">"); + curEvc.dump(tab+2); + } + } + + // Getters & Setters + + public String getId() { return id; } + public void setId(String id) { this.id = id; } + + public EvcType getEvcType() { return evcType; } + public void setEvcType(EvcType evcType) { this.evcType = evcType; } + + public long getMaxUnis() { return maxUnis; } + + public void setMaxUnis(long maxUnis) { this.maxUnis = maxUnis; } + + public FrameDelivery getUnicastFrameDelivery() { return unicastFrameDelivery; } + public void setUnicastFrameDelivery(FrameDelivery unicastFrameDelivery) { + this.unicastFrameDelivery = unicastFrameDelivery; } + + public FrameDelivery getMulticastFrameDelivery() { return multicastFrameDelivery; } + public void setMulticastFrameDelivery(FrameDelivery multicastFrameDelivery) { + this.multicastFrameDelivery = multicastFrameDelivery; } + + public FrameDelivery getBroadcastFrameDelivery() { return broadcastFrameDelivery; } + public void setBroadcastFrameDelivery(FrameDelivery broadcastFrameDelivery) { + this.broadcastFrameDelivery = broadcastFrameDelivery; } + + public List<String> getUniIdList() { return uniIdList; } + public void setUniIdList(List<String> uniIdList) { this.uniIdList = uniIdList; } + + public List<String> getUniMacList() { return uniMacList; } + public void setUniMacList(List<String> uniMacList) { this.uniMacList = uniMacList; } + + + public List<String> getUniIpList() { return uniIpList; } + public void setUniIpList(List<String> uniIpList) { this.uniIpList = uniIpList; } + + public boolean isCeVLanIdPreservation() { return ceVLanIdPreservation; } + public void setCeVLanIdPreservation(boolean ceVLanIdPreservation) { + this.ceVLanIdPreservation = ceVLanIdPreservation; } + + public boolean isCeVlanCosPreservation() { return ceVlanCosPreservation; } + + public void setCeVlanCosPreservation(boolean ceVlanCosPreservation) { + this.ceVlanCosPreservation = ceVlanCosPreservation; } + + public long getEvcMaxSvcFrameSize() { return evcMaxSvcFrameSize; } + public void setEvcMaxSvcFrameSize(long evcMaxSvcFrameSize) { + this.evcMaxSvcFrameSize = evcMaxSvcFrameSize; } + + public String getCosId() { return cosId; } + public void setCosId(String cosId) { this.cosId = cosId; } + + public double getOneWayFrameDelay() { return oneWayFrameDelay; } + public void setOneWayFrameDelay(double oneWayFrameDelay) { this.oneWayFrameDelay = oneWayFrameDelay; } + + public double getOneWayFrameLossRatio() { return oneWayFrameLossRatio; } + public void setOneWayFrameLossRatio(double oneWayFrameLossRatio) { this.oneWayFrameLossRatio = oneWayFrameLossRatio; } + + public double getOneWayAvailability() { return oneWayAvailability; } + public void setOneWayAvailability(double oneWayAvailability) { this.oneWayAvailability = oneWayAvailability; } + + + // Someday might make sense to put all EVC Perf params in seperate class +// private class EvcPerf { +// private long oneWayFrameDelay; // milliseconds +// private long oneWayFrameDelayRange; // milliseconds +// +// +// public EvcPerf () { +// this.oneWayFrameDelay = -333; +// this.oneWayFrameDelayRange = -333; +// } +// +// public void setAllParams (long oneWayFrameDelay, long oneWayFrameDelayRange) { +// this.oneWayFrameDelay = oneWayFrameDelay; +// this.oneWayFrameDelayRange = oneWayFrameDelayRange; +// } +// +// public long getOneWayFrameDelay() { return oneWayFrameDelay; } +// public void setOneWayFrameDelay(long oneWayFrameDelay) { +// this.oneWayFrameDelay = oneWayFrameDelay; } +// +// public long getOneWayFrameDelayRange() { return oneWayFrameDelayRange; } +// public void setOneWayFrameDelayRange(long oneWayFrameDelayRange) { +// this.oneWayFrameDelayRange = oneWayFrameDelayRange; } +// } +} diff --git a/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/model/EvcPerformance.java b/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/model/EvcPerformance.java new file mode 100644 index 0000000..e1bd19e --- /dev/null +++ b/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/model/EvcPerformance.java @@ -0,0 +1,102 @@ +package com.cablelabs.vcpe.evc.evcbase.model; + +import com.cablelabs.vcpe.common.Dbg; + +/** + * Created by steve on 6/9/15. + */ +public class EvcPerformance { + + private String cosId; // associated CoS + private long oneWayFrameDelay; // milliseconds + private long oneWayFrameDelayRange; // milliseconds + private long oneWayMeanFrameDelay; // milliseconds + private long oneWayInterFrameDelayVariation; // milliseconds + private double oneWayFrameLossRatio; // percentage + private double oneWayAvailability; // percentage + private long oneWayResilHighLossIntervals; //count + private long oneWayResilConsecHighLossIntervals; //count + + // zero argument constructor required for JAX-RS + public EvcPerformance() { + oneWayFrameDelay = -1; + oneWayFrameDelayRange = -1; + oneWayMeanFrameDelay = -1; + oneWayInterFrameDelayVariation = -1; + oneWayFrameLossRatio = -1.0; + oneWayAvailability = -1.0; + oneWayResilHighLossIntervals = -1; + oneWayResilConsecHighLossIntervals = -1; + } + + public void setAllProps (String cosId, long oneWayFrameDelay, long oneWayFrameDelayRange, + long oneWayMeanFrameDelay, long oneWayInterFrameDelayVariation, + double oneWayFrameLossRatio, double oneWayAvailability, + long oneWayResilHighLossIntervals, long oneWayResilConsecHighLossIntervals) + { + this.cosId = cosId; + this.oneWayFrameDelay = oneWayFrameDelay; + this.oneWayFrameDelayRange = oneWayFrameDelayRange; + this.oneWayMeanFrameDelay = oneWayMeanFrameDelay; + this.oneWayInterFrameDelayVariation = oneWayInterFrameDelayVariation; + this.oneWayFrameLossRatio = oneWayFrameLossRatio; + this.oneWayAvailability = oneWayAvailability; + this.oneWayResilHighLossIntervals = oneWayResilHighLossIntervals; + this.oneWayResilConsecHighLossIntervals = oneWayResilConsecHighLossIntervals; + } + + + // util fxns + + public void dump() { dump(0); } + public void dump(int tab) { + Dbg.p(tab, "cosId: " + this.cosId); + Dbg.p(tab, "oneWayFrameDelay: " + this.oneWayFrameDelay); + Dbg.p(tab, "oneWayFrameDelayRange: " + this.oneWayFrameDelayRange); + Dbg.p(tab, "oneWayMeanFrameDelay: " + this.oneWayMeanFrameDelay); + Dbg.p(tab, "oneWayFrameLossRatio: " + this.oneWayFrameLossRatio); + Dbg.p(tab, "oneWayAvailability: " + this.oneWayAvailability); + Dbg.p(tab, "oneWayInterFrameDelayVariation: " + this.oneWayInterFrameDelayVariation); + Dbg.p(tab, "oneWayResilHighLossIntervals: " + this.oneWayResilHighLossIntervals); + Dbg.p(tab, "oneWayResilConsecHighLossIntervals: " + this.oneWayResilConsecHighLossIntervals); + } + + // Getters and setters + + public String getCosId() { return cosId; } + public void setCosId(String cosId) { this.cosId = cosId; } + + public long getOneWayFrameDelay() { return oneWayFrameDelay; } + public void setOneWayFrameDelay(long oneWayFrameDelay) { + this.oneWayFrameDelay = oneWayFrameDelay; } + + public long getOneWayFrameDelayRange() { return oneWayFrameDelayRange; } + public void setOneWayFrameDelayRange(long oneWayFrameDelayRange) { + this.oneWayFrameDelayRange = oneWayFrameDelayRange; } + + public long getOneWayMeanFrameDelay() { return oneWayMeanFrameDelay; } + public void setOneWayMeanFrameDelay(long oneWayMeanFrameDelay) { + this.oneWayMeanFrameDelay = oneWayMeanFrameDelay; } + + public long getOneWayInterFrameDelayVariation() { return oneWayInterFrameDelayVariation; } + public void setOneWayInterFrameDelayVariation(long oneWayInterFrameDelayVariation) { + this.oneWayInterFrameDelayVariation = oneWayInterFrameDelayVariation; } + + public double getOneWayFrameLossRatio() { return oneWayFrameLossRatio; } + public void setOneWayFrameLossRatio(double oneWayFrameLossRatio) { + this.oneWayFrameLossRatio = oneWayFrameLossRatio; } + + public double getOneWayAvailability() { return oneWayAvailability; } + public void setOneWayAvailability(double oneWayAvailability) { + this.oneWayAvailability = oneWayAvailability; } + + public long getOneWayResilHighLossIntervals() { return oneWayResilHighLossIntervals; } + public void setOneWayResilHighLossIntervals(long oneWayResilHighLossIntervals) { + this.oneWayResilHighLossIntervals = oneWayResilHighLossIntervals; } + + public long getOneWayResilConsecHighLossIntervals() { return oneWayResilConsecHighLossIntervals; } + public void setOneWayResilConsecHighLossIntervals(long oneWayResilConsecHighLossIntervals) { + this.oneWayResilConsecHighLossIntervals = oneWayResilConsecHighLossIntervals; } + + +} diff --git a/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/repository/EvcRespository.java b/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/repository/EvcRespository.java new file mode 100644 index 0000000..80bebc7 --- /dev/null +++ b/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/repository/EvcRespository.java @@ -0,0 +1,21 @@ +package com.cablelabs.vcpe.evc.evcbase.repository; + +import com.cablelabs.vcpe.evc.evcbase.model.Evc; + +import java.util.List; + +/** + * Created by steve on 5/25/15. + */ +public interface EvcRespository +{ + // TODO add exceptions + + Evc add(Evc evc); // returns null if already exists, otherwise returns stored evc + Evc get(String evcId); // returns null if not found, otherwise stored evc + Evc update(Evc evc); // returns null if did not exit, otherwise evc as it was previous to update (put in any case) + Evc delete(String evcId); // returns null if not found, otherwise evc as it was previous to delete + int count(); // number of Evc stored in the repo + public void dump(int tab); // print out contents of the repo + List<Evc> getAll(); +} diff --git a/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/repository/EvcRespositoryInMem.java b/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/repository/EvcRespositoryInMem.java new file mode 100644 index 0000000..158ae3f --- /dev/null +++ b/evc/evcbase/src/main/java/com/cablelabs/vcpe/evc/evcbase/repository/EvcRespositoryInMem.java @@ -0,0 +1,91 @@ +package com.cablelabs.vcpe.evc.evcbase.repository; + +import com.cablelabs.vcpe.common.Dbg; +import com.cablelabs.vcpe.evc.evcbase.model.Evc; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Created by steve on 5/24/15. + */ + + +/* + Singleton that contains a hashmap which holds instances of Evc objects, indexed by CiS ID + */ + +public enum EvcRespositoryInMem implements EvcRespository { + INSTANCE; // Singleton + + private Map<String, Evc> evcDB = new ConcurrentHashMap<>(); + + @Override + //-------------------------------------------------------- + public Evc add(Evc evc) + //-------------------------------------------------------- + { + if ( this.get(evc.getId()) != null ) { + return null; + } + evcDB.put(evc.getId(), evc ); + return evc; + } + + @Override + //-------------------------------------------------------- + public Evc get(String evcId) { + return evcDB.get(evcId); + } + //-------------------------------------------------------- + + @Override + //-------------------------------------------------------- + public Evc update(Evc evc) + //-------------------------------------------------------- + { + // put returns null if evc did not exist, other returns evc as it stood prior to put + return evcDB.put(evc.getId(), evc); + } + + @Override + //-------------------------------------------------------- + public Evc delete(String evcId) + //-------------------------------------------------------- + { + // remove returns null if evc did not exist, other returns evc as it stood prior to remove + return evcDB.remove(evcId); + } + + @Override + //-------------------------------------------------------- + public int count() { + return evcDB.size(); + } + //-------------------------------------------------------- + + @Override + //-------------------------------------------------------- + public List<Evc> getAll() + //-------------------------------------------------------- + { + List<Evc> evcList = new ArrayList<Evc>(evcDB.values()); + return evcList; + } + + @Override + //-------------------------------------------------------- + public void dump(int tab) + //-------------------------------------------------------- + { + Dbg.p(tab, "Evc Repo: " + evcDB.size() + " entrie(s)"); + int numEvc = 0; + for (Evc curEvc : evcDB.values()) { + numEvc++; + Dbg.p(tab+1, "<Entry " + numEvc+">"); + curEvc.dump(tab+2); + } + } +} |