///<summary> /// Extract location ParsedURL parameters into a HashMap. /// Let ParamOps operate on this Map. /// Derive a new ParsedURL using the base of the original location's ParsedURL and the transformed parameter map. /// If the new ParsedURL is different than the old one, make the old one an additional location for this, /// and add the transformed ParsedURL to the DocumentLocationMap. /// <p/> /// If the location changes, then reconnect to the new one. ///</summary> public override Object Perform(Object obj) // throws IOException { bool usingThisDoc = true; // if we are changing this document's location, or its child field's location Document document = (Document)SemanticOperationHandler.SemanticOperationVariableMap.Get(SemanticOperationKeyWords.Metadata); if (ObjectStr != null) { Object o = SemanticOperationHandler.SemanticOperationVariableMap.Get(ObjectStr); if (o != null && o is Document) { document = (Document)o; usingThisDoc = false; } } ParsedUri origLocation = document.Location.value; if (origLocation.IsFile) { Debug.WriteLine("Not doing <filter_location> because this is a file: " + origLocation); return(null); } SemanticsGlobalCollection <Document> globalCollection = SemanticOperationHandler.SemanticsScope.GlobalDocumentCollection; bool locationChanged = false; if (paramOps != null && paramOps.Count > 0) { Dictionary <String, String> parametersMap = new Dictionary <string, string>(); foreach (String param in origLocation.Query.Split('&')) { parametersMap.Add(param.Split('=')[0], param.Split('=')[1]); } if (parametersMap.Count == 0) { parametersMap = new Dictionary <string, string>(paramOps.Count); } foreach (ParamOp paramOp in paramOps) { paramOp.SemanticHandler = SemanticOperationHandler; paramOp.TransformParams(parametersMap); } String str = origLocation.AbsolutePath + "?"; foreach (KeyValuePair <string, string> pair in parametersMap) { str += pair.Key + "=" + pair.Value + "&"; } if (str[str.Length - 1] == '&') { str = str.Substring(0, str.Length - 1); } ParsedUri transformedLocation = new ParsedUri(str); if (origLocation != transformedLocation) { document.Location.Value = transformedLocation; locationChanged = true; } } if (alternativeHosts != null) { String origHost = origLocation.Host; foreach (String alternativeHost in alternativeHosts) { if (!origHost.Equals(alternativeHost)) { ParsedUri newLocation = new ParsedUri(origLocation.AbsoluteUri.Replace(origLocation.Host, alternativeHost)); document.AddAdditionalLocation(new MetadataParsedURL(newLocation)); globalCollection.AddDocument(document, newLocation); } } } if (regex != null) { ParsedUri location = document.Location.Value; ParsedUri regexURL = regex.Perform(location); document.ChangeLocation(regexURL); locationChanged = true; } if (stripPrefix != null) { String origlLocationString = origLocation.ToString(); int index = origlLocationString.IndexOf(stripPrefix); if (index > 6) { String newLocationString = origlLocationString.Substring(0, index); ParsedUri newLocation = new ParsedUri(newLocationString); if (newLocation != null) { document.ChangeLocation(newLocation); } } } if (locationChanged && usingThisDoc) // if we are just changing the location of a field, we don't have to reconnect. { if (documentParser != null) { //documentParser.reConnect(); // changed the location, so we better connect again! } else { //imageClosure.RequestMetadata(); } } return(null); }