Example #1
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Extracting web from modelhost");
            var parentWeb = ExtractWeb(modelHost);

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Extracting host client context from model host");
            var hostclientContext = ExtractHostClientContext(modelHost);

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Casting web model definition");
            var webModel = model.WithAssertAndCast <WebDefinition>("model", value => value.RequireNotNull());

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Loading Url/ServerRelativeUrl");
            var context = parentWeb.Context;

            context.Load(parentWeb, w => w.Url);
            //context.Load(parentWeb, w => w.RootFolder);
            context.Load(parentWeb, w => w.ServerRelativeUrl);

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

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Extracting current web URL");
            var currentWebUrl = GetCurrentWebUrl(context, parentWeb, webModel);

            TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Current web URL: [{0}].", currentWebUrl);

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Loading existing web.");
            var currentWeb = GetExistingWeb(hostclientContext.Site, parentWeb, currentWebUrl);

            TraceService.Verbose((int)LogEventId.ModelProvisionUpdatingEventCall, "Calling OnUpdating event.");
            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = null,
                ObjectType       = typeof(Web),
                ObjectDefinition = model,
                ModelHost        = modelHost
            });

            if (currentWeb == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new web");

                var webUrl = webModel.Url;
                // Enhance web provision - handle '/' slash #620
                // https://github.com/SubPointSolutions/spmeta2/issues/620
                webUrl = UrlUtility.RemoveStartingSlash(webUrl);

                WebCreationInformation newWebInfo;

                if (string.IsNullOrEmpty(webModel.CustomWebTemplate))
                {
                    newWebInfo = new WebCreationInformation
                    {
                        Title       = webModel.Title,
                        Url         = webUrl,
                        Description = webModel.Description ?? string.Empty,
                        WebTemplate = webModel.WebTemplate,
                        UseSamePermissionsAsParentSite = !webModel.UseUniquePermission,
                        Language = (int)webModel.LCID
                    };
                }
                else
                {
                    var customWebTemplateName = webModel.CustomWebTemplate;

                    // by internal name
                    var templateCollection = parentWeb.GetAvailableWebTemplates(webModel.LCID, true);
                    var templateResult     = context.LoadQuery(templateCollection
                                                               .Include(tmp => tmp.Name, tmp => tmp.Title)
                                                               .Where(tmp => tmp.Name == customWebTemplateName));


                    TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Trying to find template based on the given CustomWebTemplate and calling ExecuteQuery.");
                    context.ExecuteQueryWithTrace();

                    if (templateResult.FirstOrDefault() == null)
                    {
                        // one more try by title
                        templateResult = context.LoadQuery(templateCollection
                                                           .Include(tmp => tmp.Name, tmp => tmp.Title)
                                                           .Where(tmp => tmp.Title == customWebTemplateName));



                        TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Trying to find template based on the given CustomWebTemplate and calling ExecuteQuery.");
                        context.ExecuteQueryWithTrace();
                    }

                    var template = templateResult.FirstOrDefault();

                    if (template == null)
                    {
                        throw new SPMeta2ModelDeploymentException("Couldn't find custom web template: " + webModel.CustomWebTemplate);
                    }

                    newWebInfo = new WebCreationInformation
                    {
                        Title       = webModel.Title,
                        Url         = webModel.Url,
                        Description = webModel.Description ?? string.Empty,
                        WebTemplate = template.Name,
                        UseSamePermissionsAsParentSite = !webModel.UseUniquePermission,
                        Language = (int)webModel.LCID
                    };
                }

                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Adding new web to the web collection and calling ExecuteQuery.");
                var newWeb = parentWeb.Webs.Add(newWebInfo);
                context.ExecuteQueryWithTrace();

                MapProperties(newWeb, webModel);
                ProcessLocalization(newWeb, webModel);

                context.Load(newWeb);

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

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = newWeb,
                    ObjectType       = typeof(Web),
                    ObjectDefinition = model,
                    ModelHost        = modelHost
                });
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Current web is not null. Updating Title/Description.");

                MapProperties(currentWeb, webModel);

                //  locale is not available with CSOM yet

                ProcessLocalization(currentWeb, webModel);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentWeb,
                    ObjectType       = typeof(Web),
                    ObjectDefinition = model,
                    ModelHost        = modelHost
                });

                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "currentWeb.Update()");
                currentWeb.Update();

                context.ExecuteQueryWithTrace();
            }
        }
Example #2
0
        private void ProcessSPSecurableObjectHost(SPSecurableObject targetSecurableObject, SPGroup securityGroup,
                                                  SecurityRoleLinkDefinition securityRoleLinkModel)
        {
            //// TODO
            // need common validation infrastructure
            var web = ExtractWeb(targetSecurableObject);

            var roleAssignment = new SPRoleAssignment(securityGroup);

            var role = ResolveSecurityRole(web, securityRoleLinkModel);

            if (!roleAssignment.RoleDefinitionBindings.Contains(role))
            {
                if (roleAssignment.RoleDefinitionBindings.Count == 1 &&
                    roleAssignment.RoleDefinitionBindings[0].Type == SPRoleType.Reader)
                {
                    roleAssignment.RoleDefinitionBindings.RemoveAll();
                }

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioning,
                    Object           = null,
                    ObjectType       = typeof(SPRoleDefinition),
                    ObjectDefinition = securityRoleLinkModel,
                    ModelHost        = targetSecurableObject
                });

                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new security role link");

                roleAssignment.RoleDefinitionBindings.Add(role);
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing security role link");

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioning,
                    Object           = role,
                    ObjectType       = typeof(SPRoleDefinition),
                    ObjectDefinition = securityRoleLinkModel,
                    ModelHost        = targetSecurableObject
                });
            }

            targetSecurableObject.RoleAssignments.Add(roleAssignment);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioned,
                Object           = role,
                ObjectType       = typeof(SPRoleDefinition),
                ObjectDefinition = securityRoleLinkModel,
                ModelHost        = targetSecurableObject
            });
        }
Example #3
0
        private void HandleWikiPageProvision(ListItem listItem, WebPartDefinitionBase webpartModel)
        {
            if (!webpartModel.AddToPageContent)
            {
                return;
            }

            TraceService.Information((int)LogEventId.ModelProvisionCoreCall, "AddToPageContent = true. Handling wiki/publishig page provision case.");

            var context = listItem.Context;

            var targetFieldName = string.Empty;

            if (listItem.FieldValues.ContainsKey(BuiltInInternalFieldNames.WikiField))
            {
                TraceService.Information((int)LogEventId.ModelProvisionCoreCall, "WikiField field is detected. Switching to wiki page web part provision.");

                targetFieldName = BuiltInInternalFieldNames.WikiField;
            }
            else if (listItem.FieldValues.ContainsKey(BuiltInInternalFieldNames.PublishingPageLayout))
            {
                TraceService.Information((int)LogEventId.ModelProvisionCoreCall, "PublishingPageLayout field is detected. Switching to publishin page web part provision.");

                targetFieldName = BuiltInInternalFieldNames.PublishingPageContent;
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionCoreCall, "Not PublishingPageLayout field, nor WikiField is detected. Skipping.");
                return;
            }

            var wikiTemplate = new StringBuilder();

            var wpId = webpartModel.Id
                       .Replace("g_", string.Empty)
                       .Replace("_", "-");

            var content = listItem[targetFieldName] == null
                ? string.Empty
                : listItem[targetFieldName].ToString();

            wikiTemplate.AppendFormat(
                "​​​​​​​​​​​​​​​​​​​​​​<div class='ms-rtestate-read ms-rte-wpbox' contentEditable='false'>");
            wikiTemplate.AppendFormat("     <div class='ms-rtestate-read {0}' id='div_{0}'>", wpId);
            wikiTemplate.AppendFormat("     </div>");
            wikiTemplate.AppendFormat("</div>");

            var wikiResult = wikiTemplate.ToString();

            if (string.IsNullOrEmpty(content))
            {
                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Page content is empty Generating new one.");

                content = wikiResult;

                listItem[targetFieldName] = content;
                listItem.Update();

                context.ExecuteQueryWithTrace();
            }
            else
            {
                if (content.ToUpper().IndexOf(wpId.ToUpper()) == -1)
                {
                    TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Replacing web part with ID: [{0}] on the page content.", wpId);

                    content += wikiResult;

                    listItem[targetFieldName] = content;
                    listItem.Update();

                    context.ExecuteQueryWithTrace();
                }
                else
                {
                    TraceService.WarningFormat((int)LogEventId.ModelProvisionCoreCall,
                                               "Cannot find web part ID: [{0}] the page content. Provision won't add web part on the page content.",
                                               new object[]
                    {
                        wpId
                    });
                }
            }
        }
        private NavigationNode EnsureRootNavigationNode(
            WebModelHost webModelHost,
            NavigationNodeDefinitionBase navigationNodeModel)
        {
            NavigationNodeCollection quickLaunch = null;

            var context = webModelHost.HostWeb.Context;

            var existingNode = GetRootNavigationNode(webModelHost, navigationNodeModel, out quickLaunch);
            var previousNode = quickLaunch.Count > 0 ? quickLaunch.Last() : null;

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = existingNode,
                ObjectType       = typeof(NavigationNode),
                ObjectDefinition = navigationNodeModel,
                ModelHost        = webModelHost
            });

            if (existingNode == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new navigation node");

                existingNode = quickLaunch.Add(new NavigationNodeCreationInformation
                {
                    Title        = navigationNodeModel.Title,
                    IsExternal   = navigationNodeModel.IsExternal,
                    Url          = ResolveTokenizedUrl(webModelHost.HostClientContext, navigationNodeModel),
                    PreviousNode = previousNode
                });

                context.ExecuteQueryWithTrace();
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing navigation node");
            }

            existingNode.Title     = navigationNodeModel.Title;
            existingNode.Url       = ResolveTokenizedUrl(webModelHost.HostClientContext, navigationNodeModel);
            existingNode.IsVisible = navigationNodeModel.IsVisible;

            ProcessLocalization(existingNode, navigationNodeModel);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioned,
                Object           = existingNode,
                ObjectType       = typeof(NavigationNode),
                ObjectDefinition = navigationNodeModel,
                ModelHost        = webModelHost
            });

            existingNode.Update();

            context.ExecuteQueryWithTrace();

            return(existingNode);
        }
