Beispiel #1
0
        private void CheckSharePointRuntimeVersion()
        {
            // Require minimum SP2013 SP1 which is 15.0.4569.1000
            // We need 15.0.4569.1000 as this allows to create content types with particular ID
            // If current assembly version is lover than 15.0.4569.1000, then we gonna have missing field exception on ContentTypeCreationInformation.Id
            // http://blogs.technet.com/b/steve_chen/archive/2013/03/26/3561010.aspx
            var minimalVersion = new Version("15.0.4569.1000");

            var spAssembly            = typeof(Field).Assembly;
            var spAssemblyFileVersion = FileVersionInfo.GetVersionInfo(spAssembly.Location);

            var versionInfo = new Version(spAssemblyFileVersion.ProductVersion);

            TraceService.InformationFormat((int)LogEventId.ModelProcessing,
                                           "CSOM - CheckSharePointRuntimeVersion. Required minimal version :[{0}]. Current version: [{1}] Location: [{2}]",
                                           new object[]
            {
                minimalVersion,
                spAssemblyFileVersion,
                spAssemblyFileVersion.ProductVersion
            });

            if (versionInfo < minimalVersion)
            {
                TraceService.Error((int)LogEventId.ModelProcessing, "CSOM - CheckSharePointRuntimeVersion failed. Throwing SPMeta2NotSupportedException");

                var exceptionMessage = string.Empty;

                exceptionMessage += string.Format("SPMeta2.CSOM.dll requires at least SP2013 SP1 runtime ({0}).{1}", minimalVersion, Environment.NewLine);
                exceptionMessage += string.Format(" Current Microsoft.SharePoint.Client.dll version:[{0}].{1}", spAssemblyFileVersion.ProductVersion, Environment.NewLine);
                exceptionMessage += string.Format(" Current Microsoft.SharePoint.Client.dll location:[{0}].{1}", spAssembly.Location, Environment.NewLine);

                throw new SPMeta2NotSupportedException(exceptionMessage);
            }
        }
Beispiel #2
0
        // AutoDetectSharePointPersistenceStorage

        protected virtual List <PersistenceStorageServiceBase> ResolvePersistenceStorages(object modelHost, ModelNode modelNode)
        {
            if (Configuration == null)
            {
                return(new List <PersistenceStorageServiceBase>());
            }

            if (Configuration.AutoDetectSharePointPersistenceStorage)
            {
                var rootModelNodeType = modelNode.Value.GetType();

                TraceService.InformationFormat(0, "Detecting SharePoint persistence storage implementation for root definitin type:[{0}]", rootModelNodeType);

                var currentStorageServices = ServiceContainer.Instance.GetServices <SharePointPersistenceStorageServiceBase>();
                SharePointPersistenceStorageServiceBase targetService = null;

                var typedModelHost = modelHost.WithAssertAndCast <ModelHostBase>("modelHost", v => v.RequireNotNull());

                foreach (var service in currentStorageServices)
                {
                    if (service.TargetDefinitionTypes.Contains(rootModelNodeType))
                    {
                        var serviceTypeName = service.GetType().Name;

                        // cause it could be multiple service registrations here by both CSOM and SSOM
                        // we need to know the context coming from the top and then resolve correct service for the API
                        if (typedModelHost.IsSSOM && serviceTypeName.Contains("SSOM"))
                        {
                            targetService = service;
                            break;
                        }

                        if (typedModelHost.IsCSOM && serviceTypeName.Contains("CSOM"))
                        {
                            targetService = service;
                            break;
                        }
                    }
                }

                if (targetService == null)
                {
                    throw new SPMeta2Exception(
                              string.Format("Coudn't find SharePoint persistence storage implementation for root definitin type:[{0}]",
                                            rootModelNodeType));
                }

                TraceService.InformationFormat(0, "Initialilize persistence storage [{0}] with model host", targetService.GetType());
                targetService.InitialiseFromModelHost(modelHost);

                TraceService.Information(0, "Returning persistence storage implementation");

                var result = new List <PersistenceStorageServiceBase>();

                result.Add(targetService);
                return(result);
            }

            return(Configuration.PersistenceStorages);
        }
