Exemplo n.º 1
0
        public void LookupAmqpMethod(MethodInfo method,
                                     string methodName,
                                     out AmqpClass amqpClass,
                                     out AmqpMethod amqpMethod)
        {
            amqpClass  = null;
            amqpMethod = null;

            // First, try autodetecting the class/method via the
            // IModel method name.

            foreach (AmqpClass c in m_classes)
            {
                foreach (AmqpMethod m in c.m_Methods)
                {
                    if (methodName.Equals(MangleMethodClass(c, m)))
                    {
                        amqpClass  = c;
                        amqpMethod = m;
                        goto stopSearching; // wheee
                    }
                }
            }
stopSearching:

            // If an explicit mapping was provided as an attribute,
            // then use that instead, whether the autodetect worked or
            // not.

            {
                AmqpMethodMappingAttribute methodMapping =
                    Attribute(method, typeof(AmqpMethodMappingAttribute)) as AmqpMethodMappingAttribute;
                if (methodMapping != null)
                {
                    amqpClass = null;
                    foreach (AmqpClass c in m_classes)
                    {
                        if (c.Name == methodMapping.m_className)
                        {
                            amqpClass = c;
                            break;
                        }
                    }
                    amqpMethod = amqpClass.MethodNamed(methodMapping.m_methodName);
                }
            }

            // At this point, if can't find either the class or the
            // method, we can't proceed. Complain.

            if (amqpClass == null || amqpMethod == null)
            {
                throw new Exception("Could not find AMQP class or method for IModel method " + method.Name);
            }
        }