Example #5
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            Guid?OldWebParKey = null;

            var listItemModelHost = modelHost.WithAssertAndCast <ListItemModelHost>("modelHost", value => value.RequireNotNull());
            var webPartModel      = model.WithAssertAndCast <WebPartDefinitionBase>("model", value => value.RequireNotNull());

            try
            {
                OnBeforeDeploy(listItemModelHost, webPartModel);

                CurrentClientContext = listItemModelHost.HostClientContext;

                var context         = listItemModelHost.HostClientContext;
                var currentPageFile = GetCurrentPageFile(listItemModelHost);


                if (listItemModelHost.HostFolder != null)
                {
                    if (!listItemModelHost.HostFolder.IsPropertyAvailable("Properties") ||
                        listItemModelHost.HostFolder.Properties.FieldValues.Count == 0)
                    {
                        listItemModelHost.HostFolder.Context.Load(listItemModelHost.HostFolder, f => f.Properties);
                        //folder.Context.Load(folder, f => f.Properties);

                        listItemModelHost.HostFolder.Context.ExecuteQueryWithTrace();
                    }
                }

                // TODO
                var doesFileHasListItem =
                    //Forms folders
                    !(listItemModelHost.HostFolder != null
                      &&
                      (listItemModelHost.HostFolder.Properties.FieldValues.ContainsKey("vti_winfileattribs")
                       &&
                       listItemModelHost.HostFolder.Properties.FieldValues["vti_winfileattribs"].ToString() ==
                       "00000012"));

                ModuleFileModelHandler.WithSafeFileOperation(listItemModelHost.HostList,
                                                             currentPageFile, pageFile =>
                {
                    Guid?webPartStoreKey = null;

                    InternalOnBeforeWebPartProvision(new WebPartProcessingContext
                    {
                        ListItemModelHost = listItemModelHost,
                        WebPartDefinition = webPartModel,
                        WebPartStoreKey   = webPartStoreKey
                    });

                    //var fileContext = pageFile.Context;
                    ListItem fileListItem = null;

                    if (webPartModel.AddToPageContent)
                    {
                        // pre load here to be used later

                        var fileContext = pageFile.Context;

                        fileListItem = pageFile.ListItemAllFields;

                        fileContext.Load(fileListItem);
                        fileContext.ExecuteQueryWithTrace();
                    }

                    var webPartManager = pageFile.GetLimitedWebPartManager(PersonalizationScope.Shared);

                    // web part on the page
                    var webpartOnPage      = webPartManager.WebParts.Include(wp => wp.Id, wp => wp.WebPart);
                    var webPartDefenitions = context.LoadQuery(webpartOnPage);

                    context.ExecuteQueryWithTrace();

                    Microsoft.SharePoint.Client.WebParts.WebPartDefinition wpDefinition;

                    WebPart existingWebPart = null;

                    // TODO
                    var tmpWp = FindExistingWebPart(webPartDefenitions, webPartModel, out wpDefinition);

                    InvokeOnModelEvent(this, new ModelEventArgs
                    {
                        CurrentModelNode = null,
                        Model            = null,
                        EventType        = ModelEventType.OnProvisioning,
                        Object           = existingWebPart,
                        ObjectType       = typeof(WebPart),
                        ObjectDefinition = webPartModel,
                        ModelHost        = modelHost
                    });

                    if (wpDefinition != null)
                    {
                        OldWebParKey = wpDefinition.Id;

                        TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject,
                                                 "Deleting current web part.");

                        wpDefinition.DeleteWebPart();
                        wpDefinition.Context.ExecuteQueryWithTrace();
                    }
                    else
                    {
                        existingWebPart = tmpWp;
                    }

                    Microsoft.SharePoint.Client.WebParts.WebPartDefinition webPartAddedDefinition = null;

                    if (existingWebPart == null)
                    {
                        TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject,
                                                 "Processing new web part");

                        var webPartXML = GetWebpartXmlDefinition(listItemModelHost, webPartModel);
                        webPartXML     = ProcessCommonWebpartProperties(webPartXML, webPartModel);

                        //// handle wiki page
                        //if (webPartModel.AddToPageContent)
                        //{

                        //    HandleWikiPageProvision(fileListItem, webPartModel);
                        //}

                        var webPartDefinition  = webPartManager.ImportWebPart(webPartXML);
                        webPartAddedDefinition = webPartManager.AddWebPart(webPartDefinition.WebPart,
                                                                           webPartModel.ZoneId,
                                                                           webPartModel.ZoneIndex);

                        context.Load(webPartAddedDefinition);
                        context.ExecuteQueryWithTrace();

                        if (webPartAddedDefinition != null && webPartAddedDefinition.ServerObjectIsNull == false)
                        {
                            existingWebPart = webPartAddedDefinition.WebPart;
                            webPartStoreKey = webPartAddedDefinition.Id;
                        }

                        // handle wiki page
                        if (webPartModel.AddToPageContent)
                        {
                            HandleWikiPageProvision(fileListItem, webPartModel, webPartStoreKey, OldWebParKey);
                        }

                        existingWebPart = webPartDefinition.WebPart;

                        InvokeOnModelEvent(this, new ModelEventArgs
                        {
                            CurrentModelNode = null,
                            Model            = null,
                            EventType        = ModelEventType.OnProvisioned,
                            Object           = existingWebPart,
                            ObjectType       = typeof(WebPart),
                            ObjectDefinition = webPartModel,
                            ModelHost        = modelHost
                        });
                    }
                    else
                    {
                        TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject,
                                                 "Processing existing web part");

                        if (webPartModel.AddToPageContent)
                        {
                            //HandleWikiPageProvision(fileListItem, webPartModel);
                        }

                        InvokeOnModelEvent(this, new ModelEventArgs
                        {
                            CurrentModelNode = null,
                            Model            = null,
                            EventType        = ModelEventType.OnProvisioned,
                            Object           = existingWebPart,
                            ObjectType       = typeof(WebPart),
                            ObjectDefinition = webPartModel,
                            ModelHost        = modelHost
                        });
                    }

                    context.ExecuteQueryWithTrace();

                    if (webPartAddedDefinition != null && webPartAddedDefinition.ServerObjectIsNull == false)
                    {
                        existingWebPart = webPartAddedDefinition.WebPart;
                        webPartStoreKey = webPartAddedDefinition.Id;
                    }

                    InternalOnAfterWebPartProvision(new WebPartProcessingContext
                    {
                        ListItemModelHost = listItemModelHost,
                        WebPartDefinition = webPartModel,
                        WebPartStoreKey   = webPartStoreKey
                    });

                    return(pageFile);
                }, doesFileHasListItem);
            }
            finally
            {
                OnAfterDeploy(listItemModelHost, webPartModel);
            }
        }
Example #6
0
        private SPFolder EnsureLibraryFolder(FolderModelHost folderModelHost, FolderDefinition folderModel)
        {
            TraceService.Information((int)LogEventId.ModelProvisionCoreCall, "EnsureLibraryFolder()");

            var parentFolder = folderModelHost.CurrentLibraryFolder;

            // dirty stuff, needs to be rewritten
            var currentFolder = GetLibraryFolder(folderModelHost, folderModel);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = currentFolder == null || !currentFolder.Exists ? null : currentFolder,
                ObjectType       = typeof(SPFolder),
                ObjectDefinition = folderModel,
                ModelHost        = folderModelHost
            });

            if (currentFolder == null || !currentFolder.Exists)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new library folder");

                currentFolder = parentFolder.SubFolders.Add(folderModel.Name);
                currentFolder.Update();

                MapFolderProperties(currentFolder.Item, folderModel);
                currentFolder.Item.Update();

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentFolder,
                    ObjectType       = typeof(SPFolder),
                    ObjectDefinition = folderModel,
                    ModelHost        = folderModelHost
                });
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing library folder");

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentFolder,
                    ObjectType       = typeof(SPFolder),
                    ObjectDefinition = folderModel,
                    ModelHost        = folderModelHost
                });

                currentFolder.Update();

                MapFolderProperties(currentFolder.Item, folderModel);
                currentFolder.Item.Update();
            }

            return(currentFolder);
        }
Example #7
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            var modelHostWrapper          = modelHost.WithAssertAndCast <ModelHostContext>("modelHost", value => value.RequireNotNull());
            var contentTypeFieldLinkModel = model.WithAssertAndCast <ContentTypeFieldLinkDefinition>("model", value => value.RequireNotNull());

            //var site = modelHostWrapper.Site;
            var web         = modelHostWrapper.Web;
            var contentType = modelHostWrapper.ContentType;

            var context = contentType.Context;

            TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Getting content type field link by ID: [{0}]", contentTypeFieldLinkModel.FieldId);

            FieldLink fieldLink = FindExistingFieldLink(contentType, contentTypeFieldLinkModel);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = fieldLink,
                ObjectType       = typeof(FieldLink),
                ObjectDefinition = model,
                ModelHost        = modelHost
            });

            if (fieldLink == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new content type field link");

                var targetField = FindAvailableField(web, contentTypeFieldLinkModel);

                fieldLink = contentType.FieldLinks.Add(new FieldLinkCreationInformation
                {
                    Field = targetField
                });
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing content type field link");
            }

            if (contentTypeFieldLinkModel.Required.HasValue)
            {
                fieldLink.Required = contentTypeFieldLinkModel.Required.Value;
            }

            if (contentTypeFieldLinkModel.Hidden.HasValue)
            {
                fieldLink.Hidden = contentTypeFieldLinkModel.Hidden.Value;
            }

            if (!string.IsNullOrEmpty(contentTypeFieldLinkModel.DisplayName))
            {
                // CSOM limitation - DisplayName is not available yet.
                // https://officespdev.uservoice.com/forums/224641-general/suggestions/7024931-enhance-fieldlink-class-with-additional-properties

                //   fieldLink.DisplayName = contentTypeFieldLinkModel.DisplayName;
            }

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioned,
                Object           = fieldLink,
                ObjectType       = typeof(FieldLink),
                ObjectDefinition = model,
                ModelHost        = modelHost
            });

            contentType.Update(true);
            context.ExecuteQueryWithTrace();
        }
