/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Reflection; using System.Collections.Concurrent; using Avro; namespace Avro.Reflect { /// /// Collection of DotNetProperty objects to repre /// public class DotnetClass { private ConcurrentDictionary _propertyMap = new ConcurrentDictionary(); private Type _type; /// /// Constructor /// /// type of the class /// record schema /// class cache - can be reused public DotnetClass(Type t, RecordSchema r, ClassCache cache) { _type = t; foreach (var f in r.Fields) { bool hasAttribute = false; PropertyInfo prop = GetPropertyInfo(f); foreach (var attr in prop.GetCustomAttributes(true)) { var avroAttr = attr as AvroFieldAttribute; if (avroAttr != null) { hasAttribute = true; _propertyMap.TryAdd(f.Name, new DotnetProperty(prop, f.Schema.Tag, avroAttr.Converter, cache)); break; } } if (!hasAttribute) { _propertyMap.TryAdd(f.Name, new DotnetProperty(prop, f.Schema.Tag, cache)); } } } private PropertyInfo GetPropertyInfo(Field f) { var prop = _type.GetProperty(f.Name); if (prop != null) { return prop; } foreach (var p in _type.GetProperties()) { foreach (var attr in p.GetCustomAttributes(true)) { var avroAttr = attr as AvroFieldAttribute; if (avroAttr != null && avroAttr.FieldName != null && avroAttr.FieldName == f.Name) { return p; } } } throw new AvroException($"Class {_type.Name} doesnt contain property {f.Name}"); } /// /// Return the value of a property from an object referenced by a field /// /// the object /// FieldSchema used to look up the property /// public object GetValue(object o, Field f) { DotnetProperty p; if (!_propertyMap.TryGetValue(f.Name, out p)) { throw new AvroException($"ByPosClass doesnt contain property {f.Name}"); } return p.GetValue(o, f.Schema); } /// /// Set the value of a property in a C# object /// /// the object /// field schema /// value for the proprty referenced by the field schema public void SetValue(object o, Field f, object v) { DotnetProperty p; if (!_propertyMap.TryGetValue(f.Name, out p)) { throw new AvroException($"ByPosClass doesnt contain property {f.Name}"); } p.SetValue(o, v, f.Schema); } /// /// Return the type of the Class /// /// The public Type GetClassType() { return _type; } /// /// Return the type of a property referenced by a field /// /// /// public Type GetPropertyType(Field f) { DotnetProperty p; if (!_propertyMap.TryGetValue(f.Name, out p)) { throw new AvroException($"ByPosClass doesnt contain property {f.Name}"); } return p.GetPropertyType(); } } }