package de.persosim.simulator.tlv; import java.util.ArrayList; import java.util.List; /** * This class represents a path that can be used to navigate within any * {@link de.persosim.simulator.tlv.TlvDataStructure TLV data structure}. * Navigation is performed on the basis of a sequence of valid tags that are * compared to the tags of {@link de.persosim.simulator.tlv.TlvDataObject TLV * data objects} using the {@link #equals(Object) equals} method. The last tag * element of a path usually, i.e. if not explicitly stated otherwise, is * considered the one to identify the TLV data object to be the target of a * certain operation. A path always is interpreted relative to where it is used. * The object on which a method is called that is provided with a path must not * be explicitly identified by the first tag of the path. Due to the relativity * of a path, navigation results will always be different for the same path to * be used both on a child and its parent. If, when navigating through a TLV * data structure, a tag is not able to identify a TLV data object, i.e. the * path is wrong or the respective object is missing, the resulting behavior * solely is up to the processing method. * * TODO currently the path does not allow to differentiate between multiple * elements that would normally all match its description, i.e. with the same * tag. This insufficiency may be straightened out by wrapping the TLVTag in a * TLVTagIdentifier also listing the offset of occurrences of the specified tag. * This would allow to address one specific element out of several elements with * identical tags. Certain values of the occurrence index (e.g. negative values) * could be used to signal special matching handling like "any" or "last" * occurrence. * * --> Class signature may change! * * @author slutters * */ public class TlvPath extends ArrayList<TlvTagIdentifier> { /* Default serialVersionUID */ private static final long serialVersionUID = 1L; /** * Basic constructor for constructing an empty path. */ public TlvPath() { super(); } /** * Basic constructor for constructing this object from a collection representation. * @param tagList a collection representation of this object */ public TlvPath(List<TlvTagIdentifier> tagList) { super(tagList); } /** * Constructor for constructing this object from a list of {@link TlvTagIdentifier} objects. * @param tagIdentifiers a list of {@link TlvTagIdentifier} objects */ public TlvPath(TlvTagIdentifier... tagIdentifiers) { for(TlvTagIdentifier curTagIdentifier : tagIdentifiers) { this.add(curTagIdentifier); } } /** * Constructor for constructing this object from a list of {@link TlvTag} objects. * <p/> * The according {@link TlvTagIdentifier} are generated using their TlvTag-only constructor * @param tags a list of {@link TlvTag} objects */ public TlvPath(TlvTag... tlvTags) { for(int i = 0; i < tlvTags.length; i++) { this.add(new TlvTagIdentifier(tlvTags[i])); } } /*--------------------------------------------------------------------------------*/ @Override public TlvPath clone() { return new TlvPath(this); } @Override public boolean equals(Object anotherProbableTlvPath) { if(anotherProbableTlvPath == null) {return false;} if (!(anotherProbableTlvPath instanceof TlvPath)) { return false; } TlvPath anotherTlvPath = (TlvPath) anotherProbableTlvPath; if(size() != anotherTlvPath.size()) {return false;}; for(int i = 0; i < size(); i++) { if(!(this.get(i).equals(anotherTlvPath.get(i)))) {return false;} } return true; } @Override public int hashCode() { int hash = 1; for(int i = 0; i < size(); i++) { hash *= get(i).hashCode(); } return hash; } /** * This method returns the last object of the path. * If the path is empty, null will be returned. * @return the last object of the path */ public TlvTagIdentifier getLastElement() { int size = size(); if(size == 0) { return null; } else{ return get(size - 1); } } /** * Convenience method to add {@link TlvTagIdentifier} based on a {@link TlvTag} * @param tag TlvTag to be added (will be wrapped in a {@link TlvTagIdentifier}) */ public void add(TlvTag tag) { add(new TlvTagIdentifier(tag)); } }