Example #8
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            var folderModelHost = modelHost.WithAssertAndCast <FolderModelHost>("modelHost", value => value.RequireNotNull());
            var definition      = model.WithAssertAndCast <WikiPageDefinition>("model", value => value.RequireNotNull());

            var folder = folderModelHost.CurrentLibraryFolder;
            var list   = folderModelHost.CurrentLibrary;

            //if (!string.IsNullOrEmpty(wikiPageModel.FolderUrl))
            //    throw new Exception("FolderUrl property is not supported yet!");

            var pageItem = FindWikiPageItem(folder, definition);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = pageItem == null ? null : pageItem.File,
                ObjectType       = typeof(SPFile),
                ObjectDefinition = model,
                ModelHost        = modelHost
            });

            if (pageItem == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new wiki page");

                var newWikiPageUrl = GetSafeWikiPageUrl(folder, definition);
                var newpage        = folder.Files.Add(newWikiPageUrl, SPTemplateFileType.WikiPage);

                FieldLookupService.EnsureDefaultValues(newpage.ListItemAllFields, definition.DefaultValues);

                if (!string.IsNullOrEmpty(definition.ContentTypeId) ||
                    !string.IsNullOrEmpty(definition.ContentTypeName))
                {
                    if (!string.IsNullOrEmpty(definition.ContentTypeId))
                    {
                        newpage.ListItemAllFields["ContentTypeId"] = ContentTypeLookupService.LookupListContentTypeById(list, definition.ContentTypeId);
                    }

                    if (!string.IsNullOrEmpty(definition.ContentTypeName))
                    {
                        newpage.ListItemAllFields["ContentTypeId"] = ContentTypeLookupService.LookupContentTypeByName(list, definition.ContentTypeName);
                    }
                }

                newpage.ListItemAllFields[SPBuiltInFieldId.WikiField] = definition.Content ?? string.Empty;

                FieldLookupService.EnsureValues(newpage.ListItemAllFields, definition.Values, true);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = newpage,
                    ObjectType       = typeof(SPFile),
                    ObjectDefinition = model,
                    ModelHost        = modelHost
                });

                newpage.ListItemAllFields.Update();
                newpage.Update();
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing wiki page");

                if (definition.NeedOverride)
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "NeedOverride = true. Updating wiki page content.");

                    FieldLookupService.EnsureDefaultValues(pageItem, definition.DefaultValues);

                    if (!string.IsNullOrEmpty(definition.ContentTypeId) ||
                        !string.IsNullOrEmpty(definition.ContentTypeName))
                    {
                        if (!string.IsNullOrEmpty(definition.ContentTypeId))
                        {
                            pageItem["ContentTypeId"] = ContentTypeLookupService.LookupListContentTypeById(list, definition.ContentTypeId);
                        }

                        if (!string.IsNullOrEmpty(definition.ContentTypeName))
                        {
                            pageItem["ContentTypeId"] = ContentTypeLookupService.LookupContentTypeByName(list, definition.ContentTypeName);
                        }
                    }

                    pageItem[SPBuiltInFieldId.WikiField] = definition.Content ?? string.Empty;

                    FieldLookupService.EnsureValues(pageItem, definition.Values, true);
                }
                else
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "NeedOverride = false. Skipping Updating wiki page content.");
                }

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = pageItem.File,
                    ObjectType       = typeof(SPFile),
                    ObjectDefinition = model,
                    ModelHost        = modelHost
                });

                pageItem.Update();
                pageItem.File.Update();
            }
        }
Example #9
0
        private void DeployWikiPage(Web web, List list, Folder folder, WikiPageDefinition definition)
        {
            var context = folder.Context;

            var newWikiPageUrl = string.Empty;

            var contentTypeId = string.Empty;

            // pre load content type
            if (!string.IsNullOrEmpty(definition.ContentTypeId))
            {
                contentTypeId = definition.ContentTypeId;
            }
            else if (!string.IsNullOrEmpty(definition.ContentTypeName))
            {
                contentTypeId = ContentTypeLookupService
                                .LookupContentTypeByName(list, definition.ContentTypeName)
                                .Id.ToString();
            }

            var file = GetWikiPageFile(web, folder, definition, out newWikiPageUrl);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = file,
                ObjectType       = typeof(File),
                ObjectDefinition = definition,
                ModelHost        = folder
            });

            if (file == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new wiki page");

                var newPageFile = folder.Files.AddTemplateFile(newWikiPageUrl, TemplateFileType.WikiPage);

                context.Load(newPageFile);

                var currentListItem = newPageFile.ListItemAllFields;
                context.Load(currentListItem);
                context.ExecuteQueryWithTrace();

                FieldLookupService.EnsureDefaultValues(currentListItem, definition.DefaultValues);

                if (!string.IsNullOrEmpty(contentTypeId))
                {
                    currentListItem[BuiltInInternalFieldNames.ContentTypeId] = contentTypeId;
                }

                currentListItem[BuiltInInternalFieldNames.WikiField] = definition.Content ?? String.Empty;

                FieldLookupService.EnsureValues(currentListItem, definition.Values, true);

                currentListItem.Update();

                context.ExecuteQueryWithTrace();

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = newPageFile,
                    ObjectType       = typeof(File),
                    ObjectDefinition = definition,
                    ModelHost        = folder
                });

                context.ExecuteQueryWithTrace();
            }
            else
            {
                // TODO,override if force
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing wiki page");

                if (definition.NeedOverride)
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "NeedOverride = true. Updating wiki page content.");

                    var currentListItem = file.ListItemAllFields;
                    context.Load(currentListItem);
                    context.ExecuteQueryWithTrace();

                    FieldLookupService.EnsureDefaultValues(currentListItem, definition.DefaultValues);

                    if (!string.IsNullOrEmpty(contentTypeId))
                    {
                        currentListItem[BuiltInInternalFieldNames.ContentTypeId] = contentTypeId;
                    }

                    currentListItem[BuiltInInternalFieldNames.WikiField] = definition.Content ?? String.Empty;
                    currentListItem.Update();
                }
                else
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "NeedOverride = false. Skipping Updating wiki page content.");
                }

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = file,
                    ObjectType       = typeof(File),
                    ObjectDefinition = definition,
                    ModelHost        = folder
                });

                context.ExecuteQueryWithTrace();
            }
        }
Example #10
0
        private ListItem EnsureListItem(List list, Folder folder, ListItemDefinition listItemModel)
        {
            var context     = list.Context;
            var currentItem = FindListItem(list, folder, listItemModel);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = currentItem,
                ObjectType       = typeof(ListItem),
                ObjectDefinition = listItemModel,
                ModelHost        = list
            });

            if (currentItem == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new list item");

                var newItem = list.AddItem(new ListItemCreationInformation
                {
                    FolderUrl            = folder.ServerRelativeUrl,
                    UnderlyingObjectType = FileSystemObjectType.File,
                    LeafName             = null
                });

                MapListItemProperties(newItem, listItemModel);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = newItem,
                    ObjectType       = typeof(ListItem),
                    ObjectDefinition = listItemModel,
                    ModelHost        = list
                });

                newItem.Update();

                context.ExecuteQueryWithTrace();

                return(newItem);
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing list item");

                MapListItemProperties(currentItem, listItemModel);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentItem,
                    ObjectType       = typeof(ListItem),
                    ObjectDefinition = listItemModel,
                    ModelHost        = list
                });

                currentItem.Update();

                context.ExecuteQueryWithTrace();

                return(currentItem);
            }
        }
        private void DeployWebWorkflowSubscriptionDefinition(
            object host,
            SPWeb web,
            SP2013WorkflowSubscriptionDefinition workflowSubscriptionModel)
        {
            var workflowServiceManager = new WorkflowServicesManager(web);

            var workflowSubscriptionService = workflowServiceManager.GetWorkflowSubscriptionService();
            var workflowDeploymentService   = workflowServiceManager.GetWorkflowDeploymentService();
            var tgtwis = workflowServiceManager.GetWorkflowInstanceService();

            var publishedWorkflows = workflowDeploymentService.EnumerateDefinitions(true);

            var currentWorkflowDefinition = publishedWorkflows.FirstOrDefault(w => w.DisplayName == workflowSubscriptionModel.WorkflowDisplayName);

            if (currentWorkflowDefinition == null)
            {
                throw new Exception(string.Format("Cannot lookup workflow definition with display name: [{0}] on web:[{1}]", workflowSubscriptionModel.WorkflowDisplayName, web.Url));
            }

            // EnumerateSubscriptionsByEventSource() somehow throws an exception
            //var subscriptions = workflowSubscriptionService.EnumerateSubscriptionsByEventSource(web.ID);
            var subscriptions = workflowSubscriptionService.EnumerateSubscriptions().Where(s => s.EventSourceId == web.ID);

            InvokeOnModelEvent <SP2013WorkflowSubscriptionDefinition, WorkflowSubscription>(null, ModelEventType.OnUpdating);

            var currentSubscription = subscriptions.FirstOrDefault(s => s.Name == workflowSubscriptionModel.Name);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = currentSubscription,
                ObjectType       = typeof(WorkflowSubscription),
                ObjectDefinition = workflowSubscriptionModel,
                ModelHost        = host
            });

            if (currentSubscription == null)
            {
                var taskList    = GetTaskList(web, workflowSubscriptionModel);
                var historyList = GetHistoryList(web, workflowSubscriptionModel);

                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new SP2013 workflow subscription");

                var newSubscription = new WorkflowSubscription();

                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Setting subscription properties");

                newSubscription.Name         = workflowSubscriptionModel.Name;
                newSubscription.DefinitionId = currentWorkflowDefinition.Id;

                newSubscription.EventTypes    = new List <string>(workflowSubscriptionModel.EventTypes);
                newSubscription.EventSourceId = web.ID;

                newSubscription.SetProperty("HistoryListId", historyList.ID.ToString());
                newSubscription.SetProperty("TaskListId", taskList.ID.ToString());

                newSubscription.SetProperty("WebId", web.ID.ToString());
                newSubscription.SetProperty("Microsoft.SharePoint.ActivationProperties.WebId", web.ID.ToString());

                // to be able to change HistoryListId, TaskListId, ListId
                InvokeOnModelEvent <SP2013WorkflowSubscriptionDefinition, WorkflowSubscription>(newSubscription, ModelEventType.OnUpdated);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = newSubscription,
                    ObjectType       = typeof(WorkflowSubscription),
                    ObjectDefinition = workflowSubscriptionModel,
                    ModelHost        = host
                });

                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Calling PublishSubscription()");
                var currentSubscriptionId = workflowSubscriptionService.PublishSubscription(newSubscription);
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing SP2013 workflow subscription");

                currentSubscription.EventTypes = new List <string>(workflowSubscriptionModel.EventTypes);

                InvokeOnModelEvent <SP2013WorkflowSubscriptionDefinition, WorkflowSubscription>(currentSubscription, ModelEventType.OnUpdated);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentSubscription,
                    ObjectType       = typeof(WorkflowSubscription),
                    ObjectDefinition = workflowSubscriptionModel,
                    ModelHost        = host
                });

                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Calling PublishSubscription()");
                workflowSubscriptionService.PublishSubscription(currentSubscription);
            }
        }
Example #12
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");
            }
        }
Example #13
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);
            }
        }
Example #14
0
        private Folder EnsureLibraryFolder(FolderModelHost folderModelHost, FolderDefinition folderModel)
        {
            TraceService.Information((int)LogEventId.ModelProvisionCoreCall, "EnsureLibraryFolder()");

            var parentFolder = folderModelHost.CurrentListFolder;
            var context      = parentFolder.Context;

            var currentFolder = GetLibraryFolder(folderModelHost, folderModel);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = currentFolder,
                ObjectType       = typeof(Folder),
                ObjectDefinition = folderModel,
                ModelHost        = folderModelHost
            });

            if (currentFolder == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new library folder");

                currentFolder = parentFolder.Folders.Add(folderModel.Name);
                context.ExecuteQueryWithTrace();

#if !NET35
                // TODO for SP2010, mostlikely won't work :(
                // https://github.com/SubPointSolutions/spmeta2/issues/766

                context.Load(currentFolder, f => f.ListItemAllFields);
                context.Load(currentFolder, f => f.Name);
                context.ExecuteQueryWithTrace();

                var currentFolderItem = currentFolder.ListItemAllFields;

                // could be NULL, in the /Forms or other hidden folders
                if (currentFolderItem != null &&
                    currentFolderItem.ServerObjectIsNull != null &&
                    !currentFolderItem.ServerObjectIsNull.Value)
                {
                    MapProperties(currentFolderItem, folderModel);

                    currentFolderItem.Update();
                    context.ExecuteQueryWithTrace();
                }
#endif
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing library folder");

#if !NET35
                // TODO for SP2010, mostlikely won't work :(
                // https://github.com/SubPointSolutions/spmeta2/issues/766

                context.Load(currentFolder, f => f.ListItemAllFields);
                context.Load(currentFolder, f => f.Name);
                context.ExecuteQueryWithTrace();

                var currentFolderItem = currentFolder.ListItemAllFields;

                // could be NULL, in the /Forms or other hidden folders
                if (currentFolderItem != null &&
                    currentFolderItem.ServerObjectIsNull != null &&
                    !currentFolderItem.ServerObjectIsNull.Value)
                {
                    MapProperties(currentFolderItem, folderModel);

                    currentFolderItem.Update();
                    context.ExecuteQueryWithTrace();
                }
#endif
            }

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioned,
                Object           = currentFolder,
                ObjectType       = typeof(Folder),
                ObjectDefinition = folderModel,
                ModelHost        = folderModelHost
            });

            currentFolder.Update();
            context.ExecuteQueryWithTrace();

            return(currentFolder);
        }