Beispiel #3
0
        public void RegisterModelHandler(ModelHandlerBase modelHandlerType)
        {
            TraceService.InformationFormat((int)LogEventId.CoreCalls,
                                           "RegisterModelHandler of type:[{0}] for target type:[{1}]",
                                           new object[]
            {
                modelHandlerType.GetType(),
                modelHandlerType.TargetType
            });

            if (!ModelHandlers.ContainsKey(modelHandlerType.TargetType))
            {
                TraceService.VerboseFormat((int)LogEventId.CoreCalls,
                                           "Model handler for type [{0}] has not been registered yet. Registering.",
                                           new object[] { modelHandlerType.GetType() });

                ModelHandlers.Add(modelHandlerType.TargetType, modelHandlerType);
            }
            else
            {
                TraceService.VerboseFormat((int)LogEventId.CoreCalls,
                                           "Model handler for type [{0}] has been registered. Skipping.",
                                           new object[] { modelHandlerType.GetType() });
            }
        }
        protected virtual void CheckCSOMRuntimeVersion()
        {
            // Require minimum SP2013 SP1 which is 15.0.4569.1000
            // We need 15.0.4569.1000 as this allows to create content types with particular ID
            // If current assembly version is lover than 15.0.4569.1000, then we gonna have missing field exception on ContentTypeCreationInformation.Id
            // http://blogs.technet.com/b/steve_chen/archive/2013/03/26/3561010.aspx

            var spAssembly  = GetCSOMRuntimeAssembly();
            var versionInfo = GetCSOMRuntimeVersion();

            var assemblyLocation = string.Empty;

            // RequireCSOMRuntimeVersionDeploymentService does not work under Azure Funtions #962
            // https://github.com/SubPointSolutions/spmeta2/issues/962
            try
            {
                assemblyLocation = spAssembly.Location;
            }
            catch (Exception assemblyLocationLoadException)
            {
                assemblyLocation = string.Format("Coudn't load .Location property. Exception was:[{0}]", assemblyLocationLoadException);
            }

            TraceService.InformationFormat((int)LogEventId.ModelProcessing,
                                           "CSOM - CheckSharePointRuntimeVersion. Required minimal version :[{0}]. Current version: [{1}] Location: [{2}]",
                                           new object[]
            {
                MinimalVersion,
                versionInfo,
                assemblyLocation
            });

            if (versionInfo.Major == 14)
            {
                // TODO, SP2010 check later
            }
            else if (versionInfo.Major == 15)
            {
                if (versionInfo < SP2013MinimalVersion)
                {
                    TraceService.Error((int)LogEventId.ModelProcessing, "CSOM - CheckSharePointRuntimeVersion failed. Throwing SPMeta2NotSupportedException");

                    var exceptionMessage = string.Empty;

                    exceptionMessage += string.Format("SPMeta2.CSOM.dll requires at least SP2013 SP1 runtime ({0}).{1}", MinimalVersion, Environment.NewLine);
                    exceptionMessage += string.Format(" Current Microsoft.SharePoint.Client.dll version:[{0}].{1}", versionInfo.Major, Environment.NewLine);
                    exceptionMessage += string.Format(" Current Microsoft.SharePoint.Client.dll location:[{0}].{1}", assemblyLocation, Environment.NewLine);

                    throw new SPMeta2NotSupportedException(exceptionMessage);
                }
            }
            else if (versionInfo.Major == 16)
            {
                // TODO, SP2016 check later
            }
        }
