Example #1
0
        private static void RaiseValidationError(object sender, ValidationEventArgs args)
        {
            XmlSchemaException ex = args.Exception;

            MTurkLog.Error("XML validation error at line {1} position {2}: '{0}'", ex.Message, ex.LineNumber, ex.LinePosition);

            throw ex;
        }
Example #2
0
        public PropertyInfo GetProperty(string propName, bool throwOnError)
        {
            PropertyInfo ret = null;

            try
            {
                if (htPropertyCache.ContainsKey(propName))
                {
                    ret = htPropertyCache[propName];
                }
                else
                {
                    lock (syncToken)
                    {
                        if (htPropertyCache.ContainsKey(propName))
                        {
                            ret = htPropertyCache[propName];
                        }
                        else
                        {
                            // check only if the property is not yet on the exclude list
                            if (!excludeList.Contains(propName))
                            {
                                // look for public property;
                                ret = _type.GetProperty(propName);
                                if (ret == null)
                                {
                                    ret = _type.GetProperty(propName, BindingFlags.Instance | BindingFlags.NonPublic);
                                    if (ret == null)
                                    {
                                        if (throwOnError)
                                        {
                                            throw new ArgumentException("No such property for type " + _type.FullName, "propName");
                                        }
                                        else
                                        {
                                            // add to exclude list
                                            excludeList.Add(propName);
                                        }
                                    }
                                }
                                else
                                {
                                    htPropertyCache[propName] = ret;
                                }
                            }
                        }
                    }
                }
            }
            catch (ArgumentException ex)
            {
                MTurkLog.Warn("Cannot find property {0} for type {1}: {2}", propName, _type.FullName, ex.Message);
            }

            return(ret);
        }
Example #3
0
        /// <summary>
        /// Instantiates the client configuration by reading the application configuration file (app.config).
        /// </summary>
        /// <remarks>
        /// The following values are read from the application configuration file:
        /// <list type="bullet">
        /// <item>
        ///     <term>MechanicalTurk.ServiceEndpoint</term>
        ///     <description>
        ///     The service endpoint receiving and processing mturk requests. Defaults to the sandbox endpoint at
        ///     <c>https://mechanicalturk.sandbox.amazonaws.com?Service=AWSMechanicalTurkRequester</c>
        ///     </description>
        /// </item>
        /// <item>
        ///     <term>MechanicalTurk.AccessKeyId</term>
        ///     <description>Required: The access key ID for the Amazon Web Services account</description>
        /// </item>
        /// <item>
        ///     <term>MechanicalTurk.SecretAccessKey</term>
        ///     <description>Required: The secret access key for the Amazon Web Services account</description>
        /// </item>
        /// <item>
        ///     <term>MechanicalTurk.Log.Level</term>
        ///     <description>The log level for SDK log messages (<see cref="ILog"/> for details). Defaults to 2 (Info)</description>
        /// </item>
        /// <item>
        ///     <term>MechanicalTurk.Proxy.Url</term>
        ///     <description>
        ///     Proxy URL (only necessary when used through a web proxy that requires authentication)
        ///     </description>
        /// </item>
        /// <item>
        ///     <term>MechanicalTurk.Proxy.User</term>
        ///     <description>
        ///     User name for proxy credentials (only necessary when used through a web proxy that
        ///     requires authentication)
        ///     </description>
        /// </item>
        /// <item>
        ///     <term>MechanicalTurk.Proxy.Password</term>
        ///     <description>
        ///     Password for proxy credentials (only necessary when used through a web proxy
        ///     that requires authentication)
        ///     </description>
        /// </item>
        /// <item>
        ///     <term>MechanicalTurk.Proxy.Domain</term>
        ///     <description>
        ///     User domain for proxy credentials (only necessary when used through a web proxy
        ///     that requires authentication)
        ///     </description>
        /// </item>
        /// <item>
        ///     <term>MechanicalTurk.MiscOptions.EnsureQuestionsAreXmlWrapped</term>
        ///     <description>
        ///     If set to true (default), ensures that questions are wrapped as XML when sent to
        ///     Mechanical Turk.
        ///     </description>
        /// </item>
        /// <item>
        ///     <term>MechanicalTurk.MiscOptions.EnsureQuestionValidity</term>
        ///     <description>
        ///     If set to true (default is false), ensures that questions are validated before
        ///     they are sent to Mechanical Turk
        ///     </description>
        /// </item>
        /// </list>
        /// </remarks>
        public MTurkConfig()
        {
            string configFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;

            MTurkLog.Info("Loading config from " + configFile);
            if (!File.Exists(configFile))
            {
                throw new IOException(string.Format("Cannot find Mechanical turk configuration file at '{0}'", configFile));
            }
            Init();
        }