Example #15
0
        private void DeployApp(object modelHost, WebModelHost webHost, AppDefinition appModel)
        {
            var web     = webHost.HostWeb;
            var context = web.Context;

            var appId = Guid.Empty;

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Creating memory stream on appModel.Content");

            using (var appPackage = new MemoryStream(appModel.Content))
            {
                var currentApplications = FindExistingApps(webHost, appModel);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioning,
                    Object           = currentApplications.FirstOrDefault(),
                    ObjectType       = typeof(AppInstance),
                    ObjectDefinition = appModel,
                    ModelHost        = modelHost
                });


                if (currentApplications == null || currentApplications.Count == 0)
                {
                    TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Cannot find application by productId. Loading and installing new instance.");

                    // install new
                    var newAppInstance = web.LoadAndInstallApp(appPackage);



                    context.Load(newAppInstance);
                    context.ExecuteQueryWithTrace();

                    if (newAppInstance != null && newAppInstance.Status == AppInstanceStatus.Initialized)
                    {
                        appId = newAppInstance.Id;

                        var         count         = 0;
                        AppInstance localInstance = null;

                        do
                        {
                            TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall,
                                                       "Waiting while app is being installed for [{0}] milliseconds.",
                                                       WaitTimeInMillliseconds);

                            Thread.Sleep(WaitTimeInMillliseconds);
                            localInstance = web.GetAppInstanceById(appId);

                            context.Load(localInstance, l => l.Status);
                            context.ExecuteQueryWithTrace();

                            count++;
                        } while (localInstance != null &&
                                 localInstance.Status != AppInstanceStatus.Installed &&
                                 count < MaxInstallAttempCount);
                    }

                    newAppInstance = web.GetAppInstanceById(appId);

                    InvokeOnModelEvent(this, new ModelEventArgs
                    {
                        CurrentModelNode = null,
                        Model            = null,
                        EventType        = ModelEventType.OnProvisioned,
                        Object           = newAppInstance,
                        ObjectType       = typeof(AppInstance),
                        ObjectDefinition = appModel,
                        ModelHost        = modelHost
                    });
                }
                else
                {
                    //we had check early
                    var currentApp = currentApplications.FirstOrDefault();

                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject,
                                             string.Format("Processing existing application. Upgrading from [{0}] to [{1}]", currentApp.Title, appModel.Version));

                    var hasUpdate = false;

                    for (int i = 0; i < currentApplications.Count; i++)
                    {
                        var spApp = currentApplications[i];
                        //var spAppVersion = new Version(spApp.App.VersionString);

                        var definitionVersion = new Version(appModel.Version);

                        // always install
                        //if (definitionVersion > spAppVersion)
                        //{
                        TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Performing upgrade");

                        var updateAppInstance = currentApplications[i];
                        var updateAppId       = updateAppInstance.Id;

                        var         count = 0;
                        AppInstance localUpdateAppInstance = null;

                        try
                        {
                            updateAppInstance.Upgrade(appPackage);
                            context.ExecuteQueryWithTrace();
                        }
                        catch (Exception upgradeException)
                        {
                            // handling early version upgrades
                            // Microsoft.SharePoint.Client.ServerException]
                            // {"An App Instance can only be upgraded to a newer version of the same product. The upgrade request was for product 1.0.0.3 version e81b6820-5d57-4d17-a098-5f4317f6c400 to product 1.0.0.0 version e81b6820-5d57-4d17-a098-5f4317f6c400."}

                            if (IsAppUpgradeException(upgradeException))
                            {
                                // fascinating
                                // jumping to the happy end
                                goto AppShouldNotBeUpdated;
                            }

                            throw;
                        }

                        do
                        {
                            TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall,
                                                       "Waiting while app is being installed for [{0}] milliseconds.",
                                                       WaitTimeInMillliseconds);

                            Thread.Sleep(WaitTimeInMillliseconds);
                            localUpdateAppInstance = web.GetAppInstanceById(updateAppId);

                            context.Load(localUpdateAppInstance, l => l.Status);
                            context.ExecuteQueryWithTrace();

                            count++;
                        } while (localUpdateAppInstance != null &&
                                 localUpdateAppInstance.Status != AppInstanceStatus.Installed &&
                                 count < MaxInstallAttempCount);

                        hasUpdate = true;

                        //}
                        //else
                        //{
                        //    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Skipping upgrade due to the lower version");
                        //}
                    }

                    if (hasUpdate)
                    {
                        // refreshing the app collection after update
                        // the .App.VersionString property will be refreshed
                        currentApplications = FindExistingApps(webHost, appModel);
                    }

AppShouldNotBeUpdated:

                    InvokeOnModelEvent(this, new ModelEventArgs
                    {
                        CurrentModelNode = null,
                        Model            = null,
                        EventType        = ModelEventType.OnProvisioned,
                        Object           = currentApplications.FirstOrDefault(),
                        ObjectType       = typeof(AppInstance),
                        ObjectDefinition = appModel,
                        ModelHost        = modelHost
                    });
                }
            }
        }
Example #16
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            var web = ExtractWeb(modelHost);
            var contentTypeModel = model.WithAssertAndCast <ContentTypeDefinition>("model", value => value.RequireNotNull());

            var site      = web.Site;
            var targetWeb = web;

            // SPBug, it has to be new SPWen for every content type operation inside feature event handler
            using (var tmpWeb = site.OpenWeb(targetWeb.ID))
            {
                var contentTypeId = new SPContentTypeId(contentTypeModel.GetContentTypeId());

                // by ID, by Name
                var targetContentType = tmpWeb.ContentTypes[contentTypeId];

                if (targetContentType == null)
                {
                    targetContentType = tmpWeb.ContentTypes
                                        .OfType <SPContentType>()
                                        .FirstOrDefault(f => f.Name.ToUpper() == contentTypeModel.Name.ToUpper());
                }

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioning,
                    Object           = targetContentType,
                    ObjectType       = typeof(SPContentType),
                    ObjectDefinition = contentTypeModel,
                    ModelHost        = modelHost
                });

                if (targetContentType == null)
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new content type");

                    targetContentType = tmpWeb
                                        .ContentTypes
                                        .Add(new SPContentType(contentTypeId, tmpWeb.ContentTypes, contentTypeModel.Name));
                }
                else
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing content type");
                }

                targetContentType.Hidden = contentTypeModel.Hidden;

                targetContentType.Name  = contentTypeModel.Name;
                targetContentType.Group = contentTypeModel.Group;

                if (contentTypeModel.Sealed.HasValue)
                {
                    targetContentType.Sealed = contentTypeModel.Sealed.Value;
                }

                if (contentTypeModel.ReadOnly.HasValue)
                {
                    targetContentType.ReadOnly = contentTypeModel.ReadOnly.Value;
                }

                // SPBug, description cannot be null
                targetContentType.Description = contentTypeModel.Description ?? string.Empty;

#if !NET35
                if (!string.IsNullOrEmpty(contentTypeModel.JSLink))
                {
                    targetContentType.JSLink = contentTypeModel.JSLink;
                }
#endif

                if (!string.IsNullOrEmpty(contentTypeModel.DocumentTemplate))
                {
                    var processedDocumentTemplateUrl = TokenReplacementService.ReplaceTokens(new TokenReplacementContext
                    {
                        Value   = contentTypeModel.DocumentTemplate,
                        Context = tmpWeb
                    }).Value;

                    // resource related path
                    if (!processedDocumentTemplateUrl.Contains('/') &&
                        !processedDocumentTemplateUrl.Contains('\\'))
                    {
                        processedDocumentTemplateUrl = UrlUtility.CombineUrl(new string[] {
                            targetContentType.ResourceFolder.ServerRelativeUrl,
                            processedDocumentTemplateUrl
                        });
                    }

                    targetContentType.DocumentTemplate = processedDocumentTemplateUrl;
                }

                ProcessLocalization(targetContentType, contentTypeModel);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = targetContentType,
                    ObjectType       = typeof(SPContentType),
                    ObjectDefinition = contentTypeModel,
                    ModelHost        = modelHost
                });

                TraceService.Information((int)LogEventId.ModelProvisionCoreCall, "Calling currentContentType.Update(true)");
                targetContentType.UpdateIncludingSealedAndReadOnly(true);

                tmpWeb.Update();
            }
        }
Example #17
0
        private SPListItem EnsureListFolder(FolderModelHost folderModelHost, FolderDefinition folderModel)
        {
            TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "EnsureListFolder()");

            var list = folderModelHost.CurrentList;
            var currentFolderItem = folderModelHost.CurrentListItem;

            var serverRelativeUrl = folderModelHost.CurrentListItem == null
                                                ? list.RootFolder.ServerRelativeUrl
                                                : folderModelHost.CurrentListItem.Folder.ServerRelativeUrl;

            var currentUrl    = serverRelativeUrl + "/" + folderModel.Name;
            var currentFolder = GetListFolder(folderModelHost, folderModel);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = currentFolder == null || !currentFolder.Exists ? null : currentFolder,
                ObjectType       = typeof(SPFolder),
                ObjectDefinition = folderModel,
                ModelHost        = folderModelHost
            });

            if (!currentFolder.Exists)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new list folder");

                currentFolderItem = list.AddItem(serverRelativeUrl, SPFileSystemObjectType.Folder);

                currentFolderItem[SPBuiltInFieldId.Title] = folderModel.Name;

                MapFolderProperties(currentFolderItem, folderModel);

                currentFolderItem.Update();

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentFolderItem.Folder,
                    ObjectType       = typeof(SPFolder),
                    ObjectDefinition = folderModel,
                    ModelHost        = folderModelHost
                });
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing list folder");

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentFolder,
                    ObjectType       = typeof(SPFolder),
                    ObjectDefinition = folderModel,
                    ModelHost        = folderModelHost
                });


                currentFolder.Update();

                currentFolderItem = currentFolder.Item;
                MapFolderProperties(currentFolderItem, folderModel);
                currentFolderItem.Update();
            }

            return(currentFolderItem);
        }
