#region MigraDoc - Creating Documents on the Fly // // Authors: // Stefan Lange // Klaus Potzesny // David Stephensen // // Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany) // // http://www.pdfsharp.com // http://www.migradoc.com // http://sourceforge.net/projects/pdfsharp // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. #endregion using System; using System.Reflection; namespace MigraDoc.DocumentObjectModel.publics { /// /// Meta class for document objects. /// public sealed class Meta { /// /// Initializes a new instance of the DomMeta class. /// public Meta(Type documentObjectType) { AddValueDescriptors(this, documentObjectType); } /// /// Gets the meta object of the specified document object. /// /// The document object the meta is returned for. public static Meta GetMeta(DocumentObject documentObject) { return documentObject.Meta; } /// /// Gets the object specified by name from dom. /// public object GetValue(DocumentObject dom, string name, GV flags) { int dot = name.IndexOf('.'); if (dot == 0) throw new ArgumentException(DomSR.InvalidValueName(name)); string trail = null; if (dot > 0) { trail = name.Substring(dot + 1); name = name.Substring(0, dot); } ValueDescriptor vd = _vds[name]; if (vd == null) throw new ArgumentException(DomSR.InvalidValueName(name)); object value = vd.GetValue(dom, flags); if (value == null && flags == GV.GetNull) //??? also for GV.ReadOnly? return null; //REVIEW DaSt: Create object in case of GV.ReadWrite? if (trail != null) { if (value == null || trail == "") throw new ArgumentException(DomSR.InvalidValueName(name)); DocumentObject doc = value as DocumentObject; if (doc == null) throw new ArgumentException(DomSR.InvalidValueName(name)); value = doc.GetValue(trail, flags); } return value; } /// /// Sets the member of dom specified by name to val. /// If a member with the specified name does not exist an ArgumentException will be thrown. /// public void SetValue(DocumentObject dom, string name, object val) { int dot = name.IndexOf('.'); if (dot == 0) throw new ArgumentException(DomSR.InvalidValueName(name)); string trail = null; if (dot > 0) { trail = name.Substring(dot + 1); name = name.Substring(0, dot); } ValueDescriptor vd = _vds[name]; if (vd == null) throw new ArgumentException(DomSR.InvalidValueName(name)); if (trail != null) { //REVIEW DaSt: dom.GetValue(name) and call SetValue recursively, // or dom.GetValue(name.BisVorletzteElement) and then call SetValue? DocumentObject doc = (DocumentObject)dom.GetValue(name); doc.SetValue(trail, val); } else vd.SetValue(dom, val); } /// /// Determines whether this meta contains a value with the specified name. /// public bool HasValue(string name) { ValueDescriptor vd = _vds[name]; return vd != null; } /// /// Sets the member of dom specified by name to null. /// If a member with the specified name does not exist an ArgumentException will be thrown. /// public void SetNull(DocumentObject dom, string name) { ValueDescriptor vd = _vds[name]; if (vd == null) throw new ArgumentException(DomSR.InvalidValueName(name)); vd.SetNull(dom); } /// /// Determines whether the member of dom specified by name is null. /// If a member with the specified name does not exist an ArgumentException will be thrown. /// public /* not virtual */ bool IsNull(DocumentObject dom, string name) { //bool isNull = false; int dot = name.IndexOf('.'); if (dot == 0) throw new ArgumentException(DomSR.InvalidValueName(name)); string trail = null; if (dot > 0) { trail = name.Substring(dot + 1); name = name.Substring(0, dot); } ValueDescriptor vd = _vds[name]; if (vd == null) throw new ArgumentException(DomSR.InvalidValueName(name)); if (vd is NullableDescriptor || vd is ValueTypeDescriptor) { if (trail != null) throw new ArgumentException(DomSR.InvalidValueName(name)); return vd.IsNull(dom); } DocumentObject docObj = (DocumentObject)vd.GetValue(dom, GV.ReadOnly); if (docObj == null) return true; if (trail != null) return docObj.IsNull(trail); return docObj.IsNull(); // DomValueDescriptor vd = vds[name]; // if (vd == null) // throw new ArgumentException(DomSR.InvalidValueName(name)); // // return vd.IsNull(dom); } /// /// Sets all members of the specified dom to null. /// public /*virtual*/ void SetNull(DocumentObject dom) { int count = _vds.Count; for (int index = 0; index < count; index++) { if (!_vds[index].IsRefOnly) _vds[index].SetNull(dom); } } /// /// Determines whether all members of the specified dom are null. If dom contains no members IsNull /// returns true. /// public bool IsNull(DocumentObject dom) { int count = _vds.Count; for (int index = 0; index < count; index++) { ValueDescriptor vd = _vds[index]; if (vd.IsRefOnly) continue; if (!vd.IsNull(dom)) return false; } return true; } /// /// Gets the DomValueDescriptor of the member specified by name from the DocumentObject. /// public ValueDescriptor this[string name] { get { return _vds[name]; } } /// /// Gets the DomValueDescriptorCollection of the DocumentObject. /// public ValueDescriptorCollection ValueDescriptors { get { return _vds; } } readonly ValueDescriptorCollection _vds = new ValueDescriptorCollection(); /// /// Adds a value descriptor for each field and property found in type to meta. /// static void AddValueDescriptors(Meta meta, Type type) { #if !NETFX_CORE FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); #else var fieldInfos = type.GetTypeInfo().DeclaredFields; #endif foreach (FieldInfo fieldInfo in fieldInfos) { #if DEBUG_ string name = fieldInfo.Name; if (name == "parent") name.GetType(); #endif DVAttribute[] dvs = (DVAttribute[])fieldInfo.GetCustomAttributes(typeof(DVAttribute), false); if (dvs.Length == 1) { ValueDescriptor vd = ValueDescriptor.CreateValueDescriptor(fieldInfo, dvs[0]); meta.ValueDescriptors.Add(vd); } } #if !NETFX_CORE PropertyInfo[] propInfos = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); #else var propInfos = type.GetTypeInfo().DeclaredProperties; #endif foreach (PropertyInfo propInfo in propInfos) { #if DEBUG_ string name = propInfo.Name; if (name == "Font") name.GetType(); #endif DVAttribute[] dvs = (DVAttribute[])propInfo.GetCustomAttributes(typeof(DVAttribute), false); if (dvs.Length == 1) { ValueDescriptor vd = ValueDescriptor.CreateValueDescriptor(propInfo, dvs[0]); meta.ValueDescriptors.Add(vd); } } } } }