Пример #1
0
        protected object RawGetObjectProperty(StringTemplate self, object o, string propertyName)
        {
            Type c = o.GetType();
            object val = null;

            // Special case: our automatically created Aggregates via
            // attribute name: "{obj.{prop1,prop2}}"
            if (c == typeof(StringTemplate.Aggregate))
            {
                val = ((StringTemplate.Aggregate) o).Get(propertyName);
                return val;
            }
                // Special case: if it's a template, pull property from
                // it's attribute table.
                // TODO: TJP just asked himself why we can't do inherited attr here?
            else if (c == typeof(StringTemplate))
            {
                IDictionary attributes = ((StringTemplate) o).Attributes;
                if (attributes != null)
                {
                    val = attributes[propertyName];
                    return val;
                }
            }

            // Special case: if it's an IDictionary then pull using
            // key not the property method.
            //
            // Original intent was to DISALLOW general IDictionary interface
            // as people could pass in their database masquerading as a IDictionary.
            // Pragmatism won out ;-)
            if (typeof(IDictionary).IsAssignableFrom(c))
            {
                IDictionary map = (IDictionary) o;
                if (propertyName.Equals("keys"))
                {
                    val = map.Keys;
                }
                else if (propertyName.Equals("values"))
                {
                    val = map.Values;
                }
                else if (map.Contains(propertyName))
                {
                    val = map[propertyName];
                }
                else
                {
                    if ( map.Contains(DEFAULT_MAP_VALUE_NAME) )
                        val = map[DEFAULT_MAP_VALUE_NAME];
                }
                if (val == MAP_KEY_VALUE)
                {
                    // no property defined; if a map in this group
                    // then there may be a default value
                    val = propertyName;
                }
                return val;
            }

            // try getXXX and isXXX properties

            // check cache
            PropertyLookupParams paramBag;
            //MemberInfo cachedMember = self.Group.GetCachedClassProperty(c, propertyName);
            //if ( cachedMember != null )
            //{
            //    try
            //    {
            //        paramBag = new PropertyLookupParams(self, c, o, propertyName, null);
            //        if ( cachedMember is PropertyInfo )
            //        {
            //            // non-indexed property (since we don't cache indexers)
            //            PropertyInfo pi = (PropertyInfo)cachedMember;
            //            GetPropertyValue(pi, paramBag, ref val);
            //        }
            //        else if ( cachedMember is MethodInfo )
            //        {
            //            MethodInfo mi = (MethodInfo)cachedMember;
            //            GetMethodValue(mi, paramBag, ref val);
            //        }
            //        else if ( cachedMember is FieldInfo )
            //        {
            //            // must be a field
            //            FieldInfo fi = (FieldInfo)cachedMember;
            //            GetFieldValue(fi, paramBag, ref val);
            //        }
            //    }
            //    catch (Exception e)
            //    {
            //        self.Error("Can't get property '" + propertyName +
            //            "' from '" + c.FullName + "' instance", e);
            //    }
            //    return val;
            //}

            // must look up using reflection
            // Search for propertyName as:
            //   Property (non-indexed), Method(get_XXX, GetXXX, IsXXX, getXXX, isXXX), Field, this[string]
            string methodSuffix = Char.ToUpper(propertyName[0]) + propertyName.Substring(1);
            paramBag = new PropertyLookupParams(self, c, o, propertyName, methodSuffix);
            totalReflectionLookups++;
            if (!GetPropertyValueByName(paramBag, ref val))
            {
                bool found = false;
                foreach (string prefix in new string[] { "get_", "Get", "Is", "get", "is" })
                {
                    paramBag.lookupName = prefix + methodSuffix;
                    totalReflectionLookups++;
                    if (found = GetMethodValueByName(paramBag, ref val))
                        break;
                }

                if (!found)
                {
                    paramBag.lookupName = methodSuffix;
                    totalReflectionLookups++;
                    if (!GetFieldValueByName(paramBag, ref val))
                    {
                        totalReflectionLookups++;
                        PropertyInfo pi = c.GetProperty("Item", new Type[] { typeof(string) });
                        if (pi != null)
                        {
                            // TODO: we don't cache indexer PropertyInfo objects (yet?)
                            // it would have complicated getting values from cached property objects
                            try
                            {
                                val = pi.GetValue(o, new object[] { propertyName });
                            }
                            catch(Exception ex)
                            {
                                self.Error("Can't get property " + propertyName + " via C# string indexer from " + c.FullName + " instance", ex);
                            }
                        }
                        else
                        {
                            self.Error("Class " + c.FullName + " has no such attribute: " + propertyName + " in template context " + self.GetEnclosingInstanceStackString());
                        }
                    }
                }
            }

            return val;
        }