Example #4
0
        /// <summary>
        /// Constructs a Question XML String that contains a multiple freetext questions
        /// </summary>
        /// <param name="questions">The question phrase to ask</param>
        /// <returns>Question in XML format</returns>
        public static string ConvertMultipleFreeTextQuestionToXML(string[] questions)
        {
            if (questions == null || questions.Length == 0)
            {
                throw new ArgumentNullException("questions", "Empty or null question cannot be converted to XML");
            }

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            for (int i = 0; i < questions.Length; i++)
            {
                if (questions[i] != null && questions[i].Length > 0)
                {
                    sb.Append(string.Format(TPL_FREE_TEXT_QUESTION_SINGLE, i + 1, XmlUtil.XmlEncode(questions[i])));
                }
                else
                {
                    MTurkLog.Warn("Ignoring empty question at position {0}", i);
                }
            }

            return(string.Format(TPL_FREE_TEXT_QUESTION_FORM, sb.ToString()));
        }
Example #5
0
        private void Init()
        {
            // log level
            string logLevel = GetConfig("MechanicalTurk.Log.Level", "2");
            byte   level    = 2;

            if (!byte.TryParse(logLevel, out level))
            {
                MTurkLog.Warn("Invalid log level specified in configuration file ({0}). Defaulting to 'INFO'", logLevel);
            }
            MTurkLog.Level = level;

            // AWS settings
            string s = GetConfig("MechanicalTurk.ServiceEndpoint", null);

            if (string.IsNullOrEmpty(s))
            {
                this.ServiceEndpoint = "https://mechanicalturk.sandbox.amazonaws.com?Service=AWSMechanicalTurkRequester";
            }
            else
            {
                this.ServiceEndpoint = s;
            }

            AccessKeyId     = GetConfig("MechanicalTurk.AccessKeyId", null);
            SecretAccessKey = GetConfig("MechanicalTurk.SecretAccessKey", null);

            // Proxy settings when connecting through a proxy that requires authentication
            string proxyURL = GetConfig("MechanicalTurk.Proxy.Url", null);

            if (!string.IsNullOrEmpty(proxyURL))
            {
                Proxy = new WebProxy(proxyURL);
            }

            // set default credentials
            Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;

            string proxyUser     = GetConfig("MechanicalTurk.Proxy.User", null);
            string proxyPassword = GetConfig("MechanicalTurk.Proxy.Password", null);
            string proxyDomain   = GetConfig("MechanicalTurk.Proxy.Domain", null);

            if (!string.IsNullOrEmpty(proxyUser) && !string.IsNullOrEmpty(proxyPassword))
            {
                // override default credentials
                Proxy.Credentials = new NetworkCredential(proxyUser, proxyPassword, proxyDomain);
            }

            // worker website
            string url = GetConfig("MechanicalTurk.Url", null);

            if (url != null)
            {
                this.WebsiteURL = url;
            }
            else
            {
                if (this.ServiceEndpoint.ToLower().IndexOf("sandbox") != -1)
                {
                    this.WebsiteURL = "http://workersandbox.mturk.com";
                }
                else
                {
                    this.WebsiteURL = "http://www.mturk.com";
                }
            }

            // question settings: Implicitly wrap questions
            string wrap = GetConfig("MechanicalTurk.MiscOptions.EnsureQuestionsAreXmlWrapped", null);

            if (wrap != null)
            {
                this.EnsureQuestionsAreXmlWrappedBeforeSending = wrap.ToLower().Equals("true");
            }

            // question settings: Implicitly validate
            string validate = GetConfig("MechanicalTurk.MiscOptions.EnsureQuestionValidity", null);

            if (validate != null)
            {
                this.ValidateQuestionBeforeSending = validate.ToLower().Equals("true");
            }

            // retry delay for sandbox throttling
            MaxRetryDelay = int.Parse(GetConfig("MechanicalTurk.MaxRetryDelay", "8000"));

            MTurkLog.Info("Initialized configuration for '{0}'", this.ServiceEndpoint);
        }