Example #18
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Extracting web from modelhost");
            var parentWeb = ExtractWeb(modelHost);

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Extracting host client context from model host");
            var hostclientContext = ExtractHostClientContext(modelHost);

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Casting web model definition");
            var webModel = model.WithAssertAndCast <WebDefinition>("model", value => value.RequireNotNull());

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Loading Url/ServerRelativeUrl");
            var context = parentWeb.Context;

            context.Load(parentWeb, w => w.Url);
            //context.Load(parentWeb, w => w.RootFolder);
            context.Load(parentWeb, w => w.ServerRelativeUrl);

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

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Extracting current web URL");
            var currentWebUrl = GetCurrentWebUrl(context, parentWeb, webModel);

            TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Current web URL: [{0}].", currentWebUrl);

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Loading existing web.");
            var currentWeb = GetExistingWeb(hostclientContext.Site, parentWeb, currentWebUrl);

            TraceService.Verbose((int)LogEventId.ModelProvisionUpdatingEventCall, "Calling OnUpdating event.");
            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = null,
                ObjectType       = typeof(Web),
                ObjectDefinition = model,
                ModelHost        = modelHost
            });

            InvokeOnModelEvent <WebDefinition, Web>(currentWeb, ModelEventType.OnUpdating);

            if (currentWeb == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new web");

                var newWebInfo = new WebCreationInformation
                {
                    Title       = webModel.Title,
                    Url         = webModel.Url,
                    Description = webModel.Description ?? string.Empty,
                    WebTemplate = webModel.WebTemplate,
                    UseSamePermissionsAsParentSite = !webModel.UseUniquePermission,
                    Language = (int)webModel.LCID
                };

                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Adding new web to the web collection and calling ExecuteQuery.");
                var newWeb = parentWeb.Webs.Add(newWebInfo);
                context.ExecuteQueryWithTrace();

                context.Load(newWeb);

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

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = newWeb,
                    ObjectType       = typeof(Web),
                    ObjectDefinition = model,
                    ModelHost        = modelHost
                });

                InvokeOnModelEvent <WebDefinition, Web>(newWeb, ModelEventType.OnUpdated);
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Current web is not null. Updating Title/Description.");

                currentWeb.Title       = webModel.Title;
                currentWeb.Description = webModel.Description ?? string.Empty;

                //  locale is not available with CSOM yet

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentWeb,
                    ObjectType       = typeof(Web),
                    ObjectDefinition = model,
                    ModelHost        = modelHost
                });
                InvokeOnModelEvent <WebDefinition, Web>(currentWeb, ModelEventType.OnUpdated);

                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "currentWeb.Update()");
                currentWeb.Update();

                context.ExecuteQueryWithTrace();
            }
        }
        private void DeployListWorkflowSubscriptionDefinition(
            object host,
            ClientContext hostclientContext, List list, SP2013WorkflowSubscriptionDefinition workflowSubscriptionModel)
        {
            // hostclientContext - it must be clientContext, not ClientRuntimeContext - won't work and would give some weirs error with wg publishing
            // use only clientContext instance for the workflow publishing, not ClientRuntimeContext

            var context = list.Context;
            var web     = list.ParentWeb;

            //This WorkflowServiceManager object is created for current web from client context,
            //but actually it has to be created for parent web of current web.
            //Otherwise it uses wrong web for provisions with multiple webs
            //var workflowServiceManager = new WorkflowServicesManager(hostclientContext, hostclientContext.Web);

            context.Load(web);
            context.Load(list);

            context.ExecuteQueryWithTrace();

            //This is creation of WorkflowServiceManager with right web
            var workflowServiceManager = new WorkflowServicesManager(hostclientContext, web);

            hostclientContext.Load(workflowServiceManager);
            hostclientContext.ExecuteQueryWithTrace();

            var workflowSubscriptionService = workflowServiceManager.GetWorkflowSubscriptionService();
            var workflowDeploymentService   = workflowServiceManager.GetWorkflowDeploymentService();
            var tgtwis = workflowServiceManager.GetWorkflowInstanceService();

            hostclientContext.Load(workflowSubscriptionService);
            hostclientContext.Load(workflowDeploymentService);
            hostclientContext.Load(tgtwis);

            hostclientContext.ExecuteQueryWithTrace();

            var publishedWorkflows = workflowDeploymentService.EnumerateDefinitions(true);

            hostclientContext.Load(publishedWorkflows);
            hostclientContext.ExecuteQueryWithTrace();

            var currentWorkflowDefinition = publishedWorkflows.FirstOrDefault(w => w.DisplayName == workflowSubscriptionModel.WorkflowDisplayName);

            if (currentWorkflowDefinition == null)
            {
                throw new Exception(string.Format("Cannot lookup workflow definition with display name: [{0}] on web:[{1}]", workflowSubscriptionModel.WorkflowDisplayName, web.Url));
            }

            var subscriptions = workflowSubscriptionService.EnumerateSubscriptionsByEventSource(list.Id);

            hostclientContext.Load(subscriptions);
            hostclientContext.ExecuteQueryWithTrace();

            InvokeOnModelEvent <SP2013WorkflowSubscriptionDefinition, WorkflowSubscription>(null, ModelEventType.OnUpdating);

            var currentSubscription = subscriptions.FirstOrDefault(s => s.Name == workflowSubscriptionModel.Name);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = currentSubscription,
                ObjectType       = typeof(WorkflowSubscription),
                ObjectDefinition = workflowSubscriptionModel,
                ModelHost        = host
            });

            if (currentSubscription == null)
            {
                var taskList    = GetTaskList(web, workflowSubscriptionModel);
                var historyList = GetHistoryList(web, workflowSubscriptionModel);

                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new SP2013 workflow subscription");

                var newSubscription = new WorkflowSubscription(hostclientContext);

                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Setting subscription properties");

                newSubscription.Name         = workflowSubscriptionModel.Name;
                newSubscription.DefinitionId = currentWorkflowDefinition.Id;

                newSubscription.EventTypes    = workflowSubscriptionModel.EventTypes;
                newSubscription.EventSourceId = list.Id;

                newSubscription.SetProperty("HistoryListId", historyList.Id.ToString());
                newSubscription.SetProperty("TaskListId", taskList.Id.ToString());

                newSubscription.SetProperty("ListId", list.Id.ToString());
                newSubscription.SetProperty("Microsoft.SharePoint.ActivationProperties.ListId", list.Id.ToString());

                // to be able to change HistoryListId, TaskListId, ListId
                InvokeOnModelEvent <SP2013WorkflowSubscriptionDefinition, WorkflowSubscription>(newSubscription, ModelEventType.OnUpdated);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = newSubscription,
                    ObjectType       = typeof(WorkflowSubscription),
                    ObjectDefinition = workflowSubscriptionModel,
                    ModelHost        = host
                });

                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Calling PublishSubscription()");
                var currentSubscriptionId = workflowSubscriptionService.PublishSubscription(newSubscription);
                hostclientContext.ExecuteQueryWithTrace();
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing SP2013 workflow subscription");

                currentSubscription.EventTypes = workflowSubscriptionModel.EventTypes;

                InvokeOnModelEvent <SP2013WorkflowSubscriptionDefinition, WorkflowSubscription>(currentSubscription, ModelEventType.OnUpdated);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentSubscription,
                    ObjectType       = typeof(WorkflowSubscription),
                    ObjectDefinition = workflowSubscriptionModel,
                    ModelHost        = host
                });

                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Calling PublishSubscription()");
                workflowSubscriptionService.PublishSubscription(currentSubscription);

                hostclientContext.ExecuteQueryWithTrace();
            }
        }
        protected virtual void DeploySolution(object modelHost,
                                              SPFarm farm,
                                              SPWebApplication webApplication,
                                              FarmSolutionDefinition definition,
                                              SPSolution existingSolution)
        {
            definition.SetPropertyBagValue("HadDeploymentHit");

            var webAppCollection = new Collection <SPWebApplication>();

            if (webApplication != null)
            {
                webAppCollection.Add(webApplication);
            }

            // either not deploed or not deployed to a particular web app
            if (!existingSolution.Deployed ||
                (webAppCollection.Any() && !existingSolution.DeployedWebApplications.Contains(webAppCollection.First())))
            {
                TraceService.Information((int)LogEventId.CoreCalls, string.Format("Deploying farm solution:[{0}]", existingSolution.Name));

                var isNowDeployment = false;

                if (definition.DeploymentDate.HasValue)
                {
                    if (webAppCollection.Any())
                    {
                        TraceService.Information((int)LogEventId.CoreCalls, string.Format("Deploying solution to web app on date [{0}]", definition.DeploymentDate.Value));


                        existingSolution.Deploy(definition.DeploymentDate.Value,
                                                definition.DeploymentGlobalInstallWPPackDlls,
                                                webAppCollection,
                                                definition.DeploymentForce);
                    }
                    else
                    {
                        TraceService.Information((int)LogEventId.CoreCalls, string.Format("Deploying solution globally on date [{0}]", definition.DeploymentDate.Value));

                        existingSolution.Deploy(definition.DeploymentDate.Value,
                                                definition.DeploymentGlobalInstallWPPackDlls,
                                                definition.DeploymentForce);
                    }
                }
                else
                {
                    if (webAppCollection.Any())
                    {
                        TraceService.Information((int)LogEventId.CoreCalls, string.Format("Deploying solution to web app NOW."));

                        existingSolution.Deploy(DateTime.Now,
                                                definition.DeploymentGlobalInstallWPPackDlls,
                                                webAppCollection,
                                                definition.DeploymentForce);
                    }
                    else
                    {
                        TraceService.Information((int)LogEventId.CoreCalls, string.Format("Deploying solution globaly NOW."));

                        existingSolution.Deploy(DateTime.Now,
                                                definition.DeploymentGlobalInstallWPPackDlls,
                                                definition.DeploymentForce);
                    }

                    isNowDeployment = true;
                }

                var deployed = existingSolution.DeploymentState != SPSolutionDeploymentState.NotDeployed;

                if (isNowDeployment)
                {
                    TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .Deployed status to be true"));

                    while (!deployed)
                    {
                        TraceService.Information((int)LogEventId.CoreCalls,
                                                 string.Format("Sleeping [{0}] milliseconds...", SolutionDeploymentTimeoutInMillisecond));
                        Thread.Sleep(SolutionDeploymentTimeoutInMillisecond);

                        TraceService.Information((int)LogEventId.CoreCalls,
                                                 string.Format("Checkin .Deployed for solution [{0}] in [{1}] milliseconds...",
                                                               existingSolution.Name, SolutionDeploymentTimeoutInMillisecond));

                        existingSolution = FindExistingSolution(modelHost, farm, webApplication, definition);
                        deployed         = existingSolution.DeploymentState != SPSolutionDeploymentState.NotDeployed;
                    }

                    TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .Deployed status to be false"));
                    var jobExists = existingSolution.JobExists;

                    while (jobExists)
                    {
                        TraceService.Information((int)LogEventId.CoreCalls,
                                                 string.Format("Sleeping [{0}] milliseconds...", SolutionDeploymentTimeoutInMillisecond));
                        Thread.Sleep(SolutionDeploymentTimeoutInMillisecond);


                        TraceService.Information((int)LogEventId.CoreCalls,
                                                 string.Format("Checkin .JobExists for solution [{0}] in [{1}] milliseconds...",
                                                               existingSolution.Name, SolutionDeploymentTimeoutInMillisecond));

                        existingSolution = FindExistingSolution(modelHost, farm, webApplication, definition);
                        jobExists        = existingSolution.JobExists;
                    }

                    TraceService.Information((int)LogEventId.CoreCalls, string.Format(".Deployed is true AND .JobExists is false"));
                }
                else
                {
                    TraceService.Information((int)LogEventId.CoreCalls, string.Format("Future deployment. Passing wait."));
                }
            }
            else
            {
                if (webAppCollection.Any())
                {
                    TraceService.Information((int)LogEventId.CoreCalls, string.Format("Farm solution:[{0}] was already deployed to web app", existingSolution.Name));
                }
                else
                {
                    TraceService.Information((int)LogEventId.CoreCalls, string.Format("Farm solution:[{0}] was already deployed.", existingSolution.Name));
                }
            }
        }
        private ListItem EnsureListFolder(FolderModelHost folderModelHost, FolderDefinition folderModel)
        {
            TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "EnsureListFolder()");

            var serverRelativeUrl = string.Empty;

            var list    = folderModelHost.CurrentList;
            var context = list.Context;

            var currentFolder     = GetListFolder(folderModelHost, folderModel, out serverRelativeUrl);
            var currentFolderItem = folderModelHost.CurrentListItem;

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = currentFolder,
                ObjectType       = typeof(Folder),
                ObjectDefinition = folderModel,
                ModelHost        = folderModelHost
            });

            context.ExecuteQueryWithTrace();

            if (currentFolder == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new list folder");

                currentFolderItem = list.AddItem(new ListItemCreationInformation
                {
                    FolderUrl            = serverRelativeUrl,
                    LeafName             = folderModel.Name,
                    UnderlyingObjectType = FileSystemObjectType.Folder
                });

                currentFolderItem[BuiltInInternalFieldNames.Title] = folderModel.Name;
                currentFolderItem.Update();

                context.ExecuteQueryWithTrace();

#if !NET35
                // TODO for SP2010, mostlikely won't work :(
                // https://github.com/SubPointSolutions/spmeta2/issues/766

                context.Load(currentFolderItem.Folder);
                context.ExecuteQueryWithTrace();

                currentFolder = currentFolderItem.Folder;

                context.Load(currentFolder, f => f.ListItemAllFields);
                context.Load(currentFolder, f => f.Name);

                context.ExecuteQueryWithTrace();

                currentFolderItem = currentFolder.ListItemAllFields;
#endif
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing list folder");

#if !NET35
                // TODO for SP2010, mostlikely won't work :(
                // https://github.com/SubPointSolutions/spmeta2/issues/766

                context.Load(currentFolder, f => f.ListItemAllFields);
                context.Load(currentFolder, f => f.Name);
                context.ExecuteQueryWithTrace();

                currentFolderItem = currentFolder.ListItemAllFields;
#endif
            }

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioned,
                Object           = currentFolder,
                ObjectType       = typeof(Folder),
                ObjectDefinition = folderModel,
                ModelHost        = folderModelHost
            });

            return(currentFolderItem);
        }
        protected virtual void UpgradeSolution(object modelHost,
                                               SPFarm farm,
                                               SPWebApplication webApplication,
                                               FarmSolutionDefinition definition,
                                               SPSolution existingSolution)
        {
            definition.SetPropertyBagValue("HadUpgradetHit");

            // ensure deployment state first
            TraceService.Information((int)LogEventId.CoreCalls, string.Format("Ensuring deployment state. Solution must be deployed before upgrading."));
            DeploySolution(modelHost, farm, webApplication, definition, existingSolution);

            // upgrade
            var tmpWspDirectory     = string.Format("{0}_{1}", Path.GetFileNameWithoutExtension(definition.FileName), Guid.NewGuid().ToString("N"));
            var tmpWspDirectoryPath = Path.Combine(Path.GetTempPath(), tmpWspDirectory);

            Directory.CreateDirectory(tmpWspDirectoryPath);

            var tmpWspFilPath = Path.Combine(tmpWspDirectoryPath, definition.FileName);

            File.WriteAllBytes(tmpWspFilPath, definition.Content);

            var isNowDeployment = false;

            if (definition.UpgradeDate.HasValue)
            {
                existingSolution.Upgrade(tmpWspFilPath, definition.UpgradeDate.Value);
            }
            else
            {
                existingSolution.Upgrade(tmpWspFilPath, DateTime.Now);
                isNowDeployment = true;
            }

            var deployed = existingSolution.Deployed;

            if (isNowDeployment)
            {
                TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .Deployed status to be true"));

                while (!deployed)
                {
                    TraceService.Information((int)LogEventId.CoreCalls,
                                             string.Format("Sleeping [{0}] milliseconds...", SolutionDeploymentTimeoutInMillisecond));
                    Thread.Sleep(SolutionDeploymentTimeoutInMillisecond);

                    TraceService.Information((int)LogEventId.CoreCalls,
                                             string.Format("Checkin .Deployed for solution [{0}] in [{1}] milliseconds...",
                                                           existingSolution.Name, SolutionDeploymentTimeoutInMillisecond));

                    existingSolution = FindExistingSolution(modelHost, farm, webApplication, definition);
                    deployed         = existingSolution.DeploymentState != SPSolutionDeploymentState.NotDeployed;
                }

                existingSolution = FindExistingSolution(modelHost, farm, webApplication, definition);
                TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .Deployed status to be false"));
                var jobExists = existingSolution.JobExists;

                while (jobExists)
                {
                    TraceService.Information((int)LogEventId.CoreCalls,
                                             string.Format("Sleeping [{0}] milliseconds...", SolutionDeploymentTimeoutInMillisecond));
                    Thread.Sleep(SolutionDeploymentTimeoutInMillisecond);


                    TraceService.Information((int)LogEventId.CoreCalls,
                                             string.Format("Checkin .JobExists for solution [{0}] in [{1}] milliseconds...",
                                                           existingSolution.Name, SolutionDeploymentTimeoutInMillisecond));

                    existingSolution = FindExistingSolution(modelHost, farm, webApplication, definition);
                    jobExists        = existingSolution.JobExists;
                }

                TraceService.Information((int)LogEventId.CoreCalls, string.Format(".Deployed is true AND .JobExists is false"));
            }
            else
            {
                TraceService.Information((int)LogEventId.CoreCalls, string.Format("Future upgrade. Passing wait."));
            }
        }
