public ArrayPathElement(String key) { super(key); if (key.charAt(0) != '[' || key.charAt(key.length() - 1) != ']') { throw new SpecException("Invalid ArrayPathElement key:" + key); } ArrayPathType apt; PathReference r = null; TransposePathElement tpe = null; String aI = ""; if (key.length() == 2) { apt = ArrayPathType.AUTO_EXPAND; canonicalForm = "[]"; } else { String meat = key.substring(1, key.length() - 1); // trim the [ ] char firstChar = meat.charAt(0); if (AmpReference.TOKEN.equals(firstChar)) { r = new AmpReference(meat); apt = ArrayPathType.REFERENCE; canonicalForm = "[" + r.getCanonicalForm() + "]"; } else if (HashReference.TOKEN.equals(firstChar)) { r = new HashReference(meat); apt = ArrayPathType.HASH; canonicalForm = "[" + r.getCanonicalForm() + "]"; } else if ('@' == firstChar) { apt = ArrayPathType.TRANSPOSE; tpe = TransposePathElement.parse(meat); canonicalForm = "[" + tpe.getCanonicalForm() + "]"; } else { aI = verifyStringIsNonNegativeInteger(meat); if (aI != null) { apt = ArrayPathType.EXPLICIT_INDEX; canonicalForm = "[" + aI + "]"; } else { throw new SpecException("Bad explict array index:" + meat + " from key:" + key); } } } transposePathElement = tpe; arrayPathType = apt; ref = r; arrayIndex = aI; }
@Override public String evaluate(WalkedPath walkedPath) { switch (arrayPathType) { case AUTO_EXPAND: return canonicalForm; case EXPLICIT_INDEX: return arrayIndex; case HASH: LiteralPathElement element = walkedPath.elementFromEnd(ref.getPathIndex()).getLiteralPathElement(); Integer index = element.getHashCount(); return index.toString(); case TRANSPOSE: String key = transposePathElement.evaluate(walkedPath); return verifyStringIsNonNegativeInteger(key); case REFERENCE: LiteralPathElement lpe = walkedPath.elementFromEnd(ref.getPathIndex()).getLiteralPathElement(); String keyPart; if (ref instanceof PathAndGroupReference) { keyPart = lpe.getSubKeyRef(((PathAndGroupReference) ref).getKeyGroup()); } else { keyPart = lpe.getSubKeyRef(0); } return verifyStringIsNonNegativeInteger(keyPart); default: throw new IllegalStateException( "ArrayPathType enum added two without updating this switch statement."); } }