Beispiel #5
0
        protected Web GetExistingWeb(Site site, Web parentWeb, string currentWebUrl)
        {
            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Entering GetExistingWeb()");

            var result = false;
            var srcUrl = currentWebUrl.ToLower().Trim('/').Trim('\\');

            // for self-hosting and '/'
            if (parentWeb.Url.ToLower().Trim('/').Trim('\\').EndsWith(srcUrl))
            {
                return(parentWeb);
            }

            var context = parentWeb.Context;

            Web web = null;

            var scope = new ExceptionHandlingScope(context);

            using (scope.StartScope())
            {
                using (scope.StartTry())
                {
                    web = site.OpenWeb(currentWebUrl);
                }

                using (scope.StartCatch())
                {
                }
            }

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "ExecuteQuery()");
            context.ExecuteQueryWithTrace();

            if (!scope.HasException && web != null && web.ServerObjectIsNull == false)
            {
                TraceService.InformationFormat((int)LogEventId.ModelProvisionCoreCall, "Found web with URL: [{0}]", currentWebUrl);

                context.Load(web);

                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "ExecuteQuery()");
                context.ExecuteQueryWithTrace();

                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Exciting GetExistingWeb()");

                return(web);
            }

            TraceService.InformationFormat((int)LogEventId.ModelProvisionCoreCall, "Can't find web with URL: [{0}]. Returning NULL.", currentWebUrl);
            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Exciting GetExistingWeb()");

            return(null);
        }
        protected ContentType FindListContentType(List list, ContentTypeLinkDefinition contentTypeLinkModel)
        {
            ContentType result = null;

            // TODO
            // https://github.com/SubPointSolutions/spmeta2/issues/68

            // if content type name was not provided, this fails
            // should be re-done by ID and Name
            // OOTB content types could be binded by ID, and custom content types might be binded by name


            // trying to find by name
            if (!string.IsNullOrEmpty(contentTypeLinkModel.ContentTypeName))
            {
                TraceService.InformationFormat((int)LogEventId.ModelProvisionCoreCall,
                                               "ContentTypeName is not NULL. Trying to find list content type by ContentTypeName: [{0}]", contentTypeLinkModel.ContentTypeName);

                result = list.ContentTypes.FindByName(contentTypeLinkModel.ContentTypeName);
            }

            // trying to find by content type id
            // will never be resolved, actually
            // list content types have different ID

            //if (result == null && !string.IsNullOrEmpty(contentTypeLinkModel.ContentTypeId))
            //    result = list.ContentTypes.GetById(contentTypeLinkModel.ContentTypeId);

            // trying to find by beat match
            if (result == null)
            {
                TraceService.InformationFormat((int)LogEventId.ModelProvisionCoreCall,
                                               "Trying to find list content type by ContentTypeId: [{0}]", contentTypeLinkModel.ContentTypeId);

                // No SPContentTypeCollection.BestMatch() method avialable.
                // http://officespdev.uservoice.com/forums/224641-general/suggestions/6356289-expose-spcontenttypecollection-bestmatch-for-csom

                // TODO, correct best match impl
                foreach (var contentType in list.ContentTypes)
                {
                    if (contentType.Id.ToString().ToUpper().StartsWith(contentTypeLinkModel.ContentTypeId.ToUpper()))
                    {
                        result = contentType;
                    }
                }
            }

            return(result);
        }