Example #23
0
        private void DeployWikiPage(Web web, Folder folder, WikiPageDefinition wikiPageModel)
        {
            var context = folder.Context;

            var newWikiPageUrl = string.Empty;
            var file           = GetWikiPageFile(web, folder, wikiPageModel, out newWikiPageUrl);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = file,
                ObjectType       = typeof(File),
                ObjectDefinition = wikiPageModel,
                ModelHost        = folder
            });

            if (file == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new wiki page");

                var newPageFile = folder.Files.AddTemplateFile(newWikiPageUrl, TemplateFileType.WikiPage);

                context.Load(newPageFile);

                var currentListItem = newPageFile.ListItemAllFields;
                context.Load(currentListItem);
                context.ExecuteQueryWithTrace();

                currentListItem[BuiltInInternalFieldNames.WikiField] = wikiPageModel.Content ?? String.Empty;
                currentListItem.Update();

                context.ExecuteQueryWithTrace();

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = newPageFile,
                    ObjectType       = typeof(File),
                    ObjectDefinition = wikiPageModel,
                    ModelHost        = folder
                });

                context.ExecuteQueryWithTrace();
            }
            else
            {
                // TODO,override if force
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing wiki page");

                if (wikiPageModel.NeedOverride)
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "NeedOverride = true. Updating wiki page content.");

                    var currentListItem = file.ListItemAllFields;
                    context.Load(currentListItem);
                    context.ExecuteQueryWithTrace();

                    currentListItem[BuiltInInternalFieldNames.WikiField] = wikiPageModel.Content ?? String.Empty;
                    currentListItem.Update();
                }
                else
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "NeedOverride = false. Skipping Updating wiki page content.");
                }

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = file,
                    ObjectType       = typeof(File),
                    ObjectDefinition = wikiPageModel,
                    ModelHost        = folder
                });

                context.ExecuteQueryWithTrace();
            }
        }
        protected virtual void RetractSolution(
            object modelHost,
            SPFarm farm,
            SPWebApplication webApplication,
            FarmSolutionDefinition definition,
            SPSolution existingSolution)
        {
            var webAppCollection = new Collection <SPWebApplication>();

            if (webApplication != null)
            {
                webAppCollection.Add(webApplication);
            }

            if (IsQARun)
            {
                definition.SetPropertyBagValue("HadRetractHit");
            }

            TraceService.Information((int)LogEventId.CoreCalls, string.Format("Retracting solution [{0}]", existingSolution.Name));

            if (existingSolution.Deployed)
            {
                var retracted = existingSolution.DeploymentState == SPSolutionDeploymentState.NotDeployed;

                if (webAppCollection.Any())
                {
                    TraceService.Information((int)LogEventId.CoreCalls, string.Format("Retracting solution from web application [{0}]", existingSolution.Name));
                    existingSolution.Retract(DateTime.Now, webAppCollection);
                }
                else
                {
                    TraceService.Information((int)LogEventId.CoreCalls, string.Format("Retracting solution from the farm [{0}]", existingSolution.Name));
                    existingSolution.Retract(DateTime.Now);
                }

                TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .Deployed status to be false"));

                if (webAppCollection.Any())
                {
                    // this is bad but we don't expext more than one web app here
                    var webApp = webAppCollection.First();

                    while (existingSolution.DeployedWebApplications.Contains(webApp))
                    {
                        TraceService.Information((int)LogEventId.CoreCalls,
                                                 string.Format("Sleeping [{0}] milliseconds...", SolutionDeploymentTimeoutInMillisecond));
                        Thread.Sleep(SolutionDeploymentTimeoutInMillisecond);

                        TraceService.Information((int)LogEventId.CoreCalls,
                                                 string.Format("Checkin .Deployed for solution [{0}] in [{1}] milliseconds...",
                                                               existingSolution.Name, SolutionDeploymentTimeoutInMillisecond));

                        existingSolution = FindExistingSolution(modelHost, farm, webApplication, definition);
                        retracted        = existingSolution.DeploymentState == SPSolutionDeploymentState.NotDeployed;
                    }
                }
                else
                {
                    while (!retracted)
                    {
                        TraceService.Information((int)LogEventId.CoreCalls,
                                                 string.Format("Sleeping [{0}] milliseconds...", SolutionDeploymentTimeoutInMillisecond));
                        Thread.Sleep(SolutionDeploymentTimeoutInMillisecond);

                        TraceService.Information((int)LogEventId.CoreCalls,
                                                 string.Format("Checkin .Deployed for solution [{0}] in [{1}] milliseconds...",
                                                               existingSolution.Name, SolutionDeploymentTimeoutInMillisecond));

                        existingSolution = FindExistingSolution(modelHost, farm, webApplication, definition);
                        retracted        = existingSolution.DeploymentState == SPSolutionDeploymentState.NotDeployed;
                    }
                }

                existingSolution = FindExistingSolution(modelHost, farm, webApplication, definition);

                TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .JobExists status to be false"));
                var jobExists = existingSolution.JobExists;

                while (jobExists)
                {
                    TraceService.Information((int)LogEventId.CoreCalls,
                                             string.Format("Sleeping [{0}] milliseconds...", SolutionDeploymentTimeoutInMillisecond));
                    Thread.Sleep(SolutionDeploymentTimeoutInMillisecond);


                    TraceService.Information((int)LogEventId.CoreCalls,
                                             string.Format("Checkin .JobExists for solution [{0}] in [{1}] milliseconds...",
                                                           existingSolution.Name, SolutionDeploymentTimeoutInMillisecond));

                    existingSolution = FindExistingSolution(modelHost, farm, webApplication, definition);
                    jobExists        = existingSolution.JobExists;
                }

                existingSolution = FindExistingSolution(modelHost, farm, webApplication, definition);

                TraceService.Information((int)LogEventId.CoreCalls, string.Format(".Deployed and .JobExists are false"));
            }
            else
            {
                TraceService.Information((int)LogEventId.CoreCalls, string.Format("Solution was already retracted."));
            }
        }
