/// <summary> /// Must be used ONLY before bot cycle started as no parent item is accepted. Usually used while feeding by input file. /// </summary> /// <param name="item_type"></param> /// <param name="field_value_pairs"></param> /// <returns></returns> static internal bool Add2QueueBeforeStart(InputItemQueue queue, Type item_type, Dictionary <string, string> field2value) { InputItem item = (InputItem)FormatterServices.GetUninitializedObject(item_type); Dictionary <string, FieldInfo> serialized_field_name2serialized_field_fis = item_types2serialized_field_names2serialized_field_fi[item_type]; foreach (string field in field2value.Keys) { try { FieldInfo fi = serialized_field_name2serialized_field_fis[field]; fi.SetValue(item, Convert.ChangeType(field2value[field], fi.FieldType)); } catch (Exception e) { throw new Exception("Field '" + field + "' does not exist.\n" + e.Message); } } ConstructorInfo ci; if (item_types2constructor_info.TryGetValue(item_type, out ci)) { ci.Invoke(item, new object[] {}); } typeof(Item).GetField("__Id", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(item, Session.This.GetNewItemId()); return(item.add2queue(queue)); }
internal bool Enqueue(InputItem item) { switch (Session.This.SourceType) { case ItemSourceType.DB: return(true); case ItemSourceType.FILE: lock (this) { string item_key = item.GetKey(); lock (item_keys) { if (item_keys.Contains(item_key)) { return(false); } item_keys.Add(item_key); } Session.This.LogInputItem(item); item_id2items.Add(item.__Id, item); if (Progress != null) { Progress.Invoke(this, CountOfProcessed + CountOfNew, CountOfProcessed); } return(true); } default: throw new Exception("Undefined SourceType: " + Session.This.SourceType.ToString()); } }
/// <summary> /// Must be used only for InputItems created by own constructor /// if InputItem was created by own constructor, its base parameters should be set /// </summary> /// <typeparam name="ItemT"></typeparam> /// <param name="parent_item"></param> /// <param name="item"></param> /// <returns></returns> static internal bool Add2Queue <ItemT>(InputItemQueue queue, InputItem parent_item, ItemT item) where ItemT : InputItem { item.set_parent_members(parent_item); item.set_tag_item_members(); typeof(Item).GetField("__Id", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(item, Session.This.GetNewItemId()); return(item.add2queue(queue)); }
virtual public void __FillStartInputItemQueue(InputItemQueue start_input_item_queue, Type start_input_item_type) { Log.Main.Write("Filling queue of " + start_input_item_queue.Name + " with input file."); if (!File.Exists(Settings.Input.File)) { throw (new Exception("Input file " + Settings.Input.File + " does not exist.")); } if (Path.GetExtension(Settings.Input.File).StartsWith(".xls", StringComparison.InvariantCultureIgnoreCase)) { throw new Exception("Reading excel is not supported"); } FileReader fr = new FileReader(Settings.Input.File, Settings.Input.FileFormat); for (FileReader.Row r = fr.ReadLine(); r != null; r = fr.ReadLine()) { InputItem.Add2QueueBeforeStart(start_input_item_queue, start_input_item_type, r.Headers.ToDictionary(x => x, x => r[x])); } if (start_input_item_queue.CountOfNew < 1) { LogMessage.Error("Input queue is empty so nothing is to do. Check your input data."); } }
static internal bool Add2Queue <ItemT>(InputItemQueue queue, InputItem parent_item, object anonymous_object) where ItemT : InputItem { ItemT item = Item.Create <ItemT>(anonymous_object); item.set_parent_members(parent_item); item.set_tag_item_members(); return(item.add2queue(queue)); }
internal void WriteInputItem(InputItem item) { if (!Settings.Engine.WriteSessionRestoringLog) { return; } if (!recorded_InputItem_ids.Contains(item.__Id)) { if (item.__State != InputItemState.NEW) { throw new Exception("InputItem has state not NEW but was not recorded."); } recorded_InputItem_ids.Add(item.__Id); Dictionary <string, TagItem> tag_item_names2tag_item = item.GetTagItemNames2TagItem(); foreach (KeyValuePair <string, TagItem> n2ti in tag_item_names2tag_item) { if (recorded_TagItem_ids.Contains(n2ti.Value.__Id)) { continue; } recorded_TagItem_ids.Add(n2ti.Value.__Id); if (!restoring) { writeElement(n2ti.Value.GetType().Name, new { id = n2ti.Value.__Id, seed = n2ti.Value.GetSeed() }); } } Dictionary <string, object> d = new Dictionary <string, object>(); d["id"] = item.__Id; d["state"] = item.__State; d["seed"] = item.GetSeed(); if (item.__Queue.Name != item.GetType().Name) { d["queue"] = item.__Queue.Name; } if (item.__ParentItem != null) { d["parent_id"] = item.__ParentItem.__Id; } foreach (KeyValuePair <string, TagItem> kv in tag_item_names2tag_item) { d["id_of_" + kv.Key] = kv.Value.__Id; } if (!restoring) { writeElement(item.GetType().Name, d); } } else if (!restoring) { writeElement(item.GetType().Name, new { id = item.__Id, state = item.__State }); } }
internal void LogInputItem(InputItem item) { if (items_xtw == null) { return; } lock (this) { try { Dictionary <string, TagItem> tag_item_name2tag_items = item.GetTagItemName2TagItems(); foreach (KeyValuePair <string, TagItem> n2ti in tag_item_name2tag_items) { if (logged_input_and_tag_item_ids.Contains(n2ti.Value.__Id)) { continue; } logged_input_and_tag_item_ids.Add(n2ti.Value.__Id); items_xtw.WriteStartElement(n2ti.Value.GetType().Name); items_xtw.WriteAttributeString("id", n2ti.Value.__Id.ToString()); items_xtw.WriteAttributeString("seed", n2ti.Value.GetSeed()); items_xtw.WriteEndElement(); } items_xtw.WriteStartElement(item.GetType().Name); items_xtw.WriteAttributeString("id", item.__Id.ToString()); items_xtw.WriteAttributeString("state", ((uint)item.__State).ToString()); if (!logged_input_and_tag_item_ids.Contains(item.__Id)) { logged_input_and_tag_item_ids.Add(item.__Id); if (item.__Queue.Name != item.GetType().Name) { items_xtw.WriteAttributeString("queue", item.__Queue.Name); } items_xtw.WriteAttributeString("seed", item.GetSeed()); if (item.__ParentItem != null) { items_xtw.WriteAttributeString("parent_id", item.__ParentItem.__Id.ToString()); } foreach (KeyValuePair <string, TagItem> kv in tag_item_name2tag_items) { items_xtw.WriteAttributeString("id_of_" + kv.Key, kv.Value.__Id.ToString()); } } //else if (item.__State == InputItemState.NEW) // throw new Exception("Logged item has state NEW"); items_xtw.WriteEndElement(); } catch (Exception e) { LogMessage.Exit(e); } items_xtw.Flush(); } }
/// <summary> /// Add item to queue. It is possible to create a named queue. /// It is the same like BotCycle.Add() but not so efficient. /// </summary> /// <param name="queue_name"></param> /// <param name="item"></param> static public bool Add(string queue_name, InputItem item) { if (queue_name == null) { queue_name = item.GetType().Name; } InputItemQueue iiq = Session.GetInputItemQueue(queue_name); return(InputItem.Add2Queue(iiq, BotCycle.GetCurrentInputItemForThisThread(), item)); }
virtual public void __Processor(InputItem item) { MethodInfo mi; if (input_item_types2processor_mi.TryGetValue(item.GetType(), out mi)) { mi.Invoke(this, new object[] { item }); } throw new Exception("No appropriate processor found for " + item.GetType()); }
/// <summary> /// Add item to queue. It is possible to create a named queue. /// Preferred method for adding items. /// </summary> /// <param name="queue_name"></param> /// <param name="item"></param> /// <returns></returns> public bool Add(string queue_name, InputItem item) { if (queue_name == null) { queue_name = item.GetType().Name; } InputItemQueue iiq = Session.GetInputItemQueue(queue_name); return(InputItem.Add2Queue(iiq, current_item, item)); }
/// <summary> /// Invoked by default if no particulare processor definition was found. /// </summary> virtual public void PROCESSOR(InputItem item) { //__input_item_type2processor_actions[item.GetType()](item); try { __input_item_type2processor_mis[item.GetType()].Invoke(this, new object[] { item }); } catch (TargetInvocationException e) { throw e.InnerException; } }
internal static InputItem Restore(InputItemQueue queue, Type item_type, string item_seed, int item_id, InputItem parent_item, Dictionary <string, TagItem> field2tag_items) { InputItem item = (InputItem)Item.Restore(item_type, item_seed, item_id); item.set_parent_members(parent_item); foreach (KeyValuePair <string, TagItem> kv in field2tag_items) { item_type.GetField(kv.Key).SetValue(item, kv.Value); } item.add2queue(queue); return(item); }
virtual public void __Processor(InputItem item) { MethodInfo mi; if (input_item_types2processor_mi.TryGetValue(item.GetType(), out mi)) { mi.Invoke(this, new object[] { item }); } else { Session.This.__Processor(item); } }
internal InputItem GetNext() { lock (input_item_queue_name2input_item_queues) { foreach (InputItemQueue iiq in input_item_queue_name2input_item_queues.Values) { InputItem ii = iiq.GetNext(); if (ii != null) { return(ii); } } return(null); } }
internal void OmitRestoredProcessedItems() { lock (this) { for (int i = item_id2items.Count - 1; i >= 0; i--) { InputItem ii = (InputItem)item_id2items[i]; if (ii.__State != InputItemState.NEW) { item_id2items.RemoveAt(i); count_of_processed_items++; } } if (Progress != null) { Progress.Invoke(this, CountOfProcessed + CountOfNew, CountOfProcessed); } } }
internal InputItem GetNext() { lock (this) { //if (current_input_item != null && current_input_item.__State == InputItemState.NEW) // throw new Exception("The previously picked up InputItem was not marked as processed"); InputItem current_input_item = PickNext(item_id2items.Values.GetEnumerator()); if (current_input_item == null) { return(null); } item_id2items.Remove(current_input_item.__Id); count_of_processed_items++; if (Progress != null) { Progress.Invoke(this, CountOfProcessed + CountOfNew, CountOfProcessed); } return(current_input_item); } }
void set_parent_members(InputItem parent_item) { //lock (item_type2parent_field_fis) //{ this.GetType().GetField("__ParentItem", BindingFlags.Instance | BindingFlags.Public).SetValue(this, parent_item); //foreach (FieldInfo fi in item_type2parent_field_fis[this.GetType()]) //{ // for (InputItem ii = __ParentItem; ii != null; ii = ii.__ParentItem) // { // if (fi.FieldType != ii.GetType()) // continue; // fi.SetValue(this, ii); // break; // } // //if (fi.GetValue(this) == null) // // throw new Exception("Field " + fi.Name + " of " + fi.FieldType + " type is not parent for " + this.GetType()); //} //} }
static public void FillStartInputItemQueue(InputItemQueue start_input_item_queue, Type start_input_item_type) { Log.Main.Write("Filling queue of " + start_input_item_queue.Name + " with input file."); if (!File.Exists(Properties.Input.Default.InputFile)) { throw (new Exception("Input file " + Properties.Input.Default.InputFile + " does not exist.")); } if (Path.GetExtension(Properties.Input.Default.InputFile).StartsWith(".xls", StringComparison.InvariantCultureIgnoreCase)) { throw new Exception("Reading excel was not implemented"); } FileReader fr = new FileReader(Properties.Input.Default.InputFile, Properties.Input.Default.InputFieldSeparator); for (FileReader.Row r = fr.ReadLine(); r != null; r = fr.ReadLine()) { InputItem.Add2QueueBeforeStart(start_input_item_queue, start_input_item_type, r.Headers.ToDictionary(x => x, x => r[x])); } }
internal InputItem GetNext() { lock (input_item_queue_name2input_item_queues) { foreach (InputItemQueue iiq in input_item_queue_name2input_item_queues.Values) { InputItem ii = iiq.GetNext(); if (ii != null) { return(ii); } } foreach (InputItemQueue iiq in input_item_queue_name2input_item_queues.Values) { if (iiq.CountOfNew > 0)//can be so if PickNext() in a queue was customized { throw new FatalException("GetNext returned nothing while " + iiq.Name + " queue has a new item."); } } return(null); } }
internal bool Enqueue(InputItem item) { lock (this) { Int64 item_key = item.GET_KEY(); lock (item_keys) { if (item_keys.Contains(item_key)) { return(false); } item_keys.Add(item_key); } item.__State = InputItemState.NEW; item_id2items.Add(item.__Id, item); if (Progress != null) { Progress.Invoke(this, CountOfProcessed + CountOfNew, CountOfProcessed); } return(true); } }
/// <summary> /// Add item as dynamic object to queue. It is possible to create a named queue. /// It is the same like BotCycle.Add() but not so efficient and safe. /// </summary> /// <param name="queue_name"></param> /// <param name="item"></param> public bool Add(InputItem item) { return(InputItem.Add2Queue(this, BotCycle.GetCurrentInputItemForThisThread(), item)); }
/// <summary> /// Add item as dynamic object to queue. By default name of queue is name of item type. /// It is the same as BotCycle.Add() but not so efficient and safe. /// </summary> /// <typeparam name="ItemT"></typeparam> /// <param name="anonymous_object"></param> /// <returns></returns> public bool Add <ItemT>(object anonymous_object) where ItemT : InputItem { return(InputItem.Add2Queue <ItemT>(this, BotCycle.GetCurrentInputItemForThisThread(), anonymous_object)); }
internal void RestoreSession() { Log.Main.Inform("Restoring session: " + This.TimeMark); restoring = true; Dictionary <int, InputItem> input_item_id2input_items = new Dictionary <int, InputItem>(); Dictionary <int, TagItem> tag_item_id2tag_items = new Dictionary <int, TagItem>(); try { startReading(); string tag; Dictionary <string, object> names2value; while (readNextElement(out tag, out names2value)) { if (tag == QueueTag) { string name = (string)names2value["name"]; int position = (int)names2value["position"]; Session.SetInputItemQueuePosition(name, position); continue; } if (tag.StartsWith("__")) { continue; } string type_name = tag; int id = (int)names2value["id"]; if (id > This.item_count) { This.item_count = id; } if (input_item_type_names2input_item_type.ContainsKey(type_name)) { InputItem parent_item = null; object o; if (names2value.TryGetValue("parent_id", out o)) { parent_item = input_item_id2input_items[(int)o]; } string queue; if (names2value.TryGetValue("queue", out o)) { queue = (string)o; } else { queue = type_name; } InputItemState state = (InputItemState)names2value["state"]; if (state == InputItemState.ERROR_RESTORE_AS_NEW && !Settings.Engine.RestoreErrorItemsAsNew) { state = InputItemState.ERROR; } switch (state) { case InputItemState.NEW: Type type = input_item_type_names2input_item_type[type_name]; Dictionary <string, TagItem> fields2tag_item = new Dictionary <string, TagItem>(); Dictionary <string, string> attr_names2tag_item_id = new Dictionary <string, string>(); foreach (string name in names2value.Keys) { Match m = Regex.Match(name, "^id_of_(?'ItemTypeName'.+)"); if (!m.Success) { continue; } fields2tag_item[m.Groups["ItemTypeName"].Value] = tag_item_id2tag_items[int.Parse(attr_names2tag_item_id[name])]; } ArrayList seed = (ArrayList)names2value["seed"]; InputItem item = InputItem.Restore(GetInputItemQueue(queue), type, seed, id, parent_item, fields2tag_item); input_item_id2input_items[id] = item; break; case InputItemState.COMPLETED: case InputItemState.ERROR: input_item_id2input_items[id].__State = state; break; default: throw new Exception("Unknown item state: " + state); } } else if (work_item_type_names2work_item_type.ContainsKey(type_name)) { string key = (string)names2value["key"]; ArrayList seed = (ArrayList)names2value["seed"]; This.GetRestoredWorkItemDictionary(work_item_type_names2work_item_type[type_name]).Restore(key, seed, id); } else if (tag_item_type_names2tag_item_type.ContainsKey(type_name)) { ArrayList seed = (ArrayList)names2value["seed"]; TagItem item = Cliver.Bot.TagItem.Restore(tag_item_type_names2tag_item_type[type_name], seed, id); tag_item_id2tag_items[item.__Id] = item; } else { throw new Exception("Unknown item type in the sesson log: " + type_name); } } } catch (Exception e) { __ErrorClose(e, true); } foreach (InputItemQueue iiq in This.input_item_queue_name2input_item_queues.Values) { iiq.OmitRestoredProcessedItems(); } restoring = false; }
/// <summary> /// Add item as dynamic object to queue. It is possible to create a named queue. /// It is the same like BotCycle.Add() but not so efficient and safe. /// </summary> /// <typeparam name="ItemT"></typeparam> /// <param name="queue_name"></param> /// <param name="anonymous_object"></param> /// <returns></returns> static public bool Add <ItemT>(string queue_name, object anonymous_object) where ItemT : InputItem { InputItemQueue iiq = Session.GetInputItemQueue(queue_name); return(InputItem.Add2Queue <ItemT>(iiq, BotCycle.GetCurrentInputItemForThisThread(), anonymous_object)); }
/// <summary> /// Restore session from the specified session file. /// </summary> /// <param name="items_xml_file">previous session file where data is to be restored from</param> void restore_session_from_xml_file(string items_xml_file) { Dictionary <int, InputItem> input_item_id2input_items = new Dictionary <int, InputItem>(); Dictionary <int, TagItem> tag_item_id2tag_items = new Dictionary <int, TagItem>(); Regex tag_item_field_filter = new Regex("^id_of_(?'ItemTypeName'.+)"); try { XmlTextReader xtr = new XmlTextReader(items_xml_file); while (xtr.Read()) { if (xtr.Name == "Items") { break; } } while (xtr.Read()) { if (xtr.NodeType != XmlNodeType.Element) { continue; } //if (xtr.Name == "__QueueOrder") //{ // string[] iiqns = xtr.ReadInnerXml().Split('\n'); // Session.SetInputItemQueuesOrder(iiqns); // continue; //} if (xtr.Name == "__Queue") { string name = xtr.GetAttribute("name"); int position = int.Parse(xtr.GetAttribute("position")); Session.SetInputItemQueuePosition(name, position); continue; } string type_name = xtr.Name; int id = int.Parse(xtr.GetAttribute("id")); string seed = xtr.GetAttribute("seed"); if (id > item_count) { item_count = id; } if (input_item_type_name2input_item_types.ContainsKey(type_name)) { InputItem parent_item = null; string parent_id = xtr.GetAttribute("parent_id"); if (parent_id != null) { parent_item = input_item_id2input_items[int.Parse(parent_id)]; } string queue = xtr.GetAttribute("queue"); if (queue == null) { queue = type_name; } InputItemState state = (InputItemState)Enum.Parse(typeof(InputItemState), xtr.GetAttribute("state"), true); if (state == InputItemState.ERROR_RESTORE_AS_NEW && !Properties.General.Default.RestoreErrorItemsAsNew) { state = InputItemState.ERROR; } switch (state) { case InputItemState.NEW: Type type = input_item_type_name2input_item_types[type_name]; Dictionary <string, string> attr_name2tag_item_id_s = xtr.GetAttributeName2AttributeValues(tag_item_field_filter); Dictionary <string, TagItem> field2tag_items = new Dictionary <string, TagItem>(); foreach (string name in attr_name2tag_item_id_s.Keys) { field2tag_items[tag_item_field_filter.Match(name).Groups["ItemTypeName"].Value] = tag_item_id2tag_items[int.Parse(attr_name2tag_item_id_s[name])]; } InputItem item = InputItem.Restore(GetInputItemQueue(queue), type, seed, id, parent_item, field2tag_items); input_item_id2input_items[id] = item; break; case InputItemState.COMPLETED: case InputItemState.ERROR: //case InputItemState.ERROR_RESTORE_AS_NEW: input_item_id2input_items[id].__State = state; break; } } else if (work_item_type_name2work_item_types.ContainsKey(type_name)) { string key = xtr.GetAttribute("key"); GetRestoredWorkItemDictionary(work_item_type_name2work_item_types[type_name]).Restore(key, seed, id); } else if (tag_item_type_name2tag_item_types.ContainsKey(type_name)) { TagItem item = Cliver.Bot.TagItem.Restore(tag_item_type_name2tag_item_types[type_name], seed, id); tag_item_id2tag_items[item.__Id] = item; } } } catch (XmlException e) { Log.Main.Warning("Session restoring: " + Log.GetExceptionMessage(e)); } catch (Exception e) { LogMessage.Error("Session restoring: " + Log.GetExceptionMessage(e)); } foreach (InputItemQueue iiq in input_item_queue_name2input_item_queues.Values) { iiq.OmitRestoredProcessedItems(); } Log.Main.Write("Items were restored from " + items_xml_file.ToString()); }
/// <summary> /// Add item as dynamic object to queue. It is possible to create a named queue. /// Preferred method for adding items. /// </summary> /// <typeparam name="ItemT"></typeparam> /// <param name="queue_name"></param> /// <param name="anonymous_object"></param> /// <returns></returns> public bool Add <ItemT>(string queue_name, object anonymous_object) where ItemT : InputItem { InputItemQueue iiq = Session.GetInputItemQueue(queue_name); return(InputItem.Add2Queue <ItemT>(iiq, current_item, anonymous_object)); }
/// <summary> /// Add item to queue. By default name of queue is name of item type. /// Preferred method for adding items. /// </summary> /// <param name="item"></param> /// <returns></returns> public bool Add(InputItem item) { return(Add(null, item)); }