Beispiel #7
0
        /// <summary>
        /// Promotes a model event outside of the model handler.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        protected void InvokeOnModelEvent(object sender, ModelEventArgs args)
        {
            TraceService.InformationFormat((int)LogEventId.CoreCalls, "Entering InvokeOnModelEvent with sender: [{0}] and args: [{1}]",
                                           new object[] { sender, args });

            if (OnModelEvent != null)
            {
                TraceService.VerboseFormat((int)LogEventId.CoreCalls,
                                           "OnModelEvent is not NULL. Calling OnModelEvent with sender: [{0}] and args: [{1}]",
                                           new object[] { sender, args });

                OnModelEvent.Invoke(this, args);
            }
            else
            {
                TraceService.Verbose((int)LogEventId.CoreCalls, "OnModelEvent is NULL. Skipping.");
            }

            TraceService.InformationFormat((int)LogEventId.CoreCalls, "Leaving InvokeOnModelEvent with sender: [{0}] and args: [{1}]",
                                           new object[] { sender, args });
        }
        public override void Traverse(object modelHost, ModelNode modelNode)
        {
            try
            {
                var modelDefinition = modelNode.Value as DefinitionBase;
                var modelHandler    = OnModelHandlerResolve(modelNode);

                TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnModelFullyProcessing for model: [{0}].", modelNode);

                if (OnModelFullyProcessing != null)
                {
                    OnModelFullyProcessing(modelNode);
                }

                TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnModelProcessing for model: [{0}].", modelNode);

                if (OnModelProcessing != null)
                {
                    OnModelProcessing(modelNode);
                }

                var requireselfProcessing = modelDefinition.RequireSelfProcessing || modelNode.Options.RequireSelfProcessing;

                TraceService.InformationFormat((int)LogEventId.ModelProcessing, "Deploying model [{0}] RSP: [{1}] : [{2}].",
                                               new[] { modelNode.Value.GetType().Name, requireselfProcessing.ToString(), modelNode.Value.ToString() });

                if (requireselfProcessing)
                {
                    modelHandler.DeployModel(modelHost, modelNode.Value);
                }

                TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnModelProcessed for model: [{0}].", modelNode);

                if (OnModelProcessed != null)
                {
                    OnModelProcessed(modelNode);
                }

                var childModelTypes = GetSortedChildModelTypes(modelNode);

                foreach (var childModelType in childModelTypes)
                {
                    TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Starting processing child models of type: [{0}].", new object[] { childModelType.Key });

                    var childModels = modelNode.GetChildModels(childModelType.Key).ToList();
                    ModelWeighService.SortChildModelNodes(modelNode, childModels);

                    TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Found [{0}] models of type: [{1}].", new object[] { childModels.Count(), childModelType.Key });

                    TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnChildModelsProcessing of type: [{0}].", new object[] { childModelType.Key });

                    if (OnChildModelsProcessing != null)
                    {
                        OnChildModelsProcessing(modelNode, childModelType.Key, childModels);
                    }

                    foreach (var childModel in childModels)
                    {
                        TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Starting resolving model host of type: [{0}].", new object[] { childModelType.Key });

                        modelHandler.WithResolvingModelHost(new ModelHostResolveContext
                        {
                            ModelHost      = modelHost,
                            Model          = modelDefinition,
                            ChildModelType = childModelType.Key,
                            ModelNode      = modelNode,
                            Action         = childModelHost =>
                            {
                                Traverse(childModelHost, childModel);
                            }
                        });

                        TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Finishing resolving model host of type: [{0}].", new object[] { childModelType.Key });
                    }

                    TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnChildModelsProcessed of type: [{0}].", new object[] { childModelType.Key });
                    if (OnChildModelsProcessed != null)
                    {
                        OnChildModelsProcessed(modelNode, childModelType.Key, childModels);
                    }

                    TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Finishing processing child models of type: [{0}].", new object[] { childModelType.Key });
                }

                TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnModelFullyProcessed for model: [{0}].", modelNode);

                if (OnModelFullyProcessed != null)
                {
                    OnModelFullyProcessed(modelNode);
                }
            }
            catch (Exception e)
            {
                if (e is SPMeta2ModelDeploymentException)
                {
                    throw;
                }

                throw new SPMeta2ModelDeploymentException("There was an error while provisioning definition. Check ModelNode prop.", e)
                      {
                          ModelNode = modelNode,
                      };
            }
        }
