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(); } }
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 }); }
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); }
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); } }
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); }
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(); }
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(); } }
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(); } }
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); } }
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"); } }
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); } }
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); }
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 }); } } }
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(); } }
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); }
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.")); } }
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.")); } }
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(); }
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); }); }
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(); }
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 }); } } }
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 }); } }