public ArrayPathElement(string key) : base(key) { if (key[0] != '[' || key[key.Length - 1] != ']') { throw new SpecException("Invalid ArrayPathElement key:" + key); } ArrayPathType apt; IPathReference r = null; TransposePathElement tpe = null; string aI = ""; if (key.Length == 2) { apt = ArrayPathType.AUTO_EXPAND; _canonicalForm = "[]"; } else { string meat = key.Substring(1, key.Length - 2); char firstChar = meat[0]; if (AmpReference.TOKEN == firstChar) { r = new AmpReference(meat); apt = ArrayPathType.REFERENCE; _canonicalForm = "[" + r.GetCanonicalForm() + "]"; } else if (HashReference.TOKEN == 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; }
/** * Visible for Testing. * * Inspects the key in a particular order to determine the correct sublass of * PathElement to create. * * @param origKey string that should represent a single PathElement * @return a concrete implementation of PathElement */ public static IPathElement ParseSingleKeyLHS(string origKey) { string elementKey; // the string to use to actually make Elements string keyToInspect; // the string to use to determine which kind of Element to create if (origKey.Contains("\\")) { // only do the extra work of processing for escaped chars, if there is one. keyToInspect = SpecStringParser.RemoveEscapedValues(origKey); elementKey = SpecStringParser.RemoveEscapeChars(origKey); } else { keyToInspect = origKey; elementKey = origKey; } //// LHS single values if ("@" == keyToInspect) { return(new AtPathElement(elementKey)); } else if ("*" == keyToInspect) { return(new StarAllPathElement(elementKey)); } else if (keyToInspect.StartsWith("[")) { if (StringTools.CountMatches(keyToInspect, "[") != 1 || StringTools.CountMatches(keyToInspect, "]") != 1) { throw new SpecException("Invalid key:" + origKey + " has too many [] references."); } return(new ArrayPathElement(elementKey)); } //// LHS multiple values else if (keyToInspect.StartsWith("@") || keyToInspect.Contains("@(")) { // The traspose path element gets the origKey so that it has it's escapes. return(TransposePathElement.Parse(origKey)); } else if (keyToInspect.Contains("@")) { throw new SpecException("Invalid key:" + origKey + " can not have an @ other than at the front."); } else if (keyToInspect.Contains("$")) { return(new DollarPathElement(elementKey)); } else if (keyToInspect.Contains("[")) { if (StringTools.CountMatches(keyToInspect, "[") != 1 || StringTools.CountMatches(keyToInspect, "]") != 1) { throw new SpecException("Invalid key:" + origKey + " has too many [] references."); } return(new ArrayPathElement(elementKey)); } else if (keyToInspect.Contains("&")) { if (keyToInspect.Contains("*")) { throw new SpecException("Invalid key:" + origKey + ", Can't mix * with & ) "); } return(new AmpPathElement(elementKey)); } else if (keyToInspect.Contains("*")) { int numOfStars = StringTools.CountMatches(keyToInspect, "*"); if (numOfStars == 1) { return(new StarSinglePathElement(elementKey)); } else if (numOfStars == 2) { return(new StarDoublePathElement(elementKey)); } else { return(new StarRegexPathElement(elementKey)); } } else if (keyToInspect.Contains("#")) { return(new HashPathElement(elementKey)); } else { return(new LiteralPathElement(elementKey)); } }