Example #25
0
        private void HandleWikiPageProvision(ListItem listItem,
                                             WebPartDefinitionBase webpartModel, Guid?currentWebPartStoreKey, Guid?oldWebParStoreKey)
        {
            if (!webpartModel.AddToPageContent)
            {
                return;
            }

            TraceService.Information((int)LogEventId.ModelProvisionCoreCall, "AddToPageContent = true. Handling wiki/publishig page provision case.");

            var context = listItem.Context;

            var targetFieldName = string.Empty;

            if (listItem.FieldValues.ContainsKey(BuiltInInternalFieldNames.WikiField))
            {
                TraceService.Information((int)LogEventId.ModelProvisionCoreCall, "WikiField field is detected. Switching to wiki page web part provision.");

                targetFieldName = BuiltInInternalFieldNames.WikiField;
            }
            else if (listItem.FieldValues.ContainsKey(BuiltInInternalFieldNames.PublishingPageLayout))
            {
                TraceService.Information((int)LogEventId.ModelProvisionCoreCall, "PublishingPageLayout field is detected. Switching to publishin page web part provision.");

                targetFieldName = BuiltInInternalFieldNames.PublishingPageContent;
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionCoreCall, "Not PublishingPageLayout field, nor WikiField is detected. Skipping.");
                return;
            }

            // any on the page?
            var existingWebPartId = string.Empty;

            // current from the new provision
            var upcomingWebPartId = string.Empty;

            // weird, by some web part ignor ID from the XML
            // so webpartStoreKey from the previous CSOM adding web part to the page must be used

            // M2 covers that fact with the regression testing, so we know what are they
            // and we have NOD idea why it happens
            if (ShouldUseWebPartStoreKeyForWikiPage)
            {
                upcomingWebPartId = currentWebPartStoreKey.ToString()
                                    .Replace("g_", string.Empty)
                                    .Replace("_", "-");;
            }
            else
            {
                // get from the model
                upcomingWebPartId = webpartModel.Id.ToString()
                                    .Replace("g_", string.Empty)
                                    .Replace("_", "-");;
            }

            if (!oldWebParStoreKey.HasGuidValue())
            {
                // first provision
                existingWebPartId = currentWebPartStoreKey.ToString()
                                    .Replace("g_", string.Empty)
                                    .Replace("_", "-");
            }
            else
            {
                // second provision,
                // we had web part on the page and can reuse that ID to relink on wiki content
                existingWebPartId = oldWebParStoreKey.ToString()
                                    .Replace("g_", string.Empty)
                                    .Replace("_", "-");
            }

            var content = listItem[targetFieldName] == null
                ? string.Empty
                : listItem[targetFieldName].ToString();

            var wikiTemplate = new StringBuilder();

            // actual ID will be replaced later
            wikiTemplate.AppendFormat("​​​​​​​​​​​​​​​​​​​​​​<div class='ms-rtestate-read ms-rte-wpbox' contentEditable='false'>");
            wikiTemplate.Append("     <div class='ms-rtestate-read {0}' id='div_{0}'>");
            wikiTemplate.AppendFormat("     </div>");
            wikiTemplate.AppendFormat("</div>");

            var wikiTemplateOutput = wikiTemplate.ToString();

            if (string.IsNullOrEmpty(content))
            {
                // page is empty, pre-generating HTML
                // pushing web part as the current WebPart Key
                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall,
                                     "Page content is empty Generating new one.");

                content = string.Format(wikiTemplateOutput, upcomingWebPartId);

                listItem[targetFieldName] = content;
                listItem.Update();

                context.ExecuteQueryWithTrace();
            }
            else
            {
                // there is a content on the page
                // there might be some web parts too
                if (oldWebParStoreKey.HasGuidValue())
                {
                    // there was an old web part on the page
                    // checking if markup has the ID

                    if (content.ToUpper().IndexOf(existingWebPartId.ToUpper()) != -1)
                    {
                        // was old web part on the page?
                        // yes, replacing ID
                        TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall,
                                                   string.Format("Replacing web part with ID: [{0}] to [{1}] on the page content.",
                                                                 existingWebPartId, upcomingWebPartId),
                                                   null);

                        content = content.Replace(existingWebPartId, upcomingWebPartId);

                        listItem[targetFieldName] = content;
                        listItem.Update();

                        context.ExecuteQueryWithTrace();
                    }
                    // original from the definigion?
                    else if (content.ToUpper().IndexOf(upcomingWebPartId.ToUpper()) != -1)
                    {
                        // yes, replacing ID
                        TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall,
                                                   string.Format("Replacing web part with ID: [{0}] to [{1}] on the page content.",
                                                                 existingWebPartId, upcomingWebPartId),
                                                   null);

                        // do nothing

                        listItem[targetFieldName] = content;
                        listItem.Update();

                        context.ExecuteQueryWithTrace();
                    }
                    else
                    {
                        // adding new, from scratch
                        TraceService.WarningFormat((int)LogEventId.ModelProvisionCoreCall,
                                                   "Cannot find web part ID: [{0}] the page content. Adding a new one.",
                                                   new object[]
                        {
                            existingWebPartId
                        });

                        content = content + string.Format(wikiTemplateOutput, upcomingWebPartId);

                        listItem[targetFieldName] = content;
                        listItem.Update();

                        context.ExecuteQueryWithTrace();
                    }
                }
                else
                {
                    // first provision of the web part on the page
                    if (content.ToUpper().IndexOf(upcomingWebPartId.ToUpper()) != -1)
                    {
                        // do nothing

                        listItem[targetFieldName] = content;
                        listItem.Update();

                        context.ExecuteQueryWithTrace();
                    }
                    else
                    {
                        // adding new, from scratch
                        TraceService.WarningFormat((int)LogEventId.ModelProvisionCoreCall,
                                                   "Cannot find web part ID: [{0}] the page content. Adding a new one.",
                                                   new object[]
                        {
                            existingWebPartId
                        });

                        content = content + string.Format(wikiTemplateOutput, upcomingWebPartId);

                        listItem[targetFieldName] = content;
                        listItem.Update();

                        context.ExecuteQueryWithTrace();
                    }
                }
            }
        }
        protected void ProcessView(object modelHost, SPList targetList, ListViewDefinition listViewModel)
        {
            var currentView = FindView(targetList, listViewModel);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = currentView,
                ObjectType       = typeof(SPView),
                ObjectDefinition = listViewModel,
                ModelHost        = modelHost
            });

            if (currentView == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new list view");

                var viewFields = new StringCollection();
                viewFields.AddRange(listViewModel.Fields.ToArray());

                var isPersonalView = false;
                var viewType       = (SPViewCollection.SPViewType)Enum.Parse(typeof(SPViewCollection.SPViewType),
                                                                             string.IsNullOrEmpty(listViewModel.Type) ? BuiltInViewType.Html : listViewModel.Type);

                // TODO, handle personal view creation
                currentView = targetList.Views.Add(
                    string.IsNullOrEmpty(listViewModel.Url) ? listViewModel.Title : GetSafeViewUrl(listViewModel.Url),
                    viewFields,
                    listViewModel.Query,
                    (uint)listViewModel.RowLimit,
                    listViewModel.IsPaged,
                    listViewModel.IsDefault,
                    viewType,
                    isPersonalView);

                currentView.Title = listViewModel.Title;
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing list view");
            }

            // viewModel.InvokeOnDeployingModelEvents<ListViewDefinition, SPView>(currentView);

            MapProperties(targetList, currentView, listViewModel);

            // viewModel.InvokeOnModelUpdatedEvents<ListViewDefinition, SPView>(currentView);

            ProcessLocalization(currentView, listViewModel);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioned,
                Object           = currentView,
                ObjectType       = typeof(SPView),
                ObjectDefinition = listViewModel,
                ModelHost        = modelHost
            });

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Calling currentView.Update()");
            currentView.Update();
        }
