private void Track(SifDataObject o) { try { if (fRefIdTracker.Contains(o.RefId)) { using ( Stream outStream = File.OpenWrite ("Duplicate " + o.RefId + "-" + o.ElementDef.Name + "-" + DateTime.Now.ToFileTime().ToString() + ".xml")) { using (TextWriter wr = new StreamWriter(outStream)) { wr.WriteLine (String.Format("Duplicate Object with Refid: {0}", o.RefId)); wr.WriteLine ("Original:" + ((SifDataObject)fRefIdTracker[o.RefId]).ToXml()); wr.WriteLine("New:" + o.ToXml()); } } } else { fRefIdTracker.Add(o.RefId, o); } } catch (Exception ex) { Console.WriteLine(ex.Message); Adk.Log.Warn(ex.Message, ex); } }
/** * Sends a SIF_Event * @param zone The zone to send the sifEvent to */ public SIF_Ack SifEvent(IZone zone, Event sifEvent, String destinationId, String sifMsgId) { if (sifEvent.Data == null || sifEvent.Data.Available == false) { throw new AdkException("The sifEvent has no SIFDataObjects", zone); } SIF_ObjectData od = new SIF_ObjectData(); // Fill out the SIF_ObjectData IDataObjectInputStream inStr = sifEvent.Data; SifDataObject data = inStr.ReadDataObject(); SifVersion msgVersion = data.EffectiveSIFVersion; SIF_EventObject eo = new SIF_EventObject(); od.SIF_EventObject = eo; eo.Action = sifEvent.ActionString; eo.ObjectName = data.ElementDef.Tag(msgVersion); // Create the SIF_Event object SIF_Event msg = new SIF_Event(msgVersion); msg.SIF_ObjectData = od; SIF_Header msgHdr = msg.Header; // Assign SIF_DestinationId if applicable if (destinationId != null) { msgHdr.SIF_DestinationId = destinationId; } while (data != null) { eo.Attach(data); data = inStr.ReadDataObject(); } if (sifMsgId != null) { msgHdr.SIF_MsgId = sifMsgId; } SifContext[] contexts = sifEvent.Contexts; if (contexts == null) { contexts = new SifContext[] { SifContext.DEFAULT }; } SIF_Contexts msgContexts = new SIF_Contexts(); foreach (SifContext context in contexts) { msgContexts.AddSIF_Context(context.Name); } msgHdr.SIF_Contexts = msgContexts; return(((ZoneImpl)zone).Dispatcher.send(msg)); }
public void testComplexAndQuery() { String sifQuery = "<SIF_Request><SIF_Query>" + " <SIF_QueryObject ObjectName=\"StudentSchoolEnrollment\"/>" + " <SIF_ConditionGroup Type=\"None\">" + " <SIF_Conditions Type=\"And\">" + " <SIF_Condition>" + " <SIF_Element>@MembershipType</SIF_Element>" + " <SIF_Operator>EQ</SIF_Operator>" + " <SIF_Value>Home</SIF_Value>" + " </SIF_Condition>" + " <SIF_Condition>" + " <SIF_Element>@RefId</SIF_Element>" + " <SIF_Operator>EQ</SIF_Operator>" + " <SIF_Value>49B02D134D6D445DA7B5C76160BF3902</SIF_Value>" + " </SIF_Condition>" + " <SIF_Condition>" + " <SIF_Element>@SchoolInfoRefId</SIF_Element>" + " <SIF_Operator>EQ</SIF_Operator>" + " <SIF_Value>EF8850D522E54688B036B08F9C4C1312</SIF_Value>" + " </SIF_Condition>" + " <SIF_Condition>" + " <SIF_Element>@SchoolYear</SIF_Element>" + " <SIF_Operator>EQ</SIF_Operator>" + " <SIF_Value>2006</SIF_Value>" + " </SIF_Condition>" + " <SIF_Condition>" + " <SIF_Element>@StudentPersonalRefId</SIF_Element>" + " <SIF_Operator>EQ</SIF_Operator>" + " <SIF_Value>1AA295D3BC5146FA9058BB62FB6CC602</SIF_Value>" + " </SIF_Condition>" + " <SIF_Condition>" + " <SIF_Element>@TimeFrame</SIF_Element>" + " <SIF_Operator>EQ</SIF_Operator>" + " <SIF_Value>Historical</SIF_Value>" + " </SIF_Condition>" + " <SIF_Condition>" + " <SIF_Element>EntryDate</SIF_Element>" + " <SIF_Operator>EQ</SIF_Operator>" + " <SIF_Value>2005-08-28</SIF_Value>" + " </SIF_Condition>" + " </SIF_Conditions>" + " </SIF_ConditionGroup>" + " </SIF_Query></SIF_Request>"; SifParser parser = SifParser.NewInstance(); SIF_Request sifR = (SIF_Request)parser.Parse(sifQuery, null, 0, SifVersion.LATEST); Query query = new Query(sifR.SIF_Query); String sse = "<StudentSchoolEnrollment RefId=\"49B02D134D6D445DA7B5C76160BF3902\" StudentPersonalRefId=\"1AA295D3BC5146FA9058BB62FB6CC602\" SchoolInfoRefId=\"EF8850D522E54688B036B08F9C4C1312\" MembershipType=\"Home\" TimeFrame=\"Historical\" SchoolYear=\"2006\">" + "<EntryDate>2005-08-28</EntryDate>" + "</StudentSchoolEnrollment>"; SifDataObject sdo = (SifDataObject)parser.Parse(sse, null, 0, SifVersion.SIF20r1); Assert.IsTrue(query.Evaluate(sdo)); }
public static SifDataObject runParsingTest(SifDataObject o) { SifDataObject o2 = WriteParseAndReturn(o, Adk.SifVersion); Assert.IsNotNull(o2, "Object is null after parsing"); runAssertions(o, o2); return(o2); }
public static SifDataObject runParsingTest( SifDataObject o ) { SifDataObject o2 = WriteParseAndReturn( o, Adk.SifVersion ); Assert.IsNotNull( o2, "Object is null after parsing" ); runAssertions( o, o2 ); return o2; }
private static void runAssertions( SifDataObject originalObject, SifDataObject reparsedObject ) { // run additional assertions by overriding this method // Compare the objects Element[][] diffs = originalObject.CompareGraphTo( reparsedObject ); if (diffs[0].Length == 0) Console.WriteLine( "\r\n*** Objects are identical ***\r\n" ); else { bool isChanged = false; // Display differences in two columns Console.WriteLine(); Console.WriteLine( pad( "Original Object" ) + " " + pad( "Reparsed Object" ) ); Console.WriteLine( underline( 50 ) + " " + underline( 50 ) ); StringBuilder str = new StringBuilder(); for (int i = 0; i < diffs[0].Length; i++) { str.Length = 0; str.Append( pad( (diffs[0][i] == null ? "" : diffs[0][i].ElementDef.GetSQPPath( Adk.SifVersion ) + " ('") + (diffs[0][i] == null ? "" : diffs[0][i].TextValue + "')") ) ); str.Append( ' ' ); str.Append( pad( ( diffs[1][i] == null ? "" : diffs[1][i].ElementDef.GetSQPPath( Adk.SifVersion ) + " ('") + (diffs[1][i] == null ? "" : diffs[1][i].TextValue + "')") ) ); Console.WriteLine( str.ToString() ); // The Element.compareGraphTo() method either has a bug, or else // the behavior is supposed to be this // way. ( Eric, please verify ). We only want to fail if the two // fields are entirely different. String s1 = diffs[0][i] == null ? "" : diffs[0][i].TextValue; s1 = s1 == null ? "" : s1; String s2 = diffs[1][i] == null ? "" : diffs[1][i].TextValue; s2 = s2 == null ? "" : s2; if (!s1.Equals( s2 )) { isChanged = true; } } if (isChanged) { Assert.Fail( " Original and reparsed object differ, see System.Out for details " ); } } }
private static void runAssertions(SifDataObject originalObject, SifDataObject reparsedObject) { // run additional assertions by overriding this method // Compare the objects Element[][] diffs = originalObject.CompareGraphTo(reparsedObject); if (diffs[0].Length == 0) { Console.WriteLine("\r\n*** Objects are identical ***\r\n"); } else { bool isChanged = false; // Display differences in two columns Console.WriteLine(); Console.WriteLine(pad("Original Object") + " " + pad("Reparsed Object")); Console.WriteLine(underline(50) + " " + underline(50)); StringBuilder str = new StringBuilder(); for (int i = 0; i < diffs[0].Length; i++) { str.Length = 0; str.Append(pad((diffs[0][i] == null ? "" : diffs[0][i].ElementDef.GetSQPPath(Adk.SifVersion) + " ('") + (diffs[0][i] == null ? "" : diffs[0][i].TextValue + "')"))); str.Append(' '); str.Append(pad(( diffs[1][i] == null ? "" : diffs[1][i].ElementDef.GetSQPPath(Adk.SifVersion) + " ('") + (diffs[1][i] == null ? "" : diffs[1][i].TextValue + "')"))); Console.WriteLine(str.ToString()); // The Element.compareGraphTo() method either has a bug, or else // the behavior is supposed to be this // way. ( Eric, please verify ). We only want to fail if the two // fields are entirely different. String s1 = diffs[0][i] == null ? "" : diffs[0][i].TextValue; s1 = s1 == null ? "" : s1; String s2 = diffs[1][i] == null ? "" : diffs[1][i].TextValue; s2 = s2 == null ? "" : s2; if (!s1.Equals(s2)) { isChanged = true; } } if (isChanged) { Assert.Fail(" Original and reparsed object differ, see System.Out for details "); } } }
private SifDataObject createPerson(string id, string lastName, string firstName, string number, string street, string locality, string town, string post, string phone, string gender, string grade, EthnicityCodes ethnicity, string birthDateyyyyMMdd) { SifDataObject person = createPersonObject(id); person.SetElementOrAttribute("@RefId", Adk.MakeGuid()); Name name = new Name(NameType.CURRENT_LEGAL, firstName, lastName); PersonalInformation personal = new PersonalInformation(name); person.AddChild(CommonDTD.PERSONALINFORMATION, personal); AddressableObjectName aon = new AddressableObjectName(); aon.StartNumber = number; Address address = new Address(AddressType.CURRENT, aon); address.Street = street; address.Locality = locality; address.Town = town; address.PostCode = post; address.SetCountry(CountryCode.GBR); personal.Address = address; personal.PhoneNumber = new PhoneNumber(PhoneType.HOME, phone); Demographics dem = new Demographics(); dem.SetEthnicityList(new Ethnicity(ethnicity)); dem.SetGender(Gender.Wrap(gender)); try { dem.BirthDate = SifDate.ParseSifDateString(birthDateyyyyMMdd, SifVersion.SIF15r1); } catch (Exception pex) { Console.WriteLine(pex); } personal.Demographics = dem; return(person); }
public static void RunSDOParsingTest( String fileName, SifVersion version, Boolean runAssertions ) { // Parse the object from the file Console.WriteLine( "Parsing from file..." + fileName ); SifParser p = SifParser.NewInstance(); StreamReader reader = new StreamReader( fileName ); SifDataObject sdo = (SifDataObject) p.Parse( reader, null ); reader.Close(); Assert.IsNull( sdo ); runParsingTest<SifDataObject>( sdo, version ); }
public static SifDataObject WriteParseAndReturn(SifDataObject o, SifVersion version) { SifDataObject returnVal = null; try { // Write the object to System.out Console.WriteLine("Writing object : " + o.ObjectTag + " using SifVersion: " + version.ToString()); SifWriter echo = new SifWriter(Console.Out); echo.Write(o, version); o.SetChanged(false); echo.Write(o); // Write the object to a file Console.WriteLine("Writing to file..."); using (Stream fos = File.Open("test.xml", FileMode.Create, FileAccess.Write)) { SifWriter writer = new SifWriter(fos); o.SetChanged(true); writer.Write(o, version); writer.Flush(); fos.Close(); } // Parse the object from the file Console.WriteLine("Parsing from file..."); SifParser p = SifParser.NewInstance(); using (Stream fis = File.OpenRead("test.xml")) { returnVal = (SifDataObject)p.Parse(fis, null); } // Write the parsed object to System.out returnVal.SetChanged(true); Console.WriteLine("Read object : " + returnVal.ObjectTag); echo.Write(returnVal, version); } catch (Exception e) { Console.WriteLine(e); Assert.Fail("Exception: " + e.Message); } return(returnVal); }
private void ParseSingleSDOObjectFromFile(string fileName) { // Parse the object from the file Console.WriteLine("Parsing from file..."); SifParser p = SifParser.NewInstance(); SifDataObject sifObject = null; using (Stream inStream = GetResourceStream(fileName)) { sifObject = (SifDataObject)p.Parse(inStream, null, SifParserFlags.None, SifVersion.SIF15r1); inStream.Close(); } Assert.IsNotNull(sifObject); AdkObjectParseHelper.runParsingTest(sifObject, SifVersion.SIF15r1); }
public static SifDataObject WriteParseAndReturn( SifDataObject o, SifVersion version ) { SifDataObject returnVal = null; try { // Write the object to System.out Console.WriteLine( "Writing object : " + o.ObjectTag + " using SifVersion: " + version.ToString() ); SifWriter echo = new SifWriter( Console.Out ); echo.Write( o, version ); o.SetChanged( false ); echo.Write( o ); // Write the object to a file Console.WriteLine( "Writing to file..." ); using(Stream fos = File.Open( "test.xml", FileMode.Create, FileAccess.Write ) ) { SifWriter writer = new SifWriter( fos ); o.SetChanged( true ); writer.Write( o, version ); writer.Flush(); fos.Close(); } // Parse the object from the file Console.WriteLine( "Parsing from file..." ); SifParser p = SifParser.NewInstance(); using( Stream fis = File.OpenRead( "test.xml")) { returnVal = (SifDataObject) p.Parse( fis, null ); } // Write the parsed object to System.out returnVal.SetChanged( true ); Console.WriteLine( "Read object : " + returnVal.ObjectTag ); echo.Write( returnVal, version ); } catch (Exception e) { Console.WriteLine( e ); Assert.Fail( "Exception: " + e.Message ); } return returnVal; }
public void run() { /** * This class periodically publishes change events to the zone. This * method starts up the thread that publishes the change events. * * A normal SIF Agent would, instead look for changes in the application's database * and publish those as changes. */ Console.WriteLine ("Event publishing enabled with an interval of " + EVENT_INTERVAL / 1000 + " seconds."); Random random = new Random(); bool isProcessing = true; // Go into a loop and send events while (isProcessing) { try { Thread.Sleep(EVENT_INTERVAL); SifDataObject changedObject = fData[random.Next(fData.Count)]; SifDataObject eventObject = Adk.Dtd.CreateSIFDataObject(getElementDef()); eventObject.SetElementOrAttribute ("@PersonRefId", changedObject.GetElementOrAttribute("@PersonRefId"). TextValue); // Create a change event with a random Learner ID; string newNum = "A" + random.Next(999999); eventObject.SetElementOrAttribute("LocalId", newNum); fZone.ReportEvent(eventObject, EventAction.Change); } catch (Exception ex) { Console.WriteLine("Error during event processing: " + ex); isProcessing = false; } } }
protected void doOutboundMapping(IFieldAdaptor adaptor, SifDataObject sdo, String cfg, IValueBuilder vb) { AgentConfig config = createConfig(cfg); Mappings root = config.Mappings; Mappings defMap = root.GetMappings("Default"); if (vb != null) { defMap.MapOutbound(adaptor, sdo, vb); } else { defMap.MapOutbound(adaptor, sdo); } Console.WriteLine(sdo.ToXml()); }
/// <summary> /// Writes the object to the outgoing data stream /// </summary> /// <param name="data"></param> /// <param name="buffer"></param> /// <param name="version"></param> /// <param name="fieldRestrictions"></param> protected virtual void WriteObject(SifDataObject data, Stream buffer, SifVersion version, IElementDef[] fieldRestrictions) { SifWriter writer = new SifWriter(buffer); writer.SuppressNamespace(true); if (fQuery != null) { fQuery.SetRenderingRestrictionsTo(data); } else if (fQueryRestrictions != null) { writer.Filter = fQueryRestrictions; } writer.Write(data, version); writer.Flush(); }
/// <summary> Evaluates this rule against a SifDataObject and returns the text value /// of the <c><OtherId></c> element that satisfied the query. If /// the OtherIdMapping passed to the constructor included a <i>prefix</i> /// attribute, the returned value will exclude the prefix string. /// /// </summary> /// <param name="data">The SifDataObject the rule is evaluated against /// </param> /// <returns> The value of the <c><OtherId></c> element that /// satisfied the query (excluding the prefix string if applicable), or /// null if no match found /// </returns> /// <param name="version">The SIFVersion to use while evaluating the data object</param> private SifSimpleType Evaluate(SifDataObject data, SifVersion version) { if (data != null) { // // Search all of the OtherId children for one that matches the type // and optionally the prefix specified by the fMapping // ICollection otherIdList = (ICollection)data.GetChild("OtherIdList"); if (otherIdList != null) { foreach (SifElement otherId in otherIdList) { // Compare the Type attribute SimpleField typ = otherId.GetField("Type"); if (typ == null || !typ.TextValue.Equals(fMapping.Type)) { continue; } // Optionally compare the prefix and if its a match return // all text after the prefix string String prefix = fMapping.Prefix; if (prefix != null) { String val = otherId.TextValue; if (val != null && val.StartsWith(prefix)) { return(new SifString(val.Substring(prefix.Length))); } } else { return(otherId.SifValue); } } } } return(null); }
/// <summary> Produce a table of field values from a SIF Data Object. /// /// This <c>map</c> method populates the supplied IDictionary with element /// or attribute values from the SifDataObject by evaluating all field rules /// defined by this Mappings object for the associated SIF Data Object type. /// Field rules are only evaluated if no entry currently exists in the /// IDictionary. Consequently, the caller may pre-load the IDictionary with known /// field values if possible and they will not be overridden by the mapping /// process. /// /// /// This method is intended to obtain element and attribute values from a /// SifDataObject <i>consumed</i> by the agent when processing SIF /// Events or SIF Responses. In contrast, the other form of the <c>map</c> /// method is intended to populate a new SifDataObject instance when an /// agent is <i>publishing</i> objects to a zone. /// /// /// To use this method, /// /// <ol> /// <item><term> /// Create a IDictionary and optionally populate it with known field /// values that will not be subject to the mapping process. If pre-loading /// the IDictionary, the key of each entry should be the local /// application-defined field name and the value should be the string /// value of that field. Any field added to the IDictionary before calling /// this method will not be subject to mapping rules. /// </term></item> /// <item><term> /// Call this <c>map</c> method, passing the SifDataObject /// instance to retrieve field values from for insertion into the /// IDictionary. The method first looks up the ObjectMapping instance /// corresponding to the SIF Data Object type. If no ObjectMapping /// has been defined for the object type, no action is taken and the /// method returns successfully without exception. Otherwise, all /// field rules defined by the ObjectMapping are evaluated in order. /// If a rule evaluates successfully, the corresponding element or /// attribute value will be inserted into the IDictionary. A rule will /// not be evaluated if the associated field already exists in the /// IDictionary. /// </term></item> /// </ol> /// /// </summary> /// <param name="dataObject">The SifDataObject from which to retrieve element and /// attribute values from when performing the mapping operation. /// /// </param> /// <param name="results">A IDictionary to receive the results of the mapping, where /// each entry in the map is keyed by the local application-defined name /// of a field and the value is the text value of the corresponding /// element or attribute in the SifDataObject. /// /// </param> /// <exception cref="AdkMappingException"> thrown if an error occurs while evaluating /// a field rule /// </exception> public void MapInbound(SifDataObject dataObject, IFieldAdaptor results) { MapInbound(dataObject, results, Adk.SifVersion); }
/// <summary>Detach a SifMessagePayload from this EventObject.<p></summary> public virtual void Detach(SifDataObject payload) { RemoveChild(payload); }
public void OnQueryResults(IDataObjectInputStream data, SIF_Error error, IZone zone, IMessageInfo info) { SifMessageInfo smi = (SifMessageInfo)info; DateTime start = DateTime.Now; if (smi.Timestamp.HasValue) { start = smi.Timestamp.Value; } Console.WriteLine(); Console.WriteLine("********************************************* "); Console.WriteLine("Received SIF_Response packet from zone" + zone.ZoneId); Console.WriteLine("Details... "); Console.WriteLine("Request MsgId: " + smi.SIFRequestMsgId); Console.WriteLine("Packet Number: " + smi.PacketNumber); Console.WriteLine(); if (error != null) { Console.WriteLine("The publisher returned an error: "); Console.WriteLine("Category: " + error.SIF_Category + " Code: " + error.SIF_Code); Console.WriteLine("Description " + error.SIF_Desc); if (error.SIF_ExtendedDesc != null) { Console.WriteLine("Details: " + error.SIF_ExtendedDesc); } return; } try { int objectCount = 0; while (data.Available) { SifDataObject next = data.ReadDataObject(); objectCount++; Console.WriteLine(); Console.WriteLine("Text Values for " + next.ElementDef.Name + " " + objectCount + " {" + next.Key + "}"); SifXPathContext context = SifXPathContext.NewSIFContext(next); // Print out all attributes Console.WriteLine("Attributes:"); XPathNodeIterator textNodes = context.Select("//@*"); while (textNodes.MoveNext()) { XPathNavigator navigator = textNodes.Current; Element value = (Element)navigator.UnderlyingObject; IElementDef valueDef = value.ElementDef; Console.WriteLine(valueDef.Parent.Tag(SifVersion.LATEST) + "/@" + valueDef.Tag(SifVersion.LATEST) + "=" + value.TextValue + ", "); } Console.WriteLine(); // Print out all elements that have a text value Console.WriteLine("Element:"); textNodes = context.Select("//*"); while (textNodes.MoveNext()) { XPathNavigator navigator = textNodes.Current; Element value = (Element)navigator.UnderlyingObject; String textValue = value.TextValue; if (textValue != null) { IElementDef valueDef = value.ElementDef; Console.WriteLine(valueDef.Tag(SifVersion.LATEST) + "=" + textValue + ", "); } } } Console.WriteLine(); Console.WriteLine("Total Objects in Packet: " + objectCount); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); } if (!smi.MorePackets) { // This is the final packet. Print stats Console.WriteLine("Final Packet has been received."); IRequestInfo ri = smi.SIFRequestInfo; if (ri != null) { Console.WriteLine("Source Query: "); Console.WriteLine(ri.UserData); TimeSpan difference = start.Subtract(ri.RequestTime); Console.WriteLine("Query execution time: " + difference.Milliseconds + " ms"); } } else { Console.WriteLine("This is not the final packet for this SIF_Response"); } Console.WriteLine("********************************************* "); Console.WriteLine( ); PrintPrompt(); }
public void testSchoolInfo010() { String schoolInfoResp = " <SIF_Message xmlns=\"http://www.sifinfo.org/infrastructure/1.x\" Version=\"1.5r1\">" + " <SIF_Response>" + " <SIF_Header>" + " <SIF_MsgId>B329CA6E5BC342339F135880CEE0578E</SIF_MsgId>" + " <SIF_Date>20070813</SIF_Date>" + " <SIF_Time Zone=\"UTC-06:00\">13:55:57</SIF_Time>" + " <SIF_Security>" + " <SIF_SecureChannel>" + " <SIF_AuthenticationLevel>0</SIF_AuthenticationLevel>" + " <SIF_EncryptionLevel>0</SIF_EncryptionLevel>" + " </SIF_SecureChannel>" + " </SIF_Security>" + " <SIF_SourceId>SASIxp</SIF_SourceId>" + " <SIF_DestinationId>Destiny</SIF_DestinationId>" + " </SIF_Header>" + " <SIF_RequestMsgId>88BE30BA0B8746809598854A1F58C8CC</SIF_RequestMsgId>" + " <SIF_PacketNumber>1</SIF_PacketNumber>" + " <SIF_MorePackets>No</SIF_MorePackets>" + " <SIF_ObjectData>" + " <SchoolInfo RefId=\"B3E73AC5E8C7392044015E25A454AC6F\">" + " <LocalId>997</LocalId>" + " <SchoolName>Junior High Demo</SchoolName>" + " <PrincipalInfo>" + " <ContactName>Mrs. Pleasant</ContactName>" + " </PrincipalInfo>\r\n" + /* " <PhoneNumber Format=\"NA\" Type=\"TE\">(949) 888-7655</PhoneNumber>" + */ " <PhoneNumber Format=\"NA\" Type=\"FE\">888-9877</PhoneNumber>\r\n" + " <Address Type=\"SS\">" + " <Street>" + " <Line1>Grand Avenue</Line1>" + " </Street>" + " <City>Plesantville</City>" + " <StatePr Code=\"CA\" />" + " <Country Code=\"US\" />" + " <PostalCode>12345</PostalCode>" + " </Address>" + " <IdentificationInfo Code=\"76\">997</IdentificationInfo>" + " </SchoolInfo>" + " </SIF_ObjectData>" + " </SIF_Response>" + " </SIF_Message>"; SifParser parser = SifParser.NewInstance(); SifMessagePayload smi = (SifMessagePayload)parser.Parse( schoolInfoResp, null); // Verify that it is parsing the correct version Assertion.AssertEquals("Version", SifVersion.SIF15r1, smi.SifVersion); Assertion.AssertEquals("Version attribute", "1.5r1", smi.VersionAttribute); SifDataObject sdo = (SifDataObject)((SIF_Response)smi) .SIF_ObjectData.GetChildList()[0]; // Now attempt an inbound mapping IDictionary fields = new ListDictionary(); StringMapAdaptor sma = new StringMapAdaptor(fields); Mappings m = fCfg.Mappings.GetMappings("Default").Select("asdf", "SASIxp", smi.SifVersion); m.MapInbound(sdo, sma, smi.SifVersion); Assertion.Assert("Elements Mapped", fields.Count > 0); Assertion.AssertEquals("Phone Number", "888-9877", fields["FAX"]); }
// BEGIN EXTRA METHODS (C:/GitHub/rafidzal/OpenADK-java/adk-generator/../adk-generator/datadef/core/sif20/SIF_EventObject.txt.cs) /// <summary>Attach a SifMessagePayload to this EventObject.<p></summary> public virtual void Attach(SifDataObject payload) { AddChild(payload); }
/// <summary> Find an SifElement given an XPath-like query string.</summary> /// <remarks> /// <para> /// Query strings can only take one of these forms: /// </para> /// <list type="bullet"> /// <item><term><c>@Attr</c></term></item> /// <item><term><c>Element</c></term></item> /// <item><term><c>Element/@Attr</c></term></item> /// <item><term><c>Element/Element/.../@Attr</c></term></item> /// <item><term><c>Element[@Attr='value1']</c></term></item> /// <item><term><c>Element[@Attr1='value1',@Attr2='value2',...]/Element/...</c></term></item> /// </list> /// /// <para> /// When the <i>create</i> parameter is true, the method will ensure that /// the elements and attributes specified in the query string are created in /// the SifDataObject. All values are evaluated by the ValueBuilder implementation /// passed to this method. In addition, the query string may end with a value /// expression in the form "<c>Element[@Attribute='val']=<b><i>expression</i></b></c>", /// where <i>expression</i> is evaluated by the <c>ValueBuilder</c>. /// Refer to the <c>DefaultValueBuilder</c> class for a description of /// how value expressions are evaluated by in XPath query strings by default. /// </para> /// <para> /// Note that when <i>create</i> is true, this method will attempt to create /// a new element when a set of attributes is specified and an element does /// not already exist with those same attribute settings. This is not always /// desirable, however. For example, if you call this method in succession /// with the following XPath query strings, the result will be a single /// <c>OtherId[@Type='ZZ']</c> element with a value of "$(School)". /// This is because each call will match the <c>OtherId[@Type='ZZ']</c> /// element created by the first call, and will replace its value instead of /// creating an new instance of the <c>OtherId</c> element: /// </para> /// /// <para> /// <code> /// OtherId[@Type='ZZ']=GRADE:$(Grade) /// OtherId[@Type='ZZ']=HOMEROOM:$(HomeRoom) /// OtherId[@Type='ZZ']=SCHOOL:$(School) /// </code> /// </para> /// /// <para> /// Produces: /// </para> /// <para> /// <c><OtherId Type='ZZ'>SCHOOL:$(School)</OtherId></c> /// </para> /// <para> /// To instruct the function to always create a new instance of an element /// even when a matching element is found, append the attribute list with a /// plus sign. The plus sign must come immediately before the closing right /// backet regardless of how many attributes are specified in the attribute /// list: /// </para> /// <para> /// <code> /// OtherId[@Type='ZZ'+]=GRADE:$(Grade) /// OtherId[@Type='ZZ'+]=HOMEROOM:$(HomeRoom) /// OtherId[@Type='ZZ'+]=SCHOOL:$(School) /// </code> /// </para> /// <para> /// Produces: /// </para> /// <para> /// <code> /// <OtherId Type='ZZ'>GRADE:$(Grade)</OtherId> /// <OtherId Type='ZZ'>HOMEROOM:$(HomeRoom)</OtherId> /// <OtherId Type='ZZ'>SCHOOL:$(School)</OtherId> /// </code> /// </para> /// </remarks> /// <param name="relativeTo">A SifDataObject to which the query is relative to.</param> /// <param name="query">An XPath-like query string as described above.</param> /// <returns> The Element satisfying the query, or <c>null</c> if no /// match was found (unless the <i>create</i> parameter is true). If the /// query resolves to an attribute, a SimpleField object is returned. If /// it resolves to an element, a SifElement object is returned. In both /// cases the caller can obtain the text value of the attribute or /// element by calling its <c>TextValue</c> property. /// </returns> /// <param name="valueBuilder"></param> public Element LookupByXPath(SifDataObject relativeTo, string query, IValueBuilder valueBuilder) { int i = query.IndexOf('/'); Element result = _xpath(relativeTo, query.Substring(0, (i == -1 ? query.Length : i) - (0)), i == -1 ? null : query.Substring(i + 1)); return result; }
/// <summary> /// Writes the object to the outgoing data stream /// </summary> /// <param name="data"></param> /// <param name="buffer"></param> /// <param name="version"></param> /// <param name="fieldRestrictions"></param> protected virtual void WriteObject( SifDataObject data, Stream buffer, SifVersion version, IElementDef[] fieldRestrictions ) { SifWriter writer = new SifWriter( buffer ); writer.SuppressNamespace( true ); if ( fQuery != null ) { fQuery.SetRenderingRestrictionsTo( data ); } else if ( fQueryRestrictions != null ) { writer.Filter = fQueryRestrictions; } writer.Write( data, version ); writer.Flush(); }
/// <summary> Find an SifElement given an XPath-like query string.</summary> /// <remarks> /// Query strings can only take one of these forms: /// /// <list type="bullet"> /// <item><term><c>@Attr</c></term></item> /// <item><term><c>Element</c></term></item> /// <item><term><c>Element/@Attr</c></term></item> /// <item><term><c>Element/Element/.../@Attr</c></term></item> /// <item><term><c>Element[@Attr='value1']</c></term></item> /// <item><term><c>Element[@Attr1='value1',@Attr2='value2',...]/Element/...</c></term></item> /// </list> /// /// </remarks> /// <param name="relativeTo">A SifDataObject to which the query is relative to. /// </param> /// <param name="query">An XPath-like query string as described above /// /// </param> /// <returns> The Element satisfying the query, or <c>null</c> if no /// match was found. If the query resolves to an attribute, a SimpleField /// object is returned. If the query resolves to an element, a SifElement /// object is returned. In both cases the caller can obtain the text /// value of the attribute or element by calling its <c>TextValue</c> /// property. /// </returns> public Element LookupByXPath(SifDataObject relativeTo, string query) { return LookupByXPath(relativeTo, query, null); }
public void testSifResponseSender010() { string queryStr = @"<SIF_Query> <SIF_QueryObject ObjectName='SectionInfo'> <SIF_Element>@RefId</SIF_Element> <SIF_Element>@SchoolCourseInfoRefId</SIF_Element> <SIF_Element>@SchoolYear</SIF_Element> <SIF_Element>LocalId</SIF_Element> <SIF_Element>ScheduleInfoList/ScheduleInfo/@TermInfoRefId</SIF_Element> <SIF_Element>Description</SIF_Element> <SIF_Element>LanguageOfInstruction</SIF_Element> <SIF_Element>LanguageOfInstruction/Code</SIF_Element> </SIF_QueryObject> </SIF_Query>"; string sectionInfoStr = @"<SectionInfo RefId='D9C9889878144863B190C7D3428D7953' SchoolCourseInfoRefId='587F89D23EDD4761A59C04BA0D39E8D9' SchoolYear='2008'> <LocalId>1</LocalId> <Description>section 19</Description> <ScheduleInfoList> <ScheduleInfo TermInfoRefId='0D8165B1ADB34780BD1DFF9E38A7B935'> <TeacherList> <StaffPersonalRefId>F9D3916707634682B84C530BCF96B5CA</StaffPersonalRefId> </TeacherList> <SectionRoomList> <RoomInfoRefId>EED167D761CD493EA94A875F56ABB0CB</RoomInfoRefId> </SectionRoomList> <MeetingTimeList> <MeetingTime> <TimetableDay>R</TimetableDay> <TimetablePeriod>6</TimetablePeriod> </MeetingTime> <MeetingTime> <TimetableDay>F</TimetableDay> <TimetablePeriod>6</TimetablePeriod> </MeetingTime> <MeetingTime> <TimetableDay>W</TimetableDay> <TimetablePeriod>6</TimetablePeriod> </MeetingTime> <MeetingTime> <TimetableDay>M</TimetableDay> <TimetablePeriod>6</TimetablePeriod> </MeetingTime> <MeetingTime> <TimetableDay>T</TimetableDay> <TimetablePeriod>6</TimetablePeriod> </MeetingTime> </MeetingTimeList> </ScheduleInfo> </ScheduleInfoList> <MediumOfInstruction><Code>0605</Code></MediumOfInstruction> <LanguageOfInstruction><Code>eng</Code></LanguageOfInstruction> <SummerSchool>No</SummerSchool> </SectionInfo>"; SifParser parser = SifParser.NewInstance(); SIF_Query sifquery = (SIF_Query)parser.Parse(queryStr); SectionInfo section = (SectionInfo)parser.Parse(sectionInfoStr); Query query = new Query(sifquery); String SifRequestMsgId = Adk.MakeGuid(); String sourceId = "TEST_SOURCEID"; SifVersion testVersion = SifVersion.LATEST; int maxBufferSize = int.MaxValue; MessageDispatcher testDispatcher = new MessageDispatcher(Zone); Zone.SetDispatcher(testDispatcher); Zone.Connect(ProvisioningFlags.None); InMemoryProtocolHandler testProto = (InMemoryProtocolHandler)Zone.ProtocolHandler; testProto.clear(); SifResponseSender srs = new SifResponseSender(); srs.Open(Zone, SifRequestMsgId, sourceId, testVersion, maxBufferSize, query); srs.Write(section); srs.Close(); // Retrieve the SIF_Response message off the protocol handler and asssert the results SIF_Response response = (SIF_Response)testProto.readMsg(); Assert.AreEqual(SifRequestMsgId, response.SIF_RequestMsgId); Assert.AreEqual(1, response.SIF_PacketNumber.Value); Assert.AreEqual("No", response.SIF_MorePackets); SIF_Header header = response.SIF_Header; Assert.AreEqual(sourceId, header.SIF_DestinationId); SifDataObject responseObject = (SifDataObject)response.SIF_ObjectData.GetChildList()[0]; Assert.IsNotNull(responseObject); Console.Out.WriteLine(responseObject.ToXml()); SifXPathContext context = SifXPathContext.NewSIFContext(responseObject); foreach (ElementRef reference in query.FieldRestrictionRefs) { Element found = context.GetElementOrAttribute(reference.XPath); Assert.IsNotNull(found, reference.XPath); } Element sectionInfoList = responseObject.GetElementOrAttribute("ScheduleInfoList/ScheduleInfo/SectionInfoList"); Assert.IsNull(sectionInfoList); }
public static void runAssertions( SifDataObject originalObject, SifDataObject reparsedObject ) { runAssertions( originalObject, reparsedObject, null ); }
public static void runAssertions( SifDataObject originalObject, SifDataObject reparsedObject, List<IElementDef> expectedDifferences, SifVersion version ) { // run additional assertions by overriding this method // Compare the objects Element[][] diffs = originalObject.CompareGraphTo( reparsedObject ); if ( diffs[0].Length == 0 ) Console.WriteLine( "\r\n*** Objects are identical ***\r\n" ); else { bool isChanged = false; // Display differences in two columns Console.WriteLine(); Console.WriteLine( pad( "Original Object" ) + " " + pad( "Reparsed Object" ) ); Console.WriteLine( underline( 50 ) + " " + underline( 50 ) ); StringBuilder str = new StringBuilder(); for ( int i = 0; i < diffs[0].Length; i++ ) { Element originalElement = diffs[0][i]; Element newElement = diffs[1][i]; str.Length = 0; if ( originalElement != null ) { } appendElementDesc( originalElement, str, version ); str.Append( ' ' ); appendElementDesc( newElement, str, version ); // The Element.compareGraphTo() method either has a bug, or else // the behavior is supposed to be this // way. ( Eric, please verify ). We only want to fail if the two // fields are entirely different. String s1 = originalElement == null ? "" : originalElement.TextValue; s1 = s1 == null ? "" : s1; String s2 = newElement == null ? "" : newElement.TextValue; s2 = s2 == null ? "" : s2; if ( !s1.Equals( s2 ) ) { if ( expectedDifferences != null && ( (originalElement != null && expectedDifferences.Contains( originalElement.ElementDef )) || (newElement != null && expectedDifferences.Contains( newElement.ElementDef )) ) ) { str.Append( " [Expected Diff]" ); } else { isChanged = true; } } Console.WriteLine( str.ToString() ); } if ( isChanged ) { // TODO: The ADK Compare Graph To method needs to be fixed // disabling this check for now so that we don't have a lot of // failing tests, since this is a known issue and logged in // TestTrack //Assert.fail( " Original and reparsed object differ, see System.Out for details " ); } } }
/// <summary> Populate a SifDataObject from values in the supplied IDictionary. /// /// This form of the <c>map</c> method that accepts a custom /// <c>ValueBuilder</c> implementation to evaluate value expressions /// in XPath-like query strings. The <c>map</c> method uses the /// DefaultValueBuilder class as its built-in implementation, but you can /// supply your own by calling this method instead. /// /// </summary> /// <param name="adaptor">An IFieldAdaptor that contains field values to assign to the /// supplied SifDataObject, where each entry in the map is keyed by the /// local application-defined name of a field and the value is the text /// value to assign to the corresponding element or attribute of the /// SifDataObject. /// /// </param> /// <param name="adaptor">An IFieldAdaptor containing field values</param> /// <param name="data">The SifDataObject to assign field values to /// /// </param> /// <param name="valueBuilder">A custom ValueBuilder implementation to evaluate /// value expressions in XPath-like query strings /// /// </param> /// <exception cref="AdkMappingException"> thrown if an error occurs while /// evaluating a field rule /// </exception> public void MapOutbound(IFieldAdaptor adaptor, SifDataObject data, IValueBuilder valueBuilder) { MapOutbound(adaptor, data, valueBuilder, Adk.SifVersion); }
/// <summary> /// Populate a SifDataObject from values in the supplied IDictionary. /// </summary> /// <param name="adaptor">An IFieldAdaptor that contains field values to assign to the /// supplied SifDataObject, where each entry in the map is keyed by the /// local application-defined name of a field and the value is the text /// value to assign to the corresponding element or attribute of the /// SifDataObject.</param> /// <param name="dataObject">The SifDataObject to assign field values to</param> /// <param name="version">The SifVersion associated with the mapping operation. /// For inbound SIF_Event and SIF_Response messages, this value should /// be obtained by calling <c>getSIFVersion</c> on the /// <i>SifMessageInfo</i> parameter passed to the message handler. For /// inbound SIF_Request messages, it should be obtained by calling the /// <c>SifMessageInfo.getSIFRequestVersion</c> method. For /// outbound messages, this value should be obtained by calling /// <c>Adk.getSIFVersion</c> to get the version of SIF the class /// framework was initialized with. Note when this parameter is /// <c>null</c>, no SIF Version filtering will be applied to /// field mapping rules.</param> public void MapOutbound(IFieldAdaptor adaptor, SifDataObject dataObject, SifVersion version) { MapOutbound(adaptor, dataObject, new DefaultValueBuilder(adaptor), version); }
/// <summary> Populate a SifDataObject from values in the supplied IDictionary. /// /// This form of the <c>map</c> method allows the caller to specify /// whether it is performing an inbound or outbound mapping operation, /// as well as the version of SIF associated with the SIF Data Object /// that's being mapped. These values are used to filter field mapping rules. /// The direction flag is also used to invoke automatic ValueSet /// translations on fields that have a <i>ValueSet</i> attribute. /// /// </summary> /// <param name="adaptor">An IFieldAdaptor that contains field values to assign to the /// supplied SifDataObject, where each entry in the map is keyed by the /// local application-defined name of a field and the value is the text /// value to assign to the corresponding element or attribute of the /// SifDataObject. /// /// </param> /// <param name="dataObject">The SifDataObject to assign field values to /// /// </param> /// <param name="valueBuilder">A custom ValueBuilder implementation to evaluate /// value expressions in XPath-like query strings /// /// </param> /// <param name="version">The SifVersion associated with the mapping operation. /// For inbound SIF_Event and SIF_Response messages, this value should /// be obtained by calling <c>getSIFVersion</c> on the /// <i>SifMessageInfo</i> parameter passed to the message handler. For /// inbound SIF_Request messages, it should be obtained by calling the /// <c>SifMessageInfo.getSIFRequestVersion</c> method. For /// outbound messages, this value should be obtained by calling /// <c>Adk.getSIFVersion</c> to get the version of SIF the class /// framework was initialized with. Note when this parameter is /// <c>null</c>, no SIF Version filtering will be applied to /// field mapping rules. /// /// </param> /// <exception cref="AdkMappingException"> thrown if an error occurs while /// evaluating a field rule</exception> public void MapOutbound(IFieldAdaptor adaptor, SifDataObject dataObject, IValueBuilder valueBuilder, SifVersion version) { ObjectMapping om = GetRules(dataObject.ElementDef.Tag(version), true); if (om != null) { SifXPathContext xpathContext = SifXPathContext.NewSIFContext(dataObject, version); if (adaptor is IXPathVariableLibrary) { xpathContext.AddVariables("", (IXPathVariableLibrary) adaptor); } IList<FieldMapping> list = GetRulesList(om, version, MappingDirection.Outbound); MapOutbound(xpathContext, adaptor, dataObject, list, valueBuilder, version); } }
/// <summary> Return an array of all ObjectMapping definitions for a given object type.</summary> /// <param name="obj">A SIF Data Object (e.g. "StudentPersonal") /// </param> /// <param name="inherit">True to inherit the ObjectMapping from the ancestry if /// this Mappings instance does not define it /// </param> public ObjectMapping GetRules(SifDataObject obj, bool inherit) { return obj != null ? GetRules(obj.ElementDef.Name, inherit) : null; }
/// <summary> Write a SifDataObject to the stream</summary> public abstract void Write( SifDataObject data );
public static void runAssertions( SifDataObject originalObject, SifDataObject reparsedObject, List<IElementDef> expectedDifferences ) { runAssertions( originalObject, reparsedObject, expectedDifferences, Adk.SifVersion ); }
/// <summary> Produce a table of field values from a SIF Data Object. /// /// This form of the <c>map</c> method allows the client to specify /// whether it is performing an inbound or outbound mapping operation. /// Currently, the direction flag is used to invoke automatic ValueSet /// translations on fields that have a <i>ValueSet</i> attribute. /// /// </summary> /// <param name="data">The SifDataObject from which to retrieve element and /// attribute values from when performing the mapping operation. /// /// </param> /// <param name="results">A IDictionary to receive the results of the mapping, where /// each entry in the map is keyed by the local application-defined name /// of a field and the value is the text value of the corresponding /// element or attribute in the SifDataObject.</param> /// <param name="version">The SifVersion associated with the mapping operation. /// For inbound SIF_Event and SIF_Response messages, this value should /// be obtained by calling <c>getSIFVersion</c> on the /// <i>SifMessageInfo</i> parameter passed to the message handler. For /// inbound SIF_Request messages, it should be obtained by calling the /// <c>SifMessageInfo.getSIFRequestVersion</c> method. For /// outbound messages, this value should be obtained by calling /// <c>Adk.getSIFVersion</c> to get the version of SIF the class /// framework was initialized with. Note when this parameter is /// <c>null</c>, no SIF Version filtering will be applied to /// field mapping rules. /// /// </param> /// <exception cref="AdkMappingException"> thrown if an error occurs while evaluating /// a field rule /// /// @since Adk 1.5 /// </exception> public void MapInbound(SifDataObject data, IFieldAdaptor results, SifVersion version) { ObjectMapping om = GetRules(data.ElementDef.Tag(data.SifVersion), true); if (om != null) { SifXPathContext xpathContext = SifXPathContext.NewSIFContext(data, version); if (results is IXPathVariableLibrary) { xpathContext.AddVariables("", (IXPathVariableLibrary) results); } IList<FieldMapping> list = GetRulesList(om, version, MappingDirection.Inbound); MapInbound(xpathContext, results, data, list, version); } }
/// <summary> Write a SifDataObject to the stream</summary> public override void Write(SifDataObject data) { // Check to see if the data object is null or if the // deferResponses() property has been set if (data == null || fDeferResponses) { return; } // Check to see if a SIF_Error has already been written if (fError != null) { throw new AdkException ("A SIF_Error has already been written to the stream", fZone); } // If the autoFilter property has been set, determine if this object meets the // conditions of the filter if (fFilter != null) { if (!fFilter.Evaluate(data)) { // TODO: Perhaps this feature should log any objects not written to the output // stream if extended logging is enabled return; } } try { if (fCurrentOutputStream == null || fZone.Properties.OneObjectPerResponse) { NewPacket(); } using (MemoryStream buffer = new MemoryStream()) { // Write to memory stream first so we can determine if the resulting // message will fit in the current packet WriteObject(data, buffer, fRenderAsVersion, fQueryRestrictions); if ((buffer.Length + fCurSize) > fMaxSize) { // If the current packet size is equal to the envelope size (e.g. no objects // have been written), we have exceeded the size of the buffer and need to abort if (buffer.Length == fEnvSize) { String errorMessage = "Publisher result data in packet " + fCurPacket + " too large (" + buffer.Length + " [Data] + " + fEnvSize + " [Sif Envelope] > " + fMaxSize + ")"; if (fZone.Properties.OneObjectPerResponse) { errorMessage += " [1 Object per Response Packet]"; } throw new AdkException(errorMessage, fZone); } else { // Create new packet for this object NewPacket(); } } if ((Adk.Debug & AdkDebugFlags.Message_Content) != 0) { buffer.Seek(0, SeekOrigin.Begin); StreamReader reader = new StreamReader(buffer, SifIOFormatter.ENCODING); string message = reader.ReadToEnd(); fZone.Log.Debug ("Writing object to SIF_Response packet #" + fCurPacket + ":\r\n" + message); } buffer.Seek(0, SeekOrigin.Begin); Streams.CopyStream(buffer, fCurrentOutputStream); fCurSize += buffer.Length; buffer.Close(); } } catch (Exception ioe) { throw new AdkException ( "Failed to write Publisher result data (packet " + fCurPacket + ") to " + fFile.FullName + ": " + ioe, fZone); } }
public void ReportEvent(SifDataObject obj, EventAction action, string destinationId) { // TODO: Add TestZone.ReportEvent implementation }
/// <summary> Write a SifDataObject to the stream</summary> public abstract void Write(SifDataObject data);
void IZone.ReportEvent(SifDataObject obj, EventAction action) { // TODO: Add TestZone.OpenADK.Library.IZone.ReportEvent implementation }
/// <summary> Dispatch a SIF_Event. /// /// <b>When ALQ Disabled:</b> Dispatching of this event is handled in a /// separate EvDisp thread in case SMB is invoked. This makes it possible /// to asynchronously return a SIF_Ack code to the dispatchEvent() caller /// before the handling of the event by the Subscriber is completed. The /// EvDisp also tracks the internal dispatch state of this particular message. /// The Topic matching the object type is then notified via its Subscriber's /// onEvent method. If a TrackQueryResults object is created within that /// method, its constructor will wakeup the EvDisp thread, instructing it to /// return a value of 2 (Intermediate). If no TrackQueryResults object is /// instantiated during the Subscriber.onEvent method, the EvDisp thread /// returns a 1 (Immediate) status code upon completion. /// /// <b>When ALQ Enabled:</b> Dispatching is immediate. The Topic matching /// the object type is then notified via its Subscriber's onEvent method, /// then processing ends. No EvDisp thread is needed because if a /// TrackQueryResults is used it will draw upon the ALQ instead of invoking /// SMB on the zone server. /// /// Note if an exception is thrown at any time during the processing of a /// SIF_Event, it is propagated up the call stack. The PH must not return a /// SIF_Ack for the message; the ALQ must not delete the message from its /// queue. /// /// </summary> private int dispatchEvent(SIF_Event sifEvent) { if ((Adk.Debug & AdkDebugFlags.Messaging_Event_Dispatching) != 0) { fZone.Log.Debug("Dispatching SIF_Event (" + sifEvent.MsgId + ")..."); } // Was this event reported by this agent? if (!fZone.Properties.ProcessEventsFromSelf && sifEvent.Header.SIF_SourceId.Equals(fZone.Agent.Id)) { if ((Adk.Debug & AdkDebugFlags.Messaging_Event_Dispatching) != 0) { fZone.Log.Debug ( "SIF_Event ignored because it was originally reported by this agent (see the adk.messaging.processEventsFromSelf property)"); } return 1; } SIF_ObjectData odata = sifEvent.SIF_ObjectData; if (odata == null) { throw new SifException (SifErrorCategoryCode.Xml, SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6, "SIF_Event message missing mandatory element", "SIF_ObjectData is a required element", fZone); } // // Loop through all SIF_EventObjects inside this SIF_Event and dispatch // to corresponding topics // SIF_EventObject eventObj = odata.SIF_EventObject; if (eventObj == null) { throw new SifException ( SifErrorCategoryCode.Xml, SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6, "SIF_Event message missing mandatory element", "SIF_ObjectData/SIF_EventObject is a required element", fZone); } int ackCode = 1; int thisCode; SifMessageInfo msgInfo = new SifMessageInfo(sifEvent, fZone); IElementDef typ = Adk.Dtd.LookupElementDef(eventObj.ObjectName); if (typ == null) { // SIF Data Object type not supported throw new SifException ( SifErrorCategoryCode.EventReportingAndProcessing, SifErrorCodes.EVENT_INVALID_EVENT_3, "Agent does not support this object type", eventObj.ObjectName, fZone); } // TODO: For now, the ADK only routes SIF Events to the first context // in the event. This needs to be implemented to support // events in multiple contexts SifContext eventContext = msgInfo.SIFContexts[0]; ISubscriber target = null; ITopic topic = null; // // Lookup the Topic for this SIF object type // Topics are only used for the SIF Default context // topic = fZone.Agent.TopicFactory.LookupInstance(typ, eventContext); if (topic != null) { target = topic.GetSubscriber(); } if (target == null) { // Is a Subscriber registered with the Zone? target = fZone.GetSubscriber(eventContext, typ); if (target == null) { // Is a Subscriber registered with the Agent? target = fZone.GetSubscriber(eventContext, typ); if (target == null) { // // No Subscriber message handler found. Try calling the Undeliverable- // MessageHandler for the zone or agent. If none is registered, // return an error SIF_Ack indicating the object type is not // supported. // Boolean handled = false; IUndeliverableMessageHandler errHandler = fZone.ErrorHandler; if (errHandler != null) { handled = errHandler.OnDispatchError(sifEvent, fZone, msgInfo); // Notify MessagingListeners... IEnumerable<IMessagingListener> mList = GetMessagingListeners(fZone); foreach (IMessagingListener ml in mList) { ml.OnMessageProcessed(SifMessageType.SIF_Event, msgInfo); } } if (!handled) { fZone.Log.Warn("Received a SIF_Event (" + sifEvent.MsgId + "), but no Subscriber object is registered to handle it"); throw new SifException( SifErrorCategoryCode.EventReportingAndProcessing, SifErrorCodes.EVENT_INVALID_EVENT_3, "Agent does not support this object type", eventObj.ObjectName, fZone); } return 1; } } } // // Call Subscriber.onEvent with the event data // IList<SifElement> sel = eventObj.GetChildList(); SifDataObject[] data = new SifDataObject[sel.Count]; for (int x = 0; x < sel.Count; x++) { data[x] = (SifDataObject)sel[x]; } // Wrap in an Event object DataObjectInputStreamImpl dataStr = DataObjectInputStreamImpl.newInstance(); dataStr.Data = data; Event adkEvent = new Event(dataStr, eventObj.Action, eventObj.GetChildList()[0].ElementDef); adkEvent.Zone = fZone; if ((Adk.Debug & AdkDebugFlags.Messaging_Event_Dispatching) != 0) { fZone.Log.Debug ( "SIF_Event contains " + data.Length + " " + eventObj.ObjectName + " objects (" + eventObj.Action + ")"); } if (fQueue == null) { if ((Adk.Debug & AdkDebugFlags.Messaging_Event_Dispatching) != 0) { fZone.Log.Debug ("Dispatching SIF_Event to Subscriber message handler via EvDisp"); } // // -- No ALQ available -- // Dispatch in a separate EvDisp thread. Block until an ack // status code is available, then return it // EvDisp disp; try { disp = checkoutEvDisp(adkEvent); thisCode = disp.dispatch(target, adkEvent, fZone, topic, msgInfo); } finally { checkinEvDisp(adkEvent); } } else { if ((Adk.Debug & AdkDebugFlags.Messaging_Event_Dispatching) != 0) { fZone.Log.Debug("Dispatching SIF_Event to Subscriber message handler"); } // // -- ALQ is available -- // Dispatch immediately. // try { target.OnEvent(adkEvent, fZone, msgInfo); } catch (SifException) { throw; } catch (Exception thr) { throw new SifException (SifErrorCategoryCode.EventReportingAndProcessing, SifErrorCodes.EVENT_GENERIC_ERROR_1, "Error processing SIF_Event", "Exception in Subscriber.onEvent message handler: " + thr, fZone); } thisCode = 1; } if (thisCode > ackCode) { ackCode = thisCode; } if ((Adk.Debug & AdkDebugFlags.Messaging) != 0) { fZone.Log.Debug ("SIF_Event (" + sifEvent.MsgId + ") dispatching returning SIF_Ack status " + ackCode); } return ackCode; }
/// <summary> Write a SifDataObject to the stream</summary> public override void Write( SifDataObject data ) { // Check to see if the data object is null or if the // deferResponses() property has been set if ( data == null || fDeferResponses ) { return; } // Check to see if a SIF_Error has already been written if ( fError != null ) { throw new AdkException ( "A SIF_Error has already been written to the stream", fZone ); } // If the autoFilter property has been set, determine if this object meets the // conditions of the filter if ( fFilter != null ) { if ( !fFilter.Evaluate( data ) ) { // TODO: Perhaps this feature should log any objects not written to the output // stream if extended logging is enabled return; } } try { if ( fCurrentOutputStream == null || fZone.Properties.OneObjectPerResponse ) { NewPacket(); } using ( MemoryStream buffer = new MemoryStream() ) { // Write to memory stream first so we can determine if the resulting // message will fit in the current packet WriteObject( data, buffer, fRenderAsVersion, fQueryRestrictions ); if ( (buffer.Length + fCurSize) > fMaxSize ) { // If the current packet size is equal to the envelope size (e.g. no objects // have been written), we have exceeded the size of the buffer and need to abort if ( buffer.Length == fEnvSize ) { String errorMessage = "Publisher result data in packet " + fCurPacket + " too large (" + buffer.Length + " [Data] + " + fEnvSize + " [Sif Envelope] > " + fMaxSize + ")"; if ( fZone.Properties.OneObjectPerResponse ) { errorMessage += " [1 Object per Response Packet]"; } throw new AdkException( errorMessage, fZone ); } else { // Create new packet for this object NewPacket(); } } if ( (Adk.Debug & AdkDebugFlags.Message_Content) != 0 ) { buffer.Seek( 0, SeekOrigin.Begin ); StreamReader reader = new StreamReader( buffer, SifIOFormatter.ENCODING ); string message = reader.ReadToEnd(); fZone.Log.Debug ( "Writing object to SIF_Response packet #" + fCurPacket + ":\r\n" + message ); } buffer.Seek( 0, SeekOrigin.Begin ); Streams.CopyStream( buffer, fCurrentOutputStream ); fCurSize += buffer.Length; buffer.Close(); } } catch ( IOException ioe ) { throw new AdkException ( "Failed to write Publisher result data (packet " + fCurPacket + ") to " + fFile.FullName + ": " + ioe, fZone ); } }
/// <summary> Dispatch a SIF_Response. /// /// SIF_Response messages are dispatched as follows: /// /// <ul> /// <li> /// If a TrackQueryResults object issued the original SIF_Request /// during this agent session (i.e. the agent process has not /// terminated since the SIF_Request was issued), the response is /// dispatched to that TrackQueryResults object via its QueryResults /// interface. /// </li> /// <li> /// If a Topic exists for the data type associated with the /// SIF_Response, it is dispatched to the QueryResults object /// registered with that Topic. /// </li> /// <li> /// If no Topic exists for the data type associated with the /// SIF_Response, it is dispatched to the QueryResults object /// registered with the Zone from which the SIF_Response was /// received. /// </li> /// </ul> /// /// <b>SIF_ZoneStatus</b> is handled specially. When Zone.awaitingZoneStatus /// returns true, the agent is blocking on a call to Zone.getZoneStatus(). /// In this case, the SIF_ZoneStatus object is routed directly to the Zone /// object instead of being dispatched via the usual QueryResults mechanism. /// /// </summary> private void dispatchResponse(SIF_Response rsp) { // block thread until Zone.Query() has completed in case it is in the // midst of a SIF_Request. This is done to ensure that we don't receive // the SIF_Response from the zone before the ADK and agent have finished // with the SIF_Request in Zone.Query() fZone.WaitForRequestsToComplete(); bool retry = false; IRequestInfo reqInfo = null; AdkException cacheErr = null; try { try { reqInfo = fRequestCache.LookupRequestInfo(rsp.SIF_RequestMsgId, fZone); } catch (AdkException adke) { cacheErr = adke; } #if PROFILED if( objType != null ) { ProfilerUtils.profileStart( com.OpenADK.sifprofiler.api.OIDs.ADK_SIFRESPONSE_REQUESTOR_MESSAGING.ToString(), Adk.Dtd.LookupElementDef(objType), rsp.MsgId ); } #endif SIF_Error error = null; SIF_ObjectData od = rsp.SIF_ObjectData; if (od == null) { throw new SifException ( SifErrorCategoryCode.Xml, SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6, "SIF_Response missing mandatory element", "SIF_ObjectData is a required element of SIF_Response", fZone); } IList<SifElement> sel = od.GetChildList(); if (sel.Count < 1) { error = rsp.SIF_Error; // // If the SIF_Response has no SIF_ObjectData elements but does // have a SIF_Error child, the associated object type can // only be gotten from the RequestCache, but that had // failed so try and call the UndeliverableMessageHandler. // if (cacheErr != null || reqInfo == null) { bool handled = false; IUndeliverableMessageHandler errHandler = fZone.ErrorHandler; if (errHandler != null) { SifMessageInfo msginfo = new SifMessageInfo(rsp, fZone); msginfo.SIFRequestInfo = reqInfo; handled = errHandler.OnDispatchError(rsp, fZone, msginfo); // Notify MessagingListeners... NotifyMessagingListeners_OnMessageProcessed (SifMessageType.SIF_Response, msginfo); } if (!handled) { fZone.Log.Warn ( "Received a SIF_Response message with MsgId " + rsp.MsgId + " (for SIF_Request with MsgId " + rsp.SIF_RequestMsgId + ") " + " containing an empty result set or a SIF_Error, but failed to obtain the SIF Data Object" + " type from the RequestCache" + (cacheErr != null ? (" due to an error: " + cacheErr.Message) : "")); } return; } } string objectType = reqInfo != null ? reqInfo.ObjectType : null; if (objectType == null && sel.Count > 0) { objectType = sel[0].ElementDef.Tag(rsp.SifVersion); } if (objectType != null && (string.Compare(objectType, "SIF_ZoneStatus", true) == 0)) { // SIF_ZoneStatus is a special case if (fZone.AwaitingZoneStatus()) { fZone.SetZoneStatus((SIF_ZoneStatus)sel[0]); return; } } if (reqInfo == null) { reqInfo = new UnknownRequestInfo(rsp.SIF_RequestMsgId, objectType); } // Decide where to send this response IQueryResults target = getQueryResultsTarget (rsp, null, Adk.Dtd.LookupElementDef(objectType), null, fZone); if (target == null) { bool handled = false; IUndeliverableMessageHandler errHandler = fZone.ErrorHandler; if (errHandler != null) { SifMessageInfo msginfo = new SifMessageInfo(rsp, fZone); if (reqInfo != null) { msginfo.SIFRequestInfo = reqInfo; } handled = errHandler.OnDispatchError(rsp, fZone, msginfo); // Notify MessagingListeners... NotifyMessagingListeners_OnMessageProcessed (SifMessageType.SIF_Response, msginfo); } if (!handled) { fZone.Log.Warn ("Received a SIF_Response message with MsgId " + rsp.MsgId + " (for SIF_Request with MsgId " + rsp.SIF_RequestMsgId + "), but no QueryResults object is registered to handle it or the request was issued by a TrackQueryResults that has timed out"); } return; } // // Dispatch the message... // IElementDef sifRequestObjectDef = Adk.Dtd.LookupElementDef(objectType); DataObjectInputStreamImpl dataStr = DataObjectInputStreamImpl.newInstance(); dataStr.fObjType = sifRequestObjectDef; if (error == null) { // Convert to a SifDataObject array SifDataObject[] data = new SifDataObject[sel.Count]; for (int i = 0; i < sel.Count; i++) { data[i] = (SifDataObject)sel[i]; } // Let the QueryResults object process the message dataStr.Data = data; } SifMessageInfo msgInf = new SifMessageInfo(rsp, fZone); msgInf.SIFRequestInfo = reqInfo; msgInf.SIFRequestObjectType = sifRequestObjectDef; target.OnQueryResults(dataStr, error, fZone, msgInf); // Notify MessagingListeners... NotifyMessagingListeners_OnMessageProcessed(SifMessageType.SIF_Response, msgInf); } catch (AdkException adkEx) { retry = adkEx.Retry; throw; } catch (Exception thr) { throw new SifException ( SifErrorCategoryCode.Generic, SifErrorCodes.GENERIC_GENERIC_ERROR_1, "Error processing SIF_Response", "Exception in QueryResults message handler: " + thr.ToString(), fZone); } finally { // If the reqInfo variable came from the cache, and retry is set to false, // remove it from the cache if this is the last packet if (!(reqInfo is UnknownRequestInfo) && !retry) { String morePackets = rsp.SIF_MorePackets; if (!(morePackets != null && morePackets.ToLower().Equals("yes"))) { // remove from the cache fRequestCache.GetRequestInfo(rsp.SIF_RequestMsgId, fZone); } } #if PROFILED if( BuildOptions.PROFILED ) { if( reqInfo != null ) { ProfilerUtils.profileStop(); } #endif } }
public override SifSimpleType Evaluate(SifXPathContext context, SifVersion version) { SifDataObject sdo = (SifDataObject)context.ContextElement; return(Evaluate(sdo, version)); }