Beispiel #9
0
        public override void Traverse(object modelHost, ModelNode modelNode)
        {
            try
            {
                if (CurrentModelPath.Count == 0)
                {
                    OnBeforeDeployModel(modelHost, modelNode);
                }

                CurrentModelPath.Push(modelNode);

                var modelDefinition = modelNode.Value as DefinitionBase;
                var modelHandler    = OnModelHandlerResolve(modelNode);

                TraceService.VerboseFormat((int)LogEventId.ModelProcessing,
                                           "Raising OnModelFullyProcessing for model: [{0}].", modelNode);

                if (OnModelFullyProcessing != null)
                {
                    OnModelFullyProcessing(modelNode);
                }

                TraceService.VerboseFormat((int)LogEventId.ModelProcessing,
                                           "Raising OnModelProcessing for model: [{0}].", modelNode);

                OnBeforeDeployModelNode(modelHost, modelNode);

                if (OnModelProcessing != null)
                {
                    OnModelProcessing(modelNode);
                }

                //var requireselfProcessing = modelDefinition.RequireSelfProcessing || modelNode.Options.RequireSelfProcessing;
                var requireselfProcessing = modelNode.Options.RequireSelfProcessing;

                TraceService.InformationFormat((int)LogEventId.ModelProcessing,
                                               "Deploying model [{0}] RSP: [{1}] : [{2}].",
                                               new[] { modelNode.Value.GetType().Name, requireselfProcessing.ToString(), modelNode.Value.ToString() });

                if (requireselfProcessing)
                {
                    try
                    {
                        modelHandler.DeployModel(modelHost, modelNode.Value);
                    }
                    catch (Exception e)
                    {
                        var onExceptionArgs = new ModelTreeTraverseServiceExceptionEventArgs
                        {
                            Handled   = false,
                            Exception = e
                        };

                        if (OnException != null)
                        {
                            OnException(this, onExceptionArgs);
                        }

                        if (!onExceptionArgs.Handled)
                        {
                            throw;
                        }
                    }
                }

                TraceService.VerboseFormat((int)LogEventId.ModelProcessing,
                                           "Raising OnModelProcessed for model: [{0}].", modelNode);

                // call up before OnModelProcessed
                // Incremental provision real time trace problems #978
                // https://github.com/SubPointSolutions/spmeta2/issues/978
                OnAfterDeployModelNode(modelHost, modelNode);

                if (OnModelProcessed != null)
                {
                    OnModelProcessed(modelNode);
                }

                var childModelTypes = GetSortedChildModelTypes(modelNode);

                foreach (var childModelType in childModelTypes)
                {
                    TraceService.VerboseFormat((int)LogEventId.ModelProcessing,
                                               "Starting processing child models of type: [{0}].", new object[] { childModelType.Key });

                    var childModels = modelNode.GetChildModels(childModelType.Key).ToList();
                    ModelWeighService.SortChildModelNodes(modelNode, childModels);

                    TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Found [{0}] models of type: [{1}].",
                                               new object[] { childModels.Count(), childModelType.Key });

                    TraceService.VerboseFormat((int)LogEventId.ModelProcessing,
                                               "Raising OnChildModelsProcessing of type: [{0}].", new object[] { childModelType.Key });

                    if (OnChildModelsProcessing != null)
                    {
                        OnChildModelsProcessing(modelNode, childModelType.Key, childModels);
                    }

                    foreach (var childModel in childModels)
                    {
                        TraceService.VerboseFormat((int)LogEventId.ModelProcessing,
                                                   "Starting resolving model host of type: [{0}].", new object[] { childModelType.Key });

                        modelHandler.WithResolvingModelHost(new ModelHostResolveContext
                        {
                            ModelHost      = modelHost,
                            Model          = modelDefinition,
                            ChildModelType = childModelType.Key,
                            ModelNode      = modelNode,
                            Action         = childModelHost =>
                            {
                                Traverse(childModelHost, childModel);
                            }
                        });

                        TraceService.VerboseFormat((int)LogEventId.ModelProcessing,
                                                   "Finishing resolving model host of type: [{0}].", new object[] { childModelType.Key });
                    }

                    TraceService.VerboseFormat((int)LogEventId.ModelProcessing,
                                               "Raising OnChildModelsProcessed of type: [{0}].", new object[] { childModelType.Key });
                    if (OnChildModelsProcessed != null)
                    {
                        OnChildModelsProcessed(modelNode, childModelType.Key, childModels);
                    }

                    TraceService.VerboseFormat((int)LogEventId.ModelProcessing,
                                               "Finishing processing child models of type: [{0}].", new object[] { childModelType.Key });
                }

                TraceService.VerboseFormat((int)LogEventId.ModelProcessing,
                                           "Raising OnModelFullyProcessed for model: [{0}].", modelNode);

                if (OnModelFullyProcessed != null)
                {
                    OnModelFullyProcessed(modelNode);
                }
            }
            catch (Exception e)
            {
                var onExceptionArgs = new ModelTreeTraverseServiceExceptionEventArgs
                {
                    Handled   = false,
                    Exception = e
                };

                if (OnException != null)
                {
                    OnException(this, onExceptionArgs);
                }

                if (!onExceptionArgs.Handled)
                {
                    if (e is SPMeta2ModelDeploymentException)
                    {
                        throw;
                    }

                    throw new SPMeta2ModelDeploymentException(
                              "There was an error while provisioning definition. Check ModelNode prop.", e)
                          {
                              ModelNode = modelNode,
                          };
                }
            }
            finally
            {
                if (CurrentModelPath.Count != 0)
                {
                    CurrentModelPath.Pop();
                }

                if (CurrentModelPath.Count == 0)
                {
                    OnAfterDeployModel(modelHost, modelNode);
                }
            }
        }