Exemplo n.º 2
0
 public bool HasFactoryMethod(AmqpClass c)
 {
     foreach (Type t in m_modelTypes)
     {
         foreach (MethodInfo method in t.GetMethods())
         {
             AmqpContentHeaderFactoryAttribute f = (AmqpContentHeaderFactoryAttribute)
                                                   Attribute(method, typeof(AmqpContentHeaderFactoryAttribute));
             if (f != null && MangleClass(f.m_contentClass) == MangleClass(c.Name))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Exemplo n.º 3
0
 public void EmitClassMethods(AmqpClass c)
 {
     foreach (AmqpMethod m in c.m_Methods)
     {
         EmitAutogeneratedSummary("  ",
                                  "AMQP specification method \"" + c.Name + "." + m.Name + "\".");
         EmitSpecComment(m.DocumentationCommentVariant("  ", "remarks"));
         EmitLine("  public interface I" + MangleMethodClass(c, m) + ": IMethod {");
         foreach (AmqpField f in m.m_Fields)
         {
             EmitSpecComment(f.DocumentationComment("    "));
             EmitLine("    " + MapDomain(f.Domain) + " " + MangleClass(f.Name) + " { get; }");
         }
         EmitLine("  }");
     }
 }
Exemplo n.º 4
0
        public void LookupAmqpMethod(MethodInfo method,
                                     string methodName,
                                     out AmqpClass amqpClass,
                                     out AmqpMethod amqpMethod)
        {
            amqpClass = null;
            amqpMethod = null;
            
            // First, try autodetecting the class/method via the
            // IModel method name.

            foreach (AmqpClass c in m_classes) {
                foreach (AmqpMethod m in c.m_Methods)
                {
                    if (methodName.Equals(MangleMethodClass(c,m))) {
                        amqpClass = c;
                        amqpMethod = m;
                        goto stopSearching; // wheee
                    }
                }
            }
            stopSearching:

            // If an explicit mapping was provided as an attribute,
            // then use that instead, whether the autodetect worked or
            // not.

            {
                AmqpMethodMappingAttribute methodMapping =
                    Attribute(method, typeof(AmqpMethodMappingAttribute)) as AmqpMethodMappingAttribute;
                if (methodMapping != null) {
                    amqpClass = null;
                    foreach (AmqpClass c in m_classes) {
                        if (c.Name == methodMapping.m_className) {
                            amqpClass = c;
                            break;
                        }
                    }
                    amqpMethod = amqpClass.MethodNamed(methodMapping.m_methodName);
                }
            }

            // At this point, if can't find either the class or the
            // method, we can't proceed. Complain.

            if (amqpClass == null || amqpMethod == null) {
                throw new Exception("Could not find AMQP class or method for IModel method " + method.Name);
            }
        }
Exemplo n.º 5
0
 public void EmitClassMethodImplementations(AmqpClass c) {
     foreach (AmqpMethod m in c.m_Methods)
     {
         EmitAutogeneratedSummary("  ",
                                  "Private implementation class - do not use directly.");
         EmitLine("  public class "+MangleMethodClass(c,m)
                  +": RabbitMQ.Client.Impl.MethodBase, I"+MangleMethodClass(c,m)+" {");
         EmitLine("    public const int ClassId = "+c.Index+";");
         EmitLine("    public const int MethodId = "+m.Index+";");
         EmitLine("");
         foreach (AmqpField f in m.m_Fields)
         {
             EmitLine("    public "+MapDomain(f.Domain)+" m_"+MangleMethod(f.Name)+";");
         }
         EmitLine("");
         foreach (AmqpField f in m.m_Fields)
         {
             EmitLine("    "+MapDomain(f.Domain)+" I"+MangleMethodClass(c,m)+
                      "."+MangleClass(f.Name)+" { get {"
                      + " return m_" + MangleMethod(f.Name) + "; } }");
         }
         EmitLine("");
         if (m.m_Fields.Count > 0)
         {
             EmitLine("    public "+MangleMethodClass(c,m)+"() {}");
         }
         EmitLine("    public "+MangleMethodClass(c,m)+"(");
         {
             int remaining = m.m_Fields.Count;
             foreach (AmqpField f in m.m_Fields)
             {
                 Emit("      "+MapDomain(f.Domain)+" init"+MangleClass(f.Name));
                 remaining--;
                 if (remaining > 0) {
                     EmitLine(",");
                 }
             }
         }
         EmitLine(")");
         EmitLine("    {");
         foreach (AmqpField f in m.m_Fields)
         {
             EmitLine("      m_" + MangleMethod(f.Name) + " = init" + MangleClass(f.Name) + ";");
         }
         EmitLine("    }");
         EmitLine("");
         EmitLine("    public override int ProtocolClassId { get { return "+c.Index+"; } }");
         EmitLine("    public override int ProtocolMethodId { get { return "+m.Index+"; } }");
         EmitLine("    public override string ProtocolMethodName { get { return \""+c.Name+"."+m.Name+"\"; } }");
         EmitLine("    public override bool HasContent { get { return "
                  +(m.HasContent ? "true" : "false")+"; } }");
         EmitLine("");
         EmitLine("    public override void ReadArgumentsFrom(RabbitMQ.Client.Impl.MethodArgumentReader reader) {");
         foreach (AmqpField f in m.m_Fields)
         {
             EmitLine("      m_" + MangleMethod(f.Name) + " = reader.Read" + MangleClass(ResolveDomain(f.Domain)) + "();");
         }
         EmitLine("    }");
         EmitLine("");
         EmitLine("    public override void WriteArgumentsTo(RabbitMQ.Client.Impl.MethodArgumentWriter writer) {");
         foreach (AmqpField f in m.m_Fields)
         {
             EmitLine("      writer.Write"+MangleClass(ResolveDomain(f.Domain))
                      + "(m_" + MangleMethod(f.Name) + ");");
         }
         EmitLine("    }");
         EmitLine("");
         EmitLine("    public override void AppendArgumentDebugStringTo(System.Text.StringBuilder sb) {");
         EmitLine("      sb.Append(\"(\");");
         {
             int remaining = m.m_Fields.Count;
             foreach (AmqpField f in m.m_Fields)
             {
                 Emit("      sb.Append(m_" + MangleMethod(f.Name) + ");");
                 remaining--;
                 if (remaining > 0) {
                     EmitLine(" sb.Append(\",\");");
                 } else {
                     EmitLine("");
                 }
             }
         }
         EmitLine("      sb.Append(\")\");");
         EmitLine("    }");
         EmitLine("  }");
     }
 }
Exemplo n.º 6
0
        public void EmitClassProperties(AmqpClass c) {
	    bool hasCommonApi = HasFactoryMethod(c);
	    string propertiesBaseClass =
		hasCommonApi
		? "RabbitMQ.Client.Impl."+MangleClass(c.Name)+"Properties"
		: "RabbitMQ.Client.Impl.ContentHeaderBase";
	    string maybeOverride = hasCommonApi ? "override " : "";

            EmitAutogeneratedSummary("  ",
                                     "AMQP specification content header properties for "+
                                     "content class \""+c.Name+"\"");
            EmitSpecComment(c.DocumentationCommentVariant("  ", "remarks"));
            EmitLine("  public class "+MangleClass(c.Name)
                     +"Properties: "+propertiesBaseClass+" {");
            foreach (AmqpField f in c.m_Fields) {
                EmitLine("    private "+MapDomain(f.Domain)+" m_"+MangleMethod(f.Name)+";");
            }
            EmitLine("");
            foreach (AmqpField f in c.m_Fields)
            {
		if (!IsBoolean(f)) {
		    EmitLine("    private bool m_"+MangleMethod(f.Name)+"_present = false;");
		}
            }
            EmitLine("");
            foreach (AmqpField f in c.m_Fields)
            {
                EmitSpecComment(f.DocumentationComment("    ", "@label"));
                EmitLine("    public "+maybeOverride+MapDomain(f.Domain)+" "+MangleClass(f.Name)+" {");
                EmitLine("      get {");
                EmitLine("        return m_"+MangleMethod(f.Name)+";");
                EmitLine("      }");
                EmitLine("      set {");
		if (!IsBoolean(f)) {
		    EmitLine("        m_"+MangleMethod(f.Name)+"_present = true;");
		}
                EmitLine("        m_"+MangleMethod(f.Name)+" = value;");
                EmitLine("      }");
                EmitLine("    }");
            }
            EmitLine("");
            foreach (AmqpField f in c.m_Fields)
            {
		if (!IsBoolean(f)) {
		    EmitLine("    public "+maybeOverride+"void Clear"+MangleClass(f.Name)+"() { m_"+MangleMethod(f.Name)+"_present = false; }");
		}
            }
            EmitLine("");
            EmitLine("    public "+MangleClass(c.Name)+"Properties() {}");
            EmitLine("    public override int ProtocolClassId { get { return "+c.Index+"; } }");
            EmitLine("    public override string ProtocolClassName { get { return \""+c.Name+"\"; } }");
            EmitLine("");
            EmitLine("    public override void ReadPropertiesFrom(RabbitMQ.Client.Impl.ContentHeaderPropertyReader reader) {");
            foreach (AmqpField f in c.m_Fields)
            {
		if (IsBoolean(f)) {
		    EmitLine("      m_"+MangleMethod(f.Name)+" = reader.ReadBit();");
		} else {
		    EmitLine("      m_"+MangleMethod(f.Name)+"_present = reader.ReadPresence();");
		}
            }
	    EmitLine("      reader.FinishPresence();");
        foreach (AmqpField f in c.m_Fields)
        {
		if (!IsBoolean(f)) {
		    EmitLine("      if (m_"+MangleMethod(f.Name)+"_present) { m_"+MangleMethod(f.Name)+" = reader.Read"+MangleClass(ResolveDomain(f.Domain))+"(); }");
		}
            }
            EmitLine("    }");
            EmitLine("");
            EmitLine("    public override void WritePropertiesTo(RabbitMQ.Client.Impl.ContentHeaderPropertyWriter writer) {");
            foreach (AmqpField f in c.m_Fields)
            {
		if (IsBoolean(f)) {
		    EmitLine("      writer.WriteBit(m_"+MangleMethod(f.Name)+");");
		} else {
		    EmitLine("      writer.WritePresence(m_"+MangleMethod(f.Name)+"_present);");
		}
            }
	    EmitLine("      writer.FinishPresence();");
        foreach (AmqpField f in c.m_Fields)
        {
		if (!IsBoolean(f)) {
		    EmitLine("      if (m_"+MangleMethod(f.Name)+"_present) { writer.Write"+MangleClass(ResolveDomain(f.Domain))+"(m_"+MangleMethod(f.Name)+"); }");
		}
            }
            EmitLine("    }");
            EmitLine("");
            EmitLine("    public override void AppendPropertyDebugStringTo(System.Text.StringBuilder sb) {");
            EmitLine("      sb.Append(\"(\");");
            {
                int remaining = c.m_Fields.Count;
                foreach (AmqpField f in c.m_Fields)
                {
                    Emit("      sb.Append(\""+f.Name+"=\");");
		    if (IsBoolean(f)) {
			Emit(" sb.Append(m_"+MangleMethod(f.Name)+");");
		    } else {
			string x = MangleMethod(f.Name);
			if (IsReferenceType(f)) {
			    Emit(" sb.Append(m_"+x+"_present ? (m_"+x+" == null ? \"(null)\" : m_"+x+".ToString()) : \"_\");");
			} else {
			    Emit(" sb.Append(m_"+x+"_present ? m_"+x+".ToString() : \"_\");");
			}
		    }
                    remaining--;
                    if (remaining > 0) {
                        EmitLine(" sb.Append(\", \");");
                    } else {
                        EmitLine("");
                    }
                }
            }
            EmitLine("      sb.Append(\")\");");
            EmitLine("    }");
            EmitLine("  }");
        }
Exemplo n.º 7
0
 public bool HasFactoryMethod(AmqpClass c) {
     foreach (Type t in m_modelTypes) {
         foreach (MethodInfo method in t.GetMethods()) {
             AmqpContentHeaderFactoryAttribute f = (AmqpContentHeaderFactoryAttribute)
                 Attribute(method, typeof(AmqpContentHeaderFactoryAttribute));
             if (f != null && MangleClass(f.m_contentClass) == MangleClass(c.Name)) {
                 return true;
             }
         }
     }
     return false;
 }
Exemplo n.º 8
0
 public void EmitClassMethods(AmqpClass c) {
     foreach (AmqpMethod m in c.m_Methods) {
         EmitAutogeneratedSummary("  ",
                                  "AMQP specification method \""+c.Name+"."+m.Name+"\".");
         EmitSpecComment(m.DocumentationCommentVariant("  ", "remarks"));
         EmitLine("  public interface I"+MangleMethodClass(c, m)+": IMethod {");
         foreach (AmqpField f in m.m_Fields) {
             EmitSpecComment(f.DocumentationComment("    "));
             EmitLine("    "+MapDomain(f.Domain)+" "+MangleClass(f.Name)+" { get; }");
         }
         EmitLine("  }");
     }
 }
Exemplo n.º 9
0
 public static string MangleMethodClass(AmqpClass c, AmqpMethod m) {
     return MangleClass(c.Name) + MangleClass(m.Name);
 }
Exemplo n.º 10
0
 public void EmitClassMethodImplementations(AmqpClass c)
 {
     foreach (AmqpMethod m in c.m_Methods)
     {
         EmitAutogeneratedSummary("  ",
                                  "Private implementation class - do not use directly.");
         EmitLine("  public class " + MangleMethodClass(c, m)
                  + ": RabbitMQ.Client.Impl.MethodBase, I" + MangleMethodClass(c, m) + " {");
         EmitLine("    public const int ClassId = " + c.Index + ";");
         EmitLine("    public const int MethodId = " + m.Index + ";");
         EmitLine("");
         foreach (AmqpField f in m.m_Fields)
         {
             EmitLine("    public " + MapDomain(f.Domain) + " m_" + MangleMethod(f.Name) + ";");
         }
         EmitLine("");
         foreach (AmqpField f in m.m_Fields)
         {
             EmitLine("    " + MapDomain(f.Domain) + " I" + MangleMethodClass(c, m) +
                      "." + MangleClass(f.Name) + " { get {"
                      + " return m_" + MangleMethod(f.Name) + "; } }");
         }
         EmitLine("");
         if (m.m_Fields.Count > 0)
         {
             EmitLine("    public " + MangleMethodClass(c, m) + "() {}");
         }
         EmitLine("    public " + MangleMethodClass(c, m) + "(");
         {
             int remaining = m.m_Fields.Count;
             foreach (AmqpField f in m.m_Fields)
             {
                 Emit("      " + MapDomain(f.Domain) + " init" + MangleClass(f.Name));
                 remaining--;
                 if (remaining > 0)
                 {
                     EmitLine(",");
                 }
             }
         }
         EmitLine(")");
         EmitLine("    {");
         foreach (AmqpField f in m.m_Fields)
         {
             EmitLine("      m_" + MangleMethod(f.Name) + " = init" + MangleClass(f.Name) + ";");
         }
         EmitLine("    }");
         EmitLine("");
         EmitLine("    public override int ProtocolClassId { get { return " + c.Index + "; } }");
         EmitLine("    public override int ProtocolMethodId { get { return " + m.Index + "; } }");
         EmitLine("    public override string ProtocolMethodName { get { return \"" + c.Name + "." + m.Name + "\"; } }");
         EmitLine("    public override bool HasContent { get { return "
                  + (m.HasContent ? "true" : "false") + "; } }");
         EmitLine("");
         EmitLine("    public override void ReadArgumentsFrom(RabbitMQ.Client.Impl.MethodArgumentReader reader) {");
         foreach (AmqpField f in m.m_Fields)
         {
             EmitLine("      m_" + MangleMethod(f.Name) + " = reader.Read" + MangleClass(ResolveDomain(f.Domain)) + "();");
         }
         EmitLine("    }");
         EmitLine("");
         EmitLine("    public override void WriteArgumentsTo(RabbitMQ.Client.Impl.MethodArgumentWriter writer) {");
         foreach (AmqpField f in m.m_Fields)
         {
             EmitLine("      writer.Write" + MangleClass(ResolveDomain(f.Domain))
                      + "(m_" + MangleMethod(f.Name) + ");");
         }
         EmitLine("    }");
         EmitLine("");
         EmitLine("    public override void AppendArgumentDebugStringTo(System.Text.StringBuilder sb) {");
         EmitLine("      sb.Append(\"(\");");
         {
             int remaining = m.m_Fields.Count;
             foreach (AmqpField f in m.m_Fields)
             {
                 Emit("      sb.Append(m_" + MangleMethod(f.Name) + ");");
                 remaining--;
                 if (remaining > 0)
                 {
                     EmitLine(" sb.Append(\",\");");
                 }
                 else
                 {
                     EmitLine("");
                 }
             }
         }
         EmitLine("      sb.Append(\")\");");
         EmitLine("    }");
         EmitLine("  }");
     }
 }
Exemplo n.º 11
0
        public void EmitClassProperties(AmqpClass c)
        {
            bool   hasCommonApi        = HasFactoryMethod(c);
            string propertiesBaseClass =
                hasCommonApi
                ? "RabbitMQ.Client.Impl." + MangleClass(c.Name) + "Properties"
                : "RabbitMQ.Client.Impl.ContentHeaderBase";
            string maybeOverride = hasCommonApi ? "override " : "";

            EmitAutogeneratedSummary("  ",
                                     "AMQP specification content header properties for " +
                                     "content class \"" + c.Name + "\"");
            EmitSpecComment(c.DocumentationCommentVariant("  ", "remarks"));
            EmitLine("  public class " + MangleClass(c.Name)
                     + "Properties: " + propertiesBaseClass + " {");
            foreach (AmqpField f in c.m_Fields)
            {
                EmitLine("    private " + MapDomain(f.Domain) + " m_" + MangleMethod(f.Name) + ";");
            }
            EmitLine("");
            foreach (AmqpField f in c.m_Fields)
            {
                if (!IsBoolean(f))
                {
                    EmitLine("    private bool m_" + MangleMethod(f.Name) + "_present = false;");
                }
            }
            EmitLine("");
            foreach (AmqpField f in c.m_Fields)
            {
                EmitSpecComment(f.DocumentationComment("    ", "@label"));
                EmitLine("    public " + maybeOverride + MapDomain(f.Domain) + " " + MangleClass(f.Name) + " {");
                EmitLine("      get {");
                EmitLine("        return m_" + MangleMethod(f.Name) + ";");
                EmitLine("      }");
                EmitLine("      set {");
                if (!IsBoolean(f))
                {
                    EmitLine("        m_" + MangleMethod(f.Name) + "_present = true;");
                }
                EmitLine("        m_" + MangleMethod(f.Name) + " = value;");
                EmitLine("      }");
                EmitLine("    }");
            }
            EmitLine("");
            foreach (AmqpField f in c.m_Fields)
            {
                if (!IsBoolean(f))
                {
                    EmitLine("    public " + maybeOverride + "void Clear" + MangleClass(f.Name) + "() { m_" + MangleMethod(f.Name) + "_present = false; }");
                }
            }
            EmitLine("");
            EmitLine("    public " + MangleClass(c.Name) + "Properties() {}");
            EmitLine("    public override int ProtocolClassId { get { return " + c.Index + "; } }");
            EmitLine("    public override string ProtocolClassName { get { return \"" + c.Name + "\"; } }");
            EmitLine("");
            EmitLine("    public override void ReadPropertiesFrom(RabbitMQ.Client.Impl.ContentHeaderPropertyReader reader) {");
            foreach (AmqpField f in c.m_Fields)
            {
                if (IsBoolean(f))
                {
                    EmitLine("      m_" + MangleMethod(f.Name) + " = reader.ReadBit();");
                }
                else
                {
                    EmitLine("      m_" + MangleMethod(f.Name) + "_present = reader.ReadPresence();");
                }
            }
            EmitLine("      reader.FinishPresence();");
            foreach (AmqpField f in c.m_Fields)
            {
                if (!IsBoolean(f))
                {
                    EmitLine("      if (m_" + MangleMethod(f.Name) + "_present) { m_" + MangleMethod(f.Name) + " = reader.Read" + MangleClass(ResolveDomain(f.Domain)) + "(); }");
                }
            }
            EmitLine("    }");
            EmitLine("");
            EmitLine("    public override void WritePropertiesTo(RabbitMQ.Client.Impl.ContentHeaderPropertyWriter writer) {");
            foreach (AmqpField f in c.m_Fields)
            {
                if (IsBoolean(f))
                {
                    EmitLine("      writer.WriteBit(m_" + MangleMethod(f.Name) + ");");
                }
                else
                {
                    EmitLine("      writer.WritePresence(m_" + MangleMethod(f.Name) + "_present);");
                }
            }
            EmitLine("      writer.FinishPresence();");
            foreach (AmqpField f in c.m_Fields)
            {
                if (!IsBoolean(f))
                {
                    EmitLine("      if (m_" + MangleMethod(f.Name) + "_present) { writer.Write" + MangleClass(ResolveDomain(f.Domain)) + "(m_" + MangleMethod(f.Name) + "); }");
                }
            }
            EmitLine("    }");
            EmitLine("");
            EmitLine("    public override void AppendPropertyDebugStringTo(System.Text.StringBuilder sb) {");
            EmitLine("      sb.Append(\"(\");");
            {
                int remaining = c.m_Fields.Count;
                foreach (AmqpField f in c.m_Fields)
                {
                    Emit("      sb.Append(\"" + f.Name + "=\");");
                    if (IsBoolean(f))
                    {
                        Emit(" sb.Append(m_" + MangleMethod(f.Name) + ");");
                    }
                    else
                    {
                        string x = MangleMethod(f.Name);
                        if (IsReferenceType(f))
                        {
                            Emit(" sb.Append(m_" + x + "_present ? (m_" + x + " == null ? \"(null)\" : m_" + x + ".ToString()) : \"_\");");
                        }
                        else
                        {
                            Emit(" sb.Append(m_" + x + "_present ? m_" + x + ".ToString() : \"_\");");
                        }
                    }
                    remaining--;
                    if (remaining > 0)
                    {
                        EmitLine(" sb.Append(\", \");");
                    }
                    else
                    {
                        EmitLine("");
                    }
                }
            }
            EmitLine("      sb.Append(\")\");");
            EmitLine("    }");
            EmitLine("  }");
        }
Exemplo n.º 12
0
 public static string MangleMethodClass(AmqpClass c, AmqpMethod m)
 {
     return(MangleClass(c.Name) + MangleClass(m.Name));
 }
Exemplo n.º 13
0
        public void EmitAsynchronousHandlers(ArrayList asynchronousHandlers)
        {
            EmitLine("    public override bool DispatchAsynchronous(RabbitMQ.Client.Impl.Command cmd) {");
            EmitLine("      RabbitMQ.Client.Impl.MethodBase __method = (RabbitMQ.Client.Impl.MethodBase) cmd.Method;");
            EmitLine("      switch ((__method.ProtocolClassId << 16) | __method.ProtocolMethodId) {");
            foreach (MethodInfo method in asynchronousHandlers)
            {
                string methodName = method.Name;
                if (methodName.StartsWith("Handle"))
                {
                    methodName = methodName.Substring(6);
                }

                AmqpClass  amqpClass  = null;
                AmqpMethod amqpMethod = null;
                LookupAmqpMethod(method, methodName, out amqpClass, out amqpMethod);

                string implClass = MangleMethodClass(amqpClass, amqpMethod);

                EmitLine("        case " + ((amqpClass.Index << 16) | amqpMethod.Index) + ": {");
                ParameterInfo[] parameters = method.GetParameters();
                if (parameters.Length > 0)
                {
                    EmitLine("          " + implClass + " __impl = (" + implClass + ") __method;");
                    EmitLine("          " + method.Name + "(");
                    int remaining = parameters.Length;
                    foreach (ParameterInfo pi in parameters)
                    {
                        if (Attribute(pi, typeof(AmqpContentHeaderMappingAttribute)) != null)
                        {
                            Emit("            (" + pi.ParameterType + ") cmd.Header");
                        }
                        else if (Attribute(pi, typeof(AmqpContentBodyMappingAttribute)) != null)
                        {
                            Emit("            cmd.Body");
                        }
                        else
                        {
                            AmqpFieldMappingAttribute fieldMapping =
                                Attribute(pi, typeof(AmqpFieldMappingAttribute)) as AmqpFieldMappingAttribute;
                            Emit("            __impl.m_" + (fieldMapping == null
                                                          ? pi.Name
                                                          : fieldMapping.m_fieldName));
                        }
                        remaining--;
                        if (remaining > 0)
                        {
                            EmitLine(",");
                        }
                    }
                    EmitLine(");");
                }
                else
                {
                    EmitLine("          " + method.Name + "();");
                }
                EmitLine("          return true;");
                EmitLine("        }");
            }
            EmitLine("        default: return false;");
            EmitLine("      }");
            EmitLine("    }");
        }
Exemplo n.º 14
0
        public void EmitModelMethod(MethodInfo method)
        {
            ParameterInfo[] parameters = method.GetParameters();

            AmqpClass  amqpClass  = null;
            AmqpMethod amqpMethod = null;

            LookupAmqpMethod(method, method.Name, out amqpClass, out amqpMethod);

            string requestImplClass = MangleMethodClass(amqpClass, amqpMethod);

            // At this point, we know which request method to
            // send. Now compute whether it's an RPC or not.

            AmqpMethod amqpReplyMethod = null;
            AmqpMethodMappingAttribute replyMapping =
                Attribute(method.ReturnTypeCustomAttributes, typeof(AmqpMethodMappingAttribute))
                as AmqpMethodMappingAttribute;

            if (Attribute(method, typeof(AmqpForceOneWayAttribute)) == null &&
                (amqpMethod.IsSimpleRpcRequest || replyMapping != null))
            {
                // We're not forcing oneway, and either are a simple
                // RPC request, or have an explicit replyMapping
                amqpReplyMethod = amqpClass.MethodNamed(replyMapping == null
                                                        ? (string)amqpMethod.m_ResponseMethods[0]
                                                        : replyMapping.m_methodName);
                if (amqpReplyMethod == null)
                {
                    throw new Exception("Could not find AMQP reply method for IModel method " + method.Name);
                }
            }

            // If amqpReplyMethod is null at this point, it's a
            // one-way operation, and no continuation needs to be
            // consed up. Otherwise, we should expect a reply of kind
            // identified by amqpReplyMethod - unless there's a nowait
            // parameter thrown into the equation!
            //
            // Examine the parameters to discover which might be
            // nowait, content header or content body.

            ParameterInfo nowaitParameter        = null;
            string        nowaitExpression       = "null";
            ParameterInfo contentHeaderParameter = null;
            ParameterInfo contentBodyParameter   = null;

            foreach (ParameterInfo pi in parameters)
            {
                AmqpNowaitArgumentAttribute nwAttr =
                    Attribute(pi, typeof(AmqpNowaitArgumentAttribute)) as AmqpNowaitArgumentAttribute;
                if (nwAttr != null)
                {
                    nowaitParameter = pi;
                    if (nwAttr.m_replacementExpression != null)
                    {
                        nowaitExpression = nwAttr.m_replacementExpression;
                    }
                }
                if (Attribute(pi, typeof(AmqpContentHeaderMappingAttribute)) != null)
                {
                    contentHeaderParameter = pi;
                }
                if (Attribute(pi, typeof(AmqpContentBodyMappingAttribute)) != null)
                {
                    contentBodyParameter = pi;
                }
            }

            // Compute expression text for the content header and body.

            string contentHeaderExpr =
                contentHeaderParameter == null
                ? "null"
                : " (" + MangleClass(amqpClass.Name) + "Properties) " + contentHeaderParameter.Name;
            string contentBodyExpr =
                contentBodyParameter == null ? "null" : contentBodyParameter.Name;

            // Emit the method declaration and preamble.

            EmitModelMethodPreamble(method);
            EmitLine("    {");

            // Emit the code to build the request.

            EmitLine("      " + requestImplClass + " __req = new " + requestImplClass + "();");
            foreach (ParameterInfo pi in parameters)
            {
                if (pi != contentHeaderParameter &&
                    pi != contentBodyParameter)
                {
                    if (Attribute(pi, typeof(AmqpUnsupportedAttribute)) != null)
                    {
                        EmitLine("      if (@" + pi.Name + " != null) {");
                        EmitLine("        throw new UnsupportedMethodFieldException(\"" + method.Name + "\",\"" + pi.Name + "\");");
                        EmitLine("      }");
                    }
                    else
                    {
                        AmqpFieldMappingAttribute fieldMapping =
                            Attribute(pi, typeof(AmqpFieldMappingAttribute)) as AmqpFieldMappingAttribute;
                        if (fieldMapping != null)
                        {
                            EmitLine("      __req.m_" + fieldMapping.m_fieldName + " = @" + pi.Name + ";");
                        }
                        else
                        {
                            EmitLine("      __req.m_" + pi.Name + " = @" + pi.Name + ";");
                        }
                    }
                }
            }

            // If we have a nowait parameter, sometimes that can turn
            // a ModelRpc call into a ModelSend call.

            if (nowaitParameter != null)
            {
                EmitLine("      if (" + nowaitParameter.Name + ") {");
                EmitLine("        ModelSend(__req," + contentHeaderExpr + "," + contentBodyExpr + ");");
                if (method.ReturnType != typeof(void))
                {
                    EmitLine("        return " + nowaitExpression + ";");
                }
                EmitLine("      }");
            }

            // At this point, perform either a ModelRpc or a
            // ModelSend.

            if (amqpReplyMethod == null)
            {
                EmitLine("      ModelSend(__req," + contentHeaderExpr + "," + contentBodyExpr + ");");
            }
            else
            {
                string replyImplClass = MangleMethodClass(amqpClass, amqpReplyMethod);

                EmitLine("      RabbitMQ.Client.Impl.MethodBase __repBase = ModelRpc(__req," + contentHeaderExpr + "," + contentBodyExpr + ");");
                EmitLine("      " + replyImplClass + " __rep = __repBase as " + replyImplClass + ";");
                EmitLine("      if (__rep == null) throw new UnexpectedMethodException(__repBase);");

                if (method.ReturnType == typeof(void))
                {
                    // No need to further examine the reply.
                }
                else
                {
                    // At this point, we have the reply method. Extract values from it.
                    AmqpFieldMappingAttribute returnMapping =
                        Attribute(method.ReturnTypeCustomAttributes, typeof(AmqpFieldMappingAttribute))
                        as AmqpFieldMappingAttribute;
                    if (returnMapping == null)
                    {
                        string fieldPrefix = IsAmqpClass(method.ReturnType) ? "m_" : "";

                        // No field mapping --> it's assumed to be a struct to fill in.
                        EmitLine("      " + method.ReturnType + " __result = new " + method.ReturnType + "();");
                        foreach (FieldInfo fi in method.ReturnType.GetFields())
                        {
                            AmqpFieldMappingAttribute returnFieldMapping =
                                Attribute(fi, typeof(AmqpFieldMappingAttribute)) as AmqpFieldMappingAttribute;
                            if (returnFieldMapping != null)
                            {
                                EmitLine("      __result." + fi.Name + " = __rep." + fieldPrefix + returnFieldMapping.m_fieldName + ";");
                            }
                            else
                            {
                                EmitLine("      __result." + fi.Name + " = __rep." + fieldPrefix + fi.Name + ";");
                            }
                        }
                        EmitLine("      return __result;");
                    }
                    else
                    {
                        // Field mapping --> return just the field we're interested in.
                        EmitLine("      return __rep.m_" + returnMapping.m_fieldName + ";");
                    }
                }
            }

            // All the IO and result-extraction has been done. Emit
            // the method postamble.

            EmitLine("    }");
        }