Beispiel #1
0
        protected override void UpdateValueCache()
        {
            if (valueCache == null) // Once is OK
            {
                var lst = Object.GetPropertyValue <INotifyCollectionChanged>(Property.Name);
                lst.CollectionChanged += ValueCollectionChanged;

                underlyingCollectionCache = (IEnumerable)lst;

                valueCache = MagicCollectionFactory.WrapAsList <ICompoundObject>(lst);
            }
        }
Beispiel #2
0
 //// Helper method which is only called by reflection from GetCollectionEntries
 private IEnumerable <IRelationEntry> GetCollectionEntriesInternal <IMPL>(TParent parent, Relation rel, RelationEndRole endRole)
     where IMPL : BaseMemoryPersistenceObject
 {
     return(MagicCollectionFactory.WrapAsCollection <IRelationEntry>(parent.GetPrivatePropertyValue <object>(rel.GetEndFromRole(endRole).Navigator.Name)).ToList());
 }
Beispiel #3
0
        /// <summary>
        /// Exports data from the specified context into the specified package provider. Data is selected by defining
        /// schema and owning module.
        /// </summary>
        /// <remarks>
        /// <para>For example, exporting {"ZetboxBase", "GUI"}/{"*"} will export all schema information to recreate the
        /// current database. Exporting {"Calendar"}/{"MyApplication"} will export all calendar data specific to the
        /// "MyApplication" module.
        /// </para>
        /// </remarks>
        /// <param name="ctx">The data source</param>
        /// <param name="s">The export target</param>
        /// <param name="schemaModules">A list of strings naming the schema-defining modules. This selects which data
        /// (-classes) should be exported. Specify a single asterisk (<code>"*"</code>) to select all available
        /// modules.</param>
        /// <param name="ownerModules">A list of strings naming the data-owning modules. This selects whose data should
        /// be exported.  Specify a single asterisk (<code>"*"</code>) to select all available data, independent of
        /// module-membership. This also includes data that is not member of any module.</param>
        public static void ExportFromContext(IReadOnlyZetboxContext ctx, IPackageProvider s, string[] schemaModules, string[] ownerModules)
        {
            using (Log.DebugTraceMethodCall("ExportFromContext"))
            {
                Log.InfoFormat("Starting Export for Modules [{0}], data owned by [{1}]", string.Join(", ", schemaModules), string.Join(", ", ownerModules));

                var allData = ownerModules.Contains("*");

                var schemaList       = GetModules(ctx, schemaModules);
                var schemaNamespaces = schemaList.Select(m => m.Namespace).ToArray();

                WriteStartDocument(s, ctx, schemaList);

                var iexpIf = ctx.GetIExportableInterface();
                foreach (var module in schemaList)
                {
                    Log.InfoFormat("  exporting module {0}", module.Name);
                    foreach (var objClass in ctx.GetQuery <ObjectClass>().Where(o => o.Module == module).OrderBy(o => o.Name).ToList())
                    {
                        if (objClass.SubClasses.Count > 0)
                        {
                            Log.DebugFormat("    skipping {0}: not a leaf class", objClass.Name);
                        }
                        else if (!objClass.AndParents(cls => new[] { cls }, cls => cls.BaseObjectClass).SelectMany(cls => cls.ImplementsInterfaces).Contains(iexpIf))
                        {
                            Log.DebugFormat("    skipping {0}: not exportable", objClass.Name);
                        }
                        else if (allData)
                        {
                            Log.InfoFormat("    exporting class {0}", objClass.Name);
                            foreach (var obj in ctx.Internals().GetAll(objClass.GetDescribedInterfaceType()).OrderBy(obj => ((IExportable)obj).ExportGuid))
                            {
                                ExportObject(s, obj, schemaNamespaces);
                            }
                        }
                        else if (objClass.ImplementsIModuleMember())
                        {
                            Log.InfoFormat("    exporting parts of class {0}", objClass.Name);
                            foreach (var obj in ctx.Internals().GetAll(objClass.GetDescribedInterfaceType())
                                     .Cast <IModuleMember>()
                                     .Where(mm => mm.Module != null && ownerModules.Contains(mm.Module.Name))
                                     .Cast <IExportable>()
                                     .OrderBy(obj => obj.ExportGuid)
                                     .Cast <IPersistenceObject>())
                            {
                                ExportObject(s, obj, schemaNamespaces);
                            }
                        }
                        else
                        {
                            Log.DebugFormat("    skipping {0}", objClass.Name);
                        }
                    }

                    int moduleID = module.ID; // Dont ask
                    foreach (var rel in ctx.GetQuery <Relation>().Where(r => r.Module.ID == moduleID)
                             .OrderBy(r => r.A.Type.Name).ThenBy(r => r.A.RoleName).ThenBy(r => r.B.Type.Name).ThenBy(r => r.B.RoleName).ThenBy(r => r.ExportGuid))
                    {
                        if (rel.GetRelationType() != RelationType.n_m)
                        {
                            continue;
                        }
                        if (!rel.A.Type.ImplementsIExportable())
                        {
                            continue;
                        }
                        if (!rel.B.Type.ImplementsIExportable())
                        {
                            continue;
                        }

                        try
                        {
                            var ifType = rel.GetEntryInterfaceType();
                            Log.InfoFormat("    {0} ", ifType.Type.Name);

                            MethodInfo mi        = ctx.GetType().FindGenericMethod("FetchRelation", new Type[] { ifType.Type }, new Type[] { typeof(Guid), typeof(RelationEndRole), typeof(IDataObject) });
                            var        relations = MagicCollectionFactory.WrapAsCollection <IPersistenceObject>(mi.Invoke(ctx, new object[] { rel.ExportGuid, RelationEndRole.A, null }));

                            foreach (var obj in relations.OrderBy(obj => ((IExportable)obj).ExportGuid))
                            {
                                ExportObject(s, obj, schemaNamespaces);
                            }
                        }
                        catch (TypeLoadException ex)
                        {
                            var message = String.Format("Failed to load InterfaceType for entries of {0}", rel);
                            Log.Warn(message, ex);
                        }
                    }
                }
                s.Writer.WriteEndElement();
                s.Writer.WriteEndDocument();

                Log.Info("Export finished");
            }
        }