Example #6
0
        /// <summary>
        /// Evaluates whether any optional properties in a request item have been set. If this
        /// is the case, then the correlating "Specified" property will be set to, otherwise
        /// the property does not get serialized in the soap request.
        ///
        /// See e.g. http://blogs.msdn.com/eugeneos/archive/2007/02/05/solving-the-disappearing-data-issue-when-using-add-web-reference-or-wsdl-exe-with-wcf-services.aspx
        /// for more details (using WCF is out of question for the API)
        /// </summary>
        /// <param name="request">Array of request items passed in an MTurk request
        /// (such as CreateItemRequest[])</param>
        public static void PreProcessOptionalRequestProperties(object request)
        {
            if (request != null)
            {
                Type requestType = request.GetType();

                if (requestType.IsArray)
                {
                    // caches the optional property to its "Specified" member (e.g. "PageSize->PageSizeSpecified")
                    Dictionary <PropertyInfo, PropertyInfo> htOptionalProps = null;

                    object[] requestItems   = request as object[];
                    Type     itemType       = null;
                    object   curRequestItem = null;

                    for (int i = 0; i < requestItems.Length; i++)
                    {
                        curRequestItem  = requestItems[i];
                        itemType        = curRequestItem.GetType();
                        htOptionalProps = GetCachedOptionalProperties(itemType);

                        // evaluate optional properties and set the "Specified" property to true,
                        // if the reference property was modified. From a client perspective, this
                        // alleviates the pain of setting the "Specified" properties to true explicitly
                        if (htOptionalProps.Count > 0)
                        {
                            PropertyInfo piSpecified  = null;
                            object       valRef       = null;
                            bool         valSpecified = false;
                            Type         propTypeRef  = null;
                            // flag indicating, whether the "xxxSpecified" property needs to be set
                            bool requiresSpecSet = false;
                            foreach (PropertyInfo piRef in htOptionalProps.Keys)
                            {
                                // check first, if it was explicitly set to true
                                valSpecified = false;
                                piSpecified  = htOptionalProps[piRef];
                                valSpecified = (bool)piSpecified.GetValue(curRequestItem, null);

                                if (!valSpecified)
                                {
                                    valRef = piRef.GetValue(curRequestItem, null);
                                    if (valRef != null)
                                    {
                                        // Generally, value types require to be explicitly set,
                                        // otherwise they can'typeOfTargetObject be set back to their default
                                        // values easily (e.g. setting a value back from "true" to "false")
                                        // The following code will set the "Specified" property to true
                                        // if the reference value is different from the default value
                                        // for the reference value type
                                        requiresSpecSet = false;

                                        propTypeRef = valRef.GetType();
                                        if (propTypeRef.IsValueType)
                                        {
                                            if (valRef is bool)
                                            {
                                                requiresSpecSet = (bool)valRef;
                                            }
                                            else if (valRef is DateTime)
                                            {
                                                requiresSpecSet = !DateTime.MinValue.Equals(valRef);
                                            }
                                            else if (propTypeRef.IsEnum)
                                            {
                                                requiresSpecSet =
                                                    !(valRef.Equals(Enum.GetValues(propTypeRef).GetValue(0)));
                                            }
                                            else
                                            {
                                                requiresSpecSet = !(Decimal.Parse(valRef.ToString(), System.Globalization.CultureInfo.InvariantCulture.NumberFormat).Equals(Decimal.Zero));
                                            }
                                        }
                                        else if (propTypeRef.IsArray)
                                        {
                                            requiresSpecSet = ((object[])valRef).Length > 0;
                                        }
                                        else if (propTypeRef.IsClass)
                                        {
                                            requiresSpecSet = true;
                                        }
                                        else
                                        {
                                            MTurkLog.Warn("Cannot preprocess optional property {0} for type {1} (No handler for property type {2}).",
                                                          piRef.Name,
                                                          itemType.FullName,
                                                          propTypeRef.FullName);
                                        }

                                        // set the "xxSpecified" property, so the referenced member gets soap serialized
                                        if (requiresSpecSet)
                                        {
                                            piSpecified.SetValue(curRequestItem, true, null);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Example #7
0
        /// <summary>
        /// Sets the property path value. If one of the properties in the path is null, a new instance for its type is created.
        /// </summary>
        /// <param name="objRoot">The root object for the path. Needs to be of the cached type</param>
        /// <param name="propertyPath">The property path (e.g. "LocaleValue.Country")</param>
        /// <param name="newValueForProperty">New value for the last property in the path</param>
        public void SetPropertyPathValue(object objRoot, string propertyPath, object newValueForProperty)
        {
            Type         curType = null;
            PropertyInfo pi      = null;

            PropertyInfo[] resolvedPath = GetPropertyPath(propertyPath);
            object         curParent    = objRoot;
            object         cur          = objRoot;

            for (int i = 0; i < resolvedPath.Length - 1; i++)
            {
                curParent = cur;
                pi        = resolvedPath[i];
                curType   = pi.PropertyType;
                cur       = pi.GetValue(cur, null);

                if (cur == null)
                {
                    if (curType.IsClass || curType.IsValueType)
                    {
                        // Create a new instance (requires default constructor)
                        ConstructorInfo ctor = curType.GetConstructor(EMPTY_PARAMS);
                        if (ctor == null)
                        {
                            throw new InvalidOperationException(string.Format("Cannot execute property resolvedPath '{0}'. No default constructor found for type '{1}'", propertyPath, curType.FullName));
                        }
                        else
                        {
                            // create a new instance and set it on the curParent
                            cur = ctor.Invoke(null);

                            ReflectionUtil.SetPropertyValue(pi.Name, curParent, cur);
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException(string.Format("Cannot execute property resolvedPath '{0}'. Property '{1}' is neither class nor value type", propertyPath, pi.Name));
                    }
                }
            }

            // now set the value for the last element of the resolvedPath
            pi      = resolvedPath[resolvedPath.Length - 1];
            curType = pi.PropertyType;
            if (newValueForProperty != null)
            {
                if (!curType.Equals(newValueForProperty.GetType()))
                {
                    // check if it is nullable and use underlying typ
                    if (curType.IsGenericType && curType.GetGenericTypeDefinition() == typeof(Nullable <>))
                    {
                        curType = Nullable.GetUnderlyingType(curType);
                    }

                    if (curType.IsEnum)
                    {
                        newValueForProperty = Enum.Parse(curType, newValueForProperty.ToString(), true);
                    }
                    else
                    {
                        TypeConverter tc = TypeDescriptor.GetConverter(newValueForProperty.GetType());
                        if (tc.CanConvertTo(curType))
                        {
                            newValueForProperty = tc.ConvertTo(newValueForProperty, curType);
                        }
                        else
                        {
                            // no builtin converter found: let's look if we have a static Parse method for this type)
                            MethodInfo mi = curType.GetMethod("Parse", new Type[] { newValueForProperty.GetType() });
                            if (mi != null)
                            {
                                object[] param = { newValueForProperty };
                                newValueForProperty = mi.Invoke(null, param);
                            }
                            else
                            {
                                MTurkLog.Warn("No type conversion/parser found for {0}. Defaulting to {1} ({2})", pi.Name, newValueForProperty, newValueForProperty.GetType().Name);
                            }
                        }
                    }
                }
            }

            pi.SetValue(cur, newValueForProperty, null);
        }