Beispiel #10
0
        protected override void OnBeforeDeployModel(object modelHost, ModelNode modelNode)
        {
            base.OnBeforeDeployModel(modelHost, modelNode);

            // clean up current model hash
            CurrentModelHash = new ModelHash();
            ClearCaches();

            TraceService.InformationFormat(0, "Starting incremental provision with EnableCaching = {0}", EnableCaching);

            var storages = ResolvePersistenceStorages(modelHost, modelNode);

            // restore previous one
            if (Configuration != null && storages.Count() > 0)
            {
                TraceService.Information(0, "Model hash restore: found [{0}] storage impl in Configuration.PersistenceStorages. Automatic model hash management is used");

                var modelIdProperty = modelNode.GetPropertyBagValue(DefaultModelNodePropertyBagValue.Sys.IncrementalProvision.PersistenceStorageModelId);

                if (modelIdProperty == null)
                {
                    throw new SPMeta2Exception("IncrementalProvisionModelId is not set. Either clean PersistenceStorages and handle model hash persistence manually or set .PersistenceStorageModelId");
                }

                var modelId  = modelIdProperty;
                var objectId = string.Format("{0}.{1}", DefaultPersistenceModelIdPrefix, modelId);

                var serializer = ServiceContainer.Instance.GetService <DefaultXMLSerializationService>();
                serializer.RegisterKnownTypes(new[]
                {
                    typeof(ModelHash),
                    typeof(ModelNodeHash)
                });

                foreach (var storage in storages)
                {
                    TraceService.Information(0, string.Format("Restoring model hash with object id:[{0}] using storage impl [{1}]",
                                                              objectId, storage.GetType()));

                    var data = storage.LoadObject(objectId);

                    if (data != null)
                    {
                        var dataString = Encoding.UTF8.GetString(data);
                        var dataObject = serializer.Deserialize(typeof(ModelHash), dataString) as ModelHash;

                        if (dataObject != null)
                        {
                            PreviousModelHash = dataObject;

                            TraceService.Information(0, string.Format("Restored model hash with object id:[{0}] using storage impl [{1}]",
                                                                      objectId, storage.GetType()));
                            break;
                        }
                    }
                    else
                    {
                        TraceService.Information(0, string.Format("Restored model hash with object id:[{0}] using storage impl [{1}]",
                                                                  objectId, storage.GetType()));
                    }
                }

                TraceService.Information(0, string.Format("Coudn't restore model hash with object id:[{0}]. Either first provision is user or storage is wrong.", objectId));
            }
            else
            {
                TraceService.Information(0, "Model hash restore: can't find any persistence storage impl in Configuration.PersistenceStorages. Assuming manual model hash management is used");
            }
        }