Example #27
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            var listItemModelHost = modelHost.WithAssertAndCast <ListItemModelHost>("modelHost", value => value.RequireNotNull());
            var webPartModel      = model.WithAssertAndCast <WebPartDefinitionBase>("model", value => value.RequireNotNull());

            var listItem = listItemModelHost.HostListItem;

            var context         = listItem.Context;
            var currentPageFile = GetCurrentPageFile(listItemModelHost);

            ModuleFileModelHandler.WithSafeFileOperation(listItem.ParentList, currentPageFile, pageFile =>
            {
                Guid?webPartStoreKey = null;

                InternalOnBeforeWebPartProvision(new WebPartProcessingContext
                {
                    ListItemModelHost = listItemModelHost,
                    WebPartDefinition = webPartModel,
                    WebPartStoreKey   = webPartStoreKey
                });

                //var fileContext = pageFile.Context;
                var fileListItem = pageFile.ListItemAllFields;
                var fileContext  = pageFile.Context;

                fileContext.Load(fileListItem);

                fileContext.ExecuteQueryWithTrace();

                var webPartManager = pageFile.GetLimitedWebPartManager(PersonalizationScope.Shared);

                // web part on the page
                var webpartOnPage      = webPartManager.WebParts.Include(wp => wp.Id, wp => wp.WebPart);
                var webPartDefenitions = context.LoadQuery(webpartOnPage);

                context.ExecuteQueryWithTrace();

                Microsoft.SharePoint.Client.WebParts.WebPartDefinition wpDefinition;

                WebPart existingWebPart = null;

                // TODO
                var tmpWp = FindExistingWebPart(webPartDefenitions, webPartModel, out wpDefinition);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioning,
                    Object           = existingWebPart,
                    ObjectType       = typeof(WebPart),
                    ObjectDefinition = webPartModel,
                    ModelHost        = modelHost
                });

                if (wpDefinition != null)
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject,
                                             "Deleting current web part.");

                    wpDefinition.DeleteWebPart();
                    wpDefinition.Context.ExecuteQueryWithTrace();
                }
                else
                {
                    existingWebPart = tmpWp;
                }

                Microsoft.SharePoint.Client.WebParts.WebPartDefinition webPartAddedDefinition = null;

                if (existingWebPart == null)
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject,
                                             "Processing new web part");

                    var webPartXML = GetWebpartXmlDefinition(listItemModelHost, webPartModel);
                    webPartXML     = ProcessCommonWebpartProperties(webPartXML, webPartModel);

                    // handle wiki page

                    HandleWikiPageProvision(fileListItem, webPartModel);

                    var webPartDefinition  = webPartManager.ImportWebPart(webPartXML);
                    webPartAddedDefinition = webPartManager.AddWebPart(webPartDefinition.WebPart,
                                                                       webPartModel.ZoneId,
                                                                       webPartModel.ZoneIndex);

                    context.Load(webPartAddedDefinition);

                    InvokeOnModelEvent <WebPartDefinition, WebPart>(null, ModelEventType.OnUpdating);

                    existingWebPart = webPartDefinition.WebPart;

                    InvokeOnModelEvent(this, new ModelEventArgs
                    {
                        CurrentModelNode = null,
                        Model            = null,
                        EventType        = ModelEventType.OnProvisioned,
                        Object           = existingWebPart,
                        ObjectType       = typeof(WebPart),
                        ObjectDefinition = webPartModel,
                        ModelHost        = modelHost
                    });

                    InvokeOnModelEvent <WebPartDefinition, WebPart>(null, ModelEventType.OnUpdated);
                }
                else
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject,
                                             "Processing existing web part");

                    HandleWikiPageProvision(fileListItem, webPartModel);

                    InvokeOnModelEvent(this, new ModelEventArgs
                    {
                        CurrentModelNode = null,
                        Model            = null,
                        EventType        = ModelEventType.OnProvisioned,
                        Object           = existingWebPart,
                        ObjectType       = typeof(WebPart),
                        ObjectDefinition = webPartModel,
                        ModelHost        = modelHost
                    });
                }

                context.ExecuteQueryWithTrace();

                if (webPartAddedDefinition != null && webPartAddedDefinition.ServerObjectIsNull == false)
                {
                    existingWebPart = webPartAddedDefinition.WebPart;
                    webPartStoreKey = webPartAddedDefinition.Id;
                }

                InternalOnAfterWebPartProvision(new WebPartProcessingContext
                {
                    ListItemModelHost = listItemModelHost,
                    WebPartDefinition = webPartModel,
                    WebPartStoreKey   = webPartStoreKey
                });

                return(pageFile);
            });
        }
Example #28
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            var site = ExtractSite(modelHost);
            var web  = ExtractWeb(modelHost);

            var contentTypeModel = model.WithAssertAndCast <ContentTypeDefinition>("model", value => value.RequireNotNull());
            var context          = web.Context;

            var contentTypeId = contentTypeModel.GetContentTypeId();

            var tmpContentType = context.LoadQuery(web.ContentTypes.Where(ct => ct.StringId == contentTypeId));

            context.ExecuteQuery();

            var tmp = tmpContentType.FirstOrDefault();

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = tmp,
                ObjectType       = typeof(ContentType),
                ObjectDefinition = model,
                ModelHost        = modelHost
            });

            InvokeOnModelEvent <ContentTypeDefinition, ContentType>(null, ModelEventType.OnUpdating);

            ContentType currentContentType = null;

            if (tmp == null || tmp.ServerObjectIsNull == null || tmp.ServerObjectIsNull.Value)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new content type");

                currentContentType = web.ContentTypes.Add(new ContentTypeCreationInformation
                {
                    Name              = contentTypeModel.Name,
                    Description       = string.IsNullOrEmpty(contentTypeModel.Description) ? string.Empty : contentTypeModel.Description,
                    Group             = contentTypeModel.Group,
                    Id                = contentTypeId,
                    ParentContentType = null
                });
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing content type");

                currentContentType = tmp;
            }

            currentContentType.Hidden = contentTypeModel.Hidden;

            currentContentType.Name        = contentTypeModel.Name;
            currentContentType.Description = string.IsNullOrEmpty(contentTypeModel.Description) ? string.Empty : contentTypeModel.Description;
            currentContentType.Group       = contentTypeModel.Group;

            if (!string.IsNullOrEmpty(contentTypeModel.DocumentTemplate))
            {
                var serverRelativeFolderUrl = ExtractResourceFolderServerRelativeUrl(web, context, currentContentType);

                var processedDocumentTemplateUrl = TokenReplacementService.ReplaceTokens(new TokenReplacementContext
                {
                    Value   = contentTypeModel.DocumentTemplate,
                    Context = context
                }).Value;

                // resource related path
                if (!processedDocumentTemplateUrl.Contains('/') &&
                    !processedDocumentTemplateUrl.Contains('\\'))
                {
                    processedDocumentTemplateUrl = UrlUtility.CombineUrl(new string[] {
                        serverRelativeFolderUrl,
                        processedDocumentTemplateUrl
                    });
                }

                currentContentType.DocumentTemplate = processedDocumentTemplateUrl;
            }

            InvokeOnModelEvent <ContentTypeDefinition, ContentType>(currentContentType, ModelEventType.OnUpdated);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioned,
                Object           = currentContentType,
                ObjectType       = typeof(ContentType),
                ObjectDefinition = model,
                ModelHost        = modelHost
            });

            TraceService.Information((int)LogEventId.ModelProvisionCoreCall, "Calling currentContentType.Update(true)");
            currentContentType.Update(true);

            context.ExecuteQueryWithTrace();
        }
Example #29
0
        private void DeployApp(object modelHost, WebModelHost webHost, AppDefinition appModel)
        {
            var  web   = webHost.HostWeb;
            Guid appId = Guid.Empty;

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Creating memory stream on appModel.Content");


            using (var appPackage = new MemoryStream(appModel.Content))
            {
                var currentApplications = FindExistingApps(webHost, appModel);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioning,
                    Object           = currentApplications.FirstOrDefault(),
                    ObjectType       = typeof(SPAppInstance),
                    ObjectDefinition = appModel,
                    ModelHost        = modelHost
                });

                if (currentApplications == null || currentApplications.Count == 0)
                {
                    TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Cannot find application by productId. Loading and installing new instance.");

                    // install new
                    var newAppInstance = web.LoadAndInstallApp(appPackage);

                    if (newAppInstance != null && newAppInstance.Status == SPAppInstanceStatus.Initialized)
                    {
                        appId = newAppInstance.Id;

                        var           count         = 0;
                        SPAppInstance localInstance = null;

                        do
                        {
                            TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall,
                                                       "Waiting while app is being installed for [{0}] milliseconds.",
                                                       WaitTimeInMillliseconds);

                            Thread.Sleep(WaitTimeInMillliseconds);
                            localInstance = web.GetAppInstanceById(appId);

                            count++;
                        } while (localInstance != null &&
                                 localInstance.Status != SPAppInstanceStatus.Installed &&
                                 count < MaxInstallAttempCount);
                    }

                    newAppInstance = web.GetAppInstanceById(appId);

                    InvokeOnModelEvent(this, new ModelEventArgs
                    {
                        CurrentModelNode = null,
                        Model            = null,
                        EventType        = ModelEventType.OnProvisioned,
                        Object           = newAppInstance,
                        ObjectType       = typeof(SPAppInstance),
                        ObjectDefinition = appModel,
                        ModelHost        = modelHost
                    });
                }
                else
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing application");

                    for (int i = 0; i < currentApplications.Count; i++)
                    {
                        var upApp     = currentApplications[i];
                        var upVersion = new Version(upApp.App.VersionString);

                        var targetVersion = new Version(appModel.Version);

                        if (upVersion < targetVersion)
                        {
                            currentApplications[i].Upgrade(appPackage);
                        }
                    }

                    InvokeOnModelEvent(this, new ModelEventArgs
                    {
                        CurrentModelNode = null,
                        Model            = null,
                        EventType        = ModelEventType.OnProvisioned,
                        Object           = currentApplications.FirstOrDefault(),
                        ObjectType       = typeof(SPAppInstance),
                        ObjectDefinition = appModel,
                        ModelHost        = modelHost
                    });
                }
            }
        }
Example #30
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            var folderModelHost  = modelHost as FolderModelHost;
            var webPartPageModel = model as WebPartPageDefinition;

            Folder folder = folderModelHost.CurrentLibraryFolder;

            //if (!string.IsNullOrEmpty(webPartPageModel.FolderUrl))
            //    throw new NotImplementedException("FolderUrl for the web part page model is not supported yet");

            var context = folder.Context;

            // #SPBug
            // it turns out that there is no support for the web part page creating via CMOM
            // we we need to get a byte array to 'hack' this pages out..
            // http://stackoverflow.com/questions/6199990/creating-a-sharepoint-2010-page-via-the-client-object-model
            // http://social.technet.microsoft.com/forums/en-US/sharepointgeneralprevious/thread/6565bac1-daf0-4215-96b2-c3b64270ec08

            var currentPage = GetCurrentWebPartPage(folderModelHost.CurrentList, folder, GetSafeWebPartPageFileName(webPartPageModel));

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = currentPage,
                ObjectType       = typeof(File),
                ObjectDefinition = webPartPageModel,
                ModelHost        = modelHost
            });

            if ((currentPage == null) || (currentPage != null && webPartPageModel.NeedOverride))
            {
                if (webPartPageModel.NeedOverride)
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing web part page");
                    TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "NeedOverride = true. Replacing web part page.");
                }
                else
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new web part page");
                }

                var file = new FileCreationInformation();

                var pageContent = string.Empty;

                if (!string.IsNullOrEmpty(webPartPageModel.CustomPageLayout))
                {
                    pageContent = webPartPageModel.CustomPageLayout;
                }
                else
                {
                    pageContent = GetWebPartTemplateContent(webPartPageModel);
                }

                var fileName = GetSafeWebPartPageFileName(webPartPageModel);

                file.Url       = fileName;
                file.Content   = Encoding.UTF8.GetBytes(pageContent);
                file.Overwrite = webPartPageModel.NeedOverride;

                var newFile = folder.Files.Add(file);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = newFile,
                    ObjectType       = typeof(File),
                    ObjectDefinition = webPartPageModel,
                    ModelHost        = modelHost
                });

                context.Load(newFile);
                context.ExecuteQueryWithTrace();
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing web part page");
                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "NeedOverride = false. Skipping replacing web part page.");

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentPage,
                    ObjectType       = typeof(File),
                    ObjectDefinition = webPartPageModel,
                    ModelHost        = modelHost
                });
            }
        }