Пример #2
0
        private bool GetPropertyValueByName(PropertyLookupParams paramBag, ref object val)
        {
            PropertyInfo pi = null;
            try
            {
                pi = paramBag.prototype.GetProperty(
                    paramBag.lookupName,
                    BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.IgnoreCase,
                    null,
                    null,
                    Type.EmptyTypes,
                    null
                    );

                if (pi != null)
                {
                    if (pi.CanRead)
                    {
                        // save to avoid [another expensive] lookup later
                        //paramBag.self.Group.CacheClassProperty(paramBag.prototype, paramBag.propertyName, pi);
                        return GetPropertyValue(pi, paramBag, ref val);
                    }
                    else
                    {
                        paramBag.self.Error("Class " + paramBag.prototype.FullName + " property: "
                            + paramBag.lookupName + " is write-only in template context "
                            + paramBag.self.GetEnclosingInstanceStackString());
                    }
                }
            }
            catch(Exception)
            {
                ;
            }
            return false;
        }
Пример #3
0
 private bool GetPropertyValue(PropertyInfo pi, PropertyLookupParams paramBag, ref object @value)
 {
     try
     {
         @value = pi.GetValue(paramBag.instance, (object[]) null);
         return true;
     }
     catch(Exception ex)
     {
         paramBag.self.Error("Can't get property " + paramBag.propertyName
             + " as CLR property " + pi.Name + " from "
             + paramBag.prototype.FullName + " instance", ex);
     }
     return false;
 }
Пример #4
0
        private bool GetMethodValueByName(PropertyLookupParams paramBag, ref object val)
        {
            MethodInfo mi = null;
            try
            {
                mi = paramBag.prototype.GetMethod(
                    paramBag.lookupName,
                    BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.IgnoreCase,
                    null,
                    Type.EmptyTypes,
                    null
                    );

                if (mi != null)
                {
                    // save to avoid [another expensive] lookup later
                    //paramBag.self.Group.CacheClassProperty(paramBag.prototype, paramBag.propertyName, mi);
                    return GetMethodValue(mi, paramBag, ref val);
                }
            }
            catch(Exception)
            {
                ;
            }
            return false;
        }
Пример #5
0
 private bool GetMethodValue(MethodInfo mi, PropertyLookupParams paramBag, ref object @value)
 {
     try
     {
         @value = mi.Invoke(paramBag.instance, (object[]) null);
         return true;
     }
     catch (Exception ex)
     {
         paramBag.self.Error("Can't get property " + paramBag.lookupName
             + " using method get_/Get/Is/get/is as " + mi.Name + " from "
             + paramBag.prototype.FullName + " instance", ex);
     }
     return false;
 }
Пример #6
0
 private bool GetFieldValue(FieldInfo fi, PropertyLookupParams paramBag, ref object @value)
 {
     try
     {
         @value = fi.GetValue(paramBag.instance);
         return true;
     }
     catch(Exception ex)
     {
         paramBag.self.Error("Can't get property " + fi.Name
             + " using direct field access from " + paramBag.prototype.FullName
             + " instance", ex
             );
     }
     return false;
 }