Beispiel #11
0
        protected override void OnBeforeDeployModelNode(object modelHost, ModelNode modelNode)
        {
            // temporary measure
            // we need to restoreoriginal value of .RequireSelfProcessing to avoid any model changes
            // set 'ProcessedRequireSelfProcessingValue' in property bag for the further
            OriginalRequireSelfProcessingValue = modelNode.Options.RequireSelfProcessing;

            // lookup node and definition in model state
            // mark as modelNode.Options.RequireSelfProcessing true/false based on state

            var currentModelNode  = modelNode;
            var currentDefinition = modelNode.Value;

            var prevModelHash = GetPreviousModelHash();

            var isSingleIdentity = IsSingletonIdentityDefinition(currentDefinition);

            if (isSingleIdentity)
            {
                TraceService.InformationFormat(0,
                                               "Detected singleton definition [{0}]. Incremental update for such definitions isn't supported yet. Skipping.",
                                               currentDefinition);
                return;
            }
            else
            {
                TraceService.InformationFormat(0,
                                               "Calculating hashes for node and definition:[{0}]",
                                               currentDefinition);
            }

            //var currentNodeHashHash = HashService.GetHashCode(currentModelNode);
            var currentDefinitionHash = GetHashString(currentDefinition);

            var currentDefinitionIdentityKey  = GetDefinitionIdentityKey(currentDefinition);
            var currentDefinitionIdentityHash = GetHashString(currentDefinitionIdentityKey);

            var currentDefinitionFullPath     = GetDefinitionFullPath(false);
            var currentDefinitionFullPathHash = GetDefinitionFullPath(true);

            //TraceService.InformationFormat(0, "    -node hash:[{0}]", currentNodeHashHash);
            TraceService.InformationFormat(0, "    - definition hash:[{0}]", currentDefinitionHash);
            TraceService.InformationFormat(0, "    - definition full path:[{0}]", currentDefinitionFullPath);
            TraceService.InformationFormat(0, "    - definition full path hash:[{0}]", currentDefinitionFullPathHash);

            var prevModeNodeHashes = prevModelHash.ModelNodes
                                     .Where(h => h.DefinitionFullPathHash == currentDefinitionFullPathHash);

            // same definition is added multiple times
            // this could be
            // - toggling, such as feature activation toggling
            // - intentional toggling of the field or something
            // - intentional adding definition twice
            // we don't change anyting with the yet preferring to skip incremental provision detection
            if (prevModeNodeHashes.Count() > 1)
            {
                TraceService.InformationFormat(0, "Found more than one previous model node by path hash:[{0}]", currentDefinitionFullPathHash);
                TraceService.Information(0, "Not changing anything, incremental provision can't detect right path to change here.");

                IgnoredModelNodes.Add(currentModelNode);

                return;
            }

            var prevModeNodeHash = prevModeNodeHashes.FirstOrDefault();

            if (prevModeNodeHash != null)
            {
                TraceService.InformationFormat(0, "Found previous model node by path hash:[{0}]", currentDefinitionFullPathHash);

                if (prevModeNodeHash.DefinitionHash != currentDefinitionHash)
                {
                    TraceService.Information(0, "Definition hashes don't macth. Setting .Options.RequireSelfProcessing  = true if it's not.");

                    if (!modelNode.Options.RequireSelfProcessing)
                    {
                        modelNode.Options.RequireSelfProcessing = true;
                    }
                }
                else
                {
                    TraceService.Information(0, "Definition hashes match. Setting .Options.RequireSelfProcessing  = false.");
                    modelNode.Options.RequireSelfProcessing = false;
                }
            }
            else
            {
                TraceService.InformationFormat(0,
                                               "Cannot find previous model hash. Leaving .Options.RequireSelfProcessing as it is:[{0}]",
                                               currentModelNode.Options.RequireSelfProcessing);
            }
        }
Beispiel #12
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            if (!(modelHost is SiteModelHost || modelHost is ListModelHost))
            {
                throw new ArgumentException("modelHost needs to be SiteModelHost/ListModelHost instance.");
            }

            CurrentSiteModelHost = modelHost as SiteModelHost;

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Casting field model definition");
            var fieldModel = model.WithAssertAndCast <FieldDefinition>("model", value => value.RequireNotNull());

            Field currentField           = null;
            ClientRuntimeContext context = null;

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = null,
                ObjectType       = GetTargetFieldType(fieldModel),
                ObjectDefinition = model,
                ModelHost        = modelHost
            });
            InvokeOnModelEvent <FieldDefinition, Field>(currentField, ModelEventType.OnUpdating);

            if (modelHost is SiteModelHost)
            {
                var siteHost = modelHost as SiteModelHost;
                context = siteHost.HostSite.Context;

                currentField = DeploySiteField(siteHost as SiteModelHost, fieldModel);
            }
            else if (modelHost is ListModelHost)
            {
                var listHost = modelHost as ListModelHost;
                context = listHost.HostList.Context;

                currentField = DeployListField(modelHost as ListModelHost, fieldModel);
            }

            object typedField = null;

            // emulate context.CastTo<>() call for typed field type
            if (GetTargetFieldType(fieldModel) != currentField.GetType())
            {
                var targetFieldType = GetTargetFieldType(fieldModel);

                TraceService.InformationFormat((int)LogEventId.ModelProvisionCoreCall, "Calling context.CastTo() to field type: [{0}]", targetFieldType);

                var method  = context.GetType().GetMethod("CastTo");
                var generic = method.MakeGenericMethod(targetFieldType);

                typedField = generic.Invoke(context, new object[] { currentField });
            }

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioned,
                Object           = typedField ?? currentField,
                ObjectType       = GetTargetFieldType(fieldModel),
                ObjectDefinition = model,
                ModelHost        = modelHost
            });
            InvokeOnModelEvent <FieldDefinition, Field>(currentField, ModelEventType.OnUpdated);

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "UpdateAndPushChanges(true)");
            currentField.UpdateAndPushChanges(true);

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "ExecuteQuery()");
            context.ExecuteQueryWithTrace();
        }