/// <summary> /// Updates the metadata for the specified resource. /// </summary> /// <param name="collectionName">Name of the target collection.</param> /// <param name="memberResourceId">The Id of the member resource.</param> /// <param name="atomEntry">Describes the resource to be modified.</param> /// <returns>A SyndicationItem that describes the updated resource.</returns> /// <exception cref="ArgumentNullException">Throws exception if collectionName is null/empty /// or atomEntry is null.</exception> /// <exception cref="ArgumentException">Throws exception if requested memberResourceId is not a unique identifier.</exception> SyndicationItem IAtomPubStoreWriter.UpdateMemberInfo(string collectionName, string memberResourceId, AtomEntryDocument atomEntry) { if (string.IsNullOrEmpty(collectionName)) { throw new ArgumentNullException("collectionName"); } if (string.IsNullOrEmpty(memberResourceId)) { throw new ArgumentNullException("memberResourceId"); } if (null == atomEntry) { throw new ArgumentNullException("atomEntry"); } using (ZentityContext context = CoreHelper.CreateZentityContext()) { ScholarlyWork resource = (ScholarlyWork)AtomPubHelper.GetMember(context, collectionName, memberResourceId, "Update"); resource.Files.Load(); // Bug Fix : 177689 - AtomPub (M2): Author node is appending after every PUT request instead of overwriting it. resource.Authors.Load(); resource.Contributors.Load(); UpdateResourceProperty(context, resource, atomEntry); context.SaveChanges(); return(ZentityAtomPubStoreReader.GenerateSyndicationItem(this.BaseUri, resource)); } }
/// <summary> /// Creates a new resource of type collectionName in the repository. /// </summary> /// <param name="collectionName">The resource type.</param> /// <param name="atomEntry">Information about the resource.</param> /// <returns>A SyndicationItem that describes the newly created resource.</returns> /// <exception cref="ArgumentNullException">Throws exception if collectionName is null/empty /// or atomEntry is null/empty .</exception> SyndicationItem IAtomPubStoreWriter.CreateMember(string collectionName, AtomEntryDocument atomEntry) { if (string.IsNullOrEmpty(collectionName)) { throw new ArgumentNullException("collectionName"); } if (null == atomEntry) { throw new ArgumentNullException("atomEntry"); } AuthenticatedToken authenticatedToken = CoreHelper.GetAuthenticationToken(); using (ZentityContext context = CoreHelper.CreateZentityContext()) { if (!authenticatedToken.HasCreatePermission(context)) { throw new UnauthorizedException(Resources.ATOMPUB_UNAUTHORIZED); } ScholarlyWork resource = CreateScholarlyWork(collectionName); context.AddToResources(resource); ZentityAtomPubStoreWriter.UpdateResourceProperty(context, resource, atomEntry); resource.GrantDefaultPermissions(context, authenticatedToken); context.SaveChanges(); return(ZentityAtomPubStoreReader.GenerateSyndicationItem(this.BaseUri, resource)); } }
/// <summary> /// Gets the specified resource. /// </summary> /// <param name="collectionName">The name of the resource type.</param> /// <param name="memberResourceId">The Guid of the resource to return.</param> /// <returns>A SyndicationItem for the specified resource.</returns> /// <exception cref="ArgumentNullException">Throws exception if collectionName is null/empty.</exception> SyndicationItem IAtomPubStoreReader.GetMember(string collectionName, string memberResourceId) { using (ZentityContext context = CoreHelper.CreateZentityContext()) { ScholarlyWork resource = (ScholarlyWork)AtomPubHelper.GetMember(context, collectionName, memberResourceId, "Read"); return(ZentityAtomPubStoreReader.GenerateSyndicationItem(this.BaseUri, resource)); } }
/// <summary> /// Updates the Resource.File of the specified resource. /// </summary> /// <param name="collectionName">The type of the resource.</param> /// <param name="memberResourceId">The resource whose File needs to be updated.</param> /// <param name="mimeType">The MIME type of media.</param> /// <param name="media">The new File contents.</param> /// <returns>A SyndicationItem that describes the updated resource.</returns> /// <exception cref="ArgumentNullException">Throws exception if collectionName is null/empty /// or media is null.</exception> /// <exception cref="ArgumentException">Throws exception if requested memberResourceId is not a unique identifier.</exception> SyndicationItem IAtomPubStoreWriter.UpdateMedia(string collectionName, string memberResourceId, string mimeType, byte[] media) { if (string.IsNullOrEmpty(collectionName)) { throw new ArgumentNullException("collectionName"); } if (null == media) { throw new ArgumentNullException("media"); } if (string.IsNullOrEmpty(memberResourceId)) { throw new ArgumentNullException("memberResourceId"); } if (!AtomPubHelper.IsValidGuid(memberResourceId)) { throw new ArgumentException(Resources.ATOMPUB_INVALID_RESOURCE_ID, "memberResourceId"); } using (ZentityContext context = CoreHelper.CreateZentityContext()) { Type collectionType = CoreHelper.GetSystemResourceType(collectionName); // Prepare a query to get a resource with specified Id and specified type. string commandText = string.Format(CultureInfo.InvariantCulture, AtomPubConstants.EsqlToGetFileContents, collectionType.FullName); ObjectQuery <Core.File> query = new ObjectQuery <Core.File>(commandText, context); query.Parameters.Add(new ObjectParameter("Id", new Guid(memberResourceId))); Core.File mediaResource = query.FirstOrDefault(); if (null == mediaResource) { throw new ResourceNotFoundException(Resources.ATOMPUB_RESOURCE_NOT_FOUND); } if (!mediaResource.Authorize("Update", context, CoreHelper.GetAuthenticationToken())) { throw new UnauthorizedException(Resources.ATOMPUB_UNAUTHORIZED); } mediaResource.Resources.Load(); ScholarlyWork resource = (ScholarlyWork)mediaResource.Resources.First(); resource.DateModified = DateTime.Now; mediaResource.MimeType = mimeType; mediaResource.FileExtension = AtomPubHelper.GetFileExtension(mimeType); MemoryStream mediaStream = ZentityAtomPubStoreWriter.GetMediaStream(media); context.UploadFileContent(mediaResource, mediaStream); // Bug Fix : 180811 - Save Changes once mime type and contents are set. context.SaveChanges(); return(ZentityAtomPubStoreReader.GenerateSyndicationItem(this.BaseUri, resource)); } }
/// <summary> /// Creates a new Resource.File for a specified resource of type collectionName in the repository. /// </summary> /// <param name="collectionName">The resource type.</param> /// <param name="mimeType">The MIME type of media.</param> /// <param name="media">The new File contents.</param> /// <param name="fileExtension">The media file extension.</param> /// <returns>A SyndicationItem that describes the newly created resource.</returns> /// <exception cref="ArgumentNullException">Throws exception if collectionName is null/empty /// or mimeType is null/empty or media is null.</exception> protected SyndicationItem CreateMedia(string collectionName, string mimeType, byte[] media, string fileExtension) { if (string.IsNullOrEmpty(collectionName)) { throw new ArgumentNullException("collectionName"); } if (string.IsNullOrEmpty(mimeType)) { throw new ArgumentNullException("mimeType"); } if (null == media) { throw new ArgumentNullException("media"); } AuthenticatedToken authenticatedToken = CoreHelper.GetAuthenticationToken(); using (ZentityContext context = CoreHelper.CreateZentityContext()) { if (!authenticatedToken.HasCreatePermission(context)) { throw new UnauthorizedException(Resources.ATOMPUB_UNAUTHORIZED); } ScholarlyWork resource = CreateScholarlyWork(collectionName); resource.DateModified = DateTime.Now; Core.File mediaResource = new Core.File(); mediaResource.MimeType = mimeType; mediaResource.FileExtension = string.IsNullOrEmpty(fileExtension) ? AtomPubHelper.GetFileExtension(mimeType) : fileExtension; context.AddToResources(mediaResource); context.SaveChanges(); resource.Files.Add(mediaResource); MemoryStream mediaStream = ZentityAtomPubStoreWriter.GetMediaStream(media); context.UploadFileContent(mediaResource, mediaStream); mediaStream.Close(); resource.GrantDefaultPermissions(context, authenticatedToken); mediaResource.GrantDefaultPermissions(context, authenticatedToken); context.SaveChanges(); return(ZentityAtomPubStoreReader.GenerateSyndicationItem(this.BaseUri, resource)); } }
/// <summary> /// Gets a SyndicationFeed containing resources of type collectionName. /// </summary> /// <param name="collectionName">The name of the resource type.</param> /// <param name="skip">The number of resources to skip from the start.</param> /// <param name="count">The number of resources to return.</param> /// <returns>A SyndicationFeed of resources of the specified type.</returns> /// <exception cref="ArgumentNullException">Throws exception if collectionName is null/empty.</exception> /// <exception cref="ArgumentException">Throws exception if skip value is negative or count value is negative.</exception> SyndicationFeed IAtomPubStoreReader.GetMembers(string collectionName, long skip, long count) { if (string.IsNullOrEmpty(collectionName)) { throw new ArgumentNullException("collectionName"); } if (0 > skip) { throw new ArgumentException(Resources.ATOMPUB_INVALID_VALUE, "skip"); } if (0 > count) { throw new ArgumentException(Resources.ATOMPUB_INVALID_VALUE, "count"); } int skipCount = (int)skip; int takeCount = (int)count; ResourceType collectionType = coreHelper.GetResourceType(collectionName); // Prepare a query to get a resource with specified Id and specified type. string commandText = string.Format(CultureInfo.InvariantCulture, AtomPubConstants.EsqlToGetAllResources, collectionType.FullName); AuthenticatedToken authenticatedToken = CoreHelper.GetAuthenticationToken(); using (ZentityContext zentityContext = CoreHelper.CreateZentityContext()) { ObjectQuery <ScholarlyWork> resourcesQuery = new ObjectQuery <ScholarlyWork>(commandText, zentityContext); List <ScholarlyWork> resources = resourcesQuery.Authorize("Read", zentityContext, authenticatedToken) .OrderByDescending(resource => resource.DateModified) .Skip(skipCount).Take(takeCount) .ToList(); List <SyndicationItem> syndicationItems = new List <SyndicationItem>(); if (null != resources && 0 < resources.Count) { foreach (ScholarlyWork resource in resources) { SyndicationItem syndicationItem = ZentityAtomPubStoreReader.GenerateSyndicationItem(this.BaseUri, resource); syndicationItems.Add(syndicationItem); } } return(new SyndicationFeed(syndicationItems)); } }
/// <summary> /// Sets the extension property. /// </summary> /// <param name="context">The context.</param> /// <param name="resource">The resource.</param> /// <param name="propertyName">Name of the property.</param> /// <param name="propertyValue">The property value.</param> private static void SetExtensionProperty( ZentityContext context, ScholarlyWork resource, string propertyName, string propertyValue) { ResourceProperty resourceProperty = ZentityAtomPubStoreReader.GetResourceProperty(resource, propertyName); if (null == resourceProperty) { Property extensionProperty = GetProperty(context, propertyName); resourceProperty = new ResourceProperty { Property = extensionProperty, Resource = resource, }; } resourceProperty.Value = propertyValue; }
/// <summary> /// Creates a <typeref name="System.ServiceModel.Syndication.SyndicationItem"/> item /// for the given resource. /// </summary> /// <param name="resource">The associated resource.</param> /// <returns>The SyndicationItem Object.</returns> private static SyndicationItem CreateSyndicationItem(Resource resource) { if (null == resource) { return(null); } SyndicationItem item = new SyndicationItem(); ScholarlyWorks.ScholarlyWork scholarlyWork = resource as ScholarlyWorks.ScholarlyWork; if (null != scholarlyWork) { item = ZentityAtomPubStoreReader.GenerateSyndicationItem(new Uri( ConfigurationManager.AppSettings["ServiceHost"] + ConfigurationManager.AppSettings["AtomPubBaseUri"]), scholarlyWork); } else { //TODO: Would Title be Non Empty always.. If no then what would be the heading for the feed? item.Title = new TextSyndicationContent( string.IsNullOrEmpty(resource.Title) ? string.Empty : resource.Title); item.Id = "urn:guid:" + resource.Id.ToString(); item.Summary = new TextSyndicationContent(resource.Description); if (null != resource.DateAdded && DateTime.MinValue != resource.DateAdded.Value) { item.PublishDate = new DateTimeOffset(resource.DateAdded.Value); } if (null != resource.DateModified && DateTime.MinValue != resource.DateModified.Value) { item.LastUpdatedTime = new DateTimeOffset(resource.DateModified.Value); } } return(item); }
/// <summary> /// Updates the resource property. /// </summary> /// <param name="context">The context.</param> /// <param name="resource">The resource.</param> /// <param name="atomEntry">The atom entry.</param> private static void UpdateResourceProperty( ZentityContext context, ScholarlyWork resource, AtomEntryDocument atomEntry) { resource.Title = atomEntry.Title.Text; SetContentType(context, resource, atomEntry.Title.Type, AtomPubConstants.TitleTypeProperty); resource.DateModified = DateTime.Now; Publication publication = resource as Publication; if (null != publication && atomEntry.PublishDate != DateTimeOffset.MinValue) { publication.DatePublished = atomEntry.PublishDate.DateTime; } if (null != atomEntry.Copyright) { resource.Copyright = atomEntry.Copyright.Text; SetContentType(context, resource, atomEntry.Copyright.Type, AtomPubConstants.CopyrightTypeProperty); } if (null != atomEntry.Summary && !string.IsNullOrEmpty(atomEntry.Summary.Text)) { SetExtensionProperty(context, resource, AtomPubConstants.SummaryProperty, atomEntry.Summary.Text); SetContentType(context, resource, atomEntry.Summary.Type, AtomPubConstants.SummaryTypeProperty); } if (null != atomEntry.Content) { UrlSyndicationContent urlContent = atomEntry.Content as UrlSyndicationContent; if (null != urlContent) { resource.Description = null; SetExtensionProperty(context, resource, AtomPubConstants.ContentUrlProperty, urlContent.Url.AbsoluteUri); } else { ResourceProperty urlContentProperty = ZentityAtomPubStoreReader.GetResourceProperty(resource, AtomPubConstants.ContentUrlProperty); if (null != urlContentProperty) { resource.ResourceProperties.Remove(urlContentProperty); } TextSyndicationContent textDescription = atomEntry.Content as TextSyndicationContent; if (null != textDescription) { resource.Description = textDescription.Text; } else { XmlSyndicationContent content = atomEntry.Content as XmlSyndicationContent; if (null != content) { XmlDictionaryReader contentReader = content.GetReaderAtContent(); StringBuilder contentValue = new StringBuilder(151); try { while (contentReader.Read()) { contentValue.Append(contentReader.Value); } } finally { contentReader.Close(); } resource.Description = contentValue.ToString(); } } } SetContentType(context, resource, atomEntry.Content.Type, AtomPubConstants.DescriptionTypeProperty); } if (null != atomEntry.Source) { ResourceProperty source = ZentityAtomPubStoreReader.GetResourceProperty(resource, AtomPubConstants.SourceProperty); if (null == source) { Property sourceProperty = GetProperty(context, AtomPubConstants.SourceProperty); source = new ResourceProperty { Property = sourceProperty, Resource = resource, }; } source.Value = atomEntry.Source; } #region Add Links List <ResourceProperty> links = ZentityAtomPubStoreReader.GetResourceProperties(resource, AtomPubConstants.LinksProperty); if (0 == atomEntry.XmlLinks.Count && null != links) { foreach (var item in links) { resource.ResourceProperties.Remove(item); } } Property linkProperty = GetProperty(context, AtomPubConstants.LinksProperty); foreach (string xmlLink in atomEntry.XmlLinks) { resource.ResourceProperties.Add(new ResourceProperty { Resource = resource, Property = linkProperty, Value = xmlLink }); } #endregion var authors = atomEntry.Authors.Select(author => new Person { Title = author.Name, Email = author.Email, Uri = author.Uri }); // Bug Fix : 177689 - AtomPub (M2): Author node is appending after every PUT request instead // of overwriting it. // Remove previous authors. resource.Authors.Clear(); AddPersons(context, resource.Authors, authors); resource.Contributors.Clear(); var contributors = atomEntry.Contributors.Select(author => new Person { Title = author.Name, Email = author.Email, Uri = author.Uri }); AddPersons(context, resource.Contributors, contributors); }
/// <summary> /// Creates a new Resource.File for a specified resource of type collectionName in the repository. /// </summary> /// <param name="collectionName">The resource type.</param> /// <param name="mimeType">The MIME type of media.</param> /// <param name="media">The new File contents.</param> /// <param name="fileExtension">The media file extension.</param> /// <returns>A SyndicationItem that describes the newly created resource.</returns> SyndicationItem IAtomPubStoreWriter.CreateMedia(string collectionName, string mimeType, byte[] media, string fileExtension) { if (string.IsNullOrEmpty(collectionName)) { throw new ArgumentNullException("collectionName"); } if (string.IsNullOrEmpty(mimeType)) { throw new ArgumentNullException("mimeType"); } if (null == media) { throw new ArgumentNullException("media"); } if (SwordConstants.ZipContentType != mimeType) { return(base.CreateMedia(collectionName, mimeType, media, fileExtension)); } // Convert byte array to stream. MemoryStream mediaStream = ZentityAtomPubStoreWriter.GetMediaStream(media); string extractionPath = ExtractZipContent(mediaStream); HttpContext.Current.Items[SwordConstants.ZipExtractedPath] = extractionPath; // Get the path of METS xml file. string metsFilePath = extractionPath + "\\" + SwordConstants.MetsDocumentName; if (!System.IO.File.Exists(metsFilePath)) { //string errorMessage = string.Format(CultureInfo.CurrentCulture, // Properties.Resources.SWORD_MISSING_METS_DOCUMENT, // SwordConstants.MetsDocumentName); //throw new MetsException(errorMessage); return(base.CreateMedia(collectionName, mimeType, media, fileExtension)); } AuthenticatedToken authenticatedToken = CoreHelper.GetAuthenticationToken(); using (ZentityContext zentityContext = CoreHelper.CreateZentityContext()) { if (!authenticatedToken.HasCreatePermission(zentityContext)) { throw new UnauthorizedException(Resources.ATOMPUB_UNAUTHORIZED); } // Generate METS document from given METS xml file. MetsDocument document = new MetsDocument(metsFilePath); // Create resource of specified collection type. ScholarlyWork resource = CreateScholarlyWork(collectionName); resource.DateModified = DateTime.Now; // Upload the zip file contents as media for main resource. // This will be required in AtomPub get requests and further use. Core.File mediaResource = AddFileResource(zentityContext, resource, mediaStream); mediaResource.MimeType = mimeType; mediaResource.FileExtension = AtomPubHelper.GetFileExtension(mimeType); // close the stream mediaStream.Close(); AddChildResources(extractionPath, document, resource, zentityContext); resource.GrantDefaultPermissions(zentityContext, authenticatedToken); mediaResource.GrantDefaultPermissions(zentityContext, authenticatedToken); // Save all changes at the end zentityContext.SaveChanges(); return(ZentityAtomPubStoreReader.GenerateSyndicationItem(base.BaseUri, resource)); } }
/// <summary> /// Adds the links and source. /// </summary> /// <param name="baseUri">The base URI.</param> /// <param name="resource">The resource.</param> /// <param name="item">The syndication item.</param> private static void AddLinksAndSource(Uri baseUri, ScholarlyWork resource, ref SyndicationItem item) { // NameValue pair for creating Uri from UriTemplate. NameValueCollection parameters = new NameValueCollection(); parameters.Add(AtomPubParameterType.CollectionName.ToString(), resource.GetType().Name); parameters.Add(AtomPubParameterType.Id.ToString(), resource.Id.ToString()); Core.File mediaFile = resource.Files.FirstOrDefault(); if (null != mediaFile) { Uri mediaUri = AtomPubHelper.AtomPubTemplates[AtomPubRequestType.EditMedia] .BindByName(baseUri, parameters); // Add content linnk and edit-media link if (string.IsNullOrEmpty(mediaFile.MimeType)) { mediaFile.MimeType = AtomPubConstants.DefaultMimeType; } SyndicationLink resourceMediaLink = new SyndicationLink(mediaUri); resourceMediaLink.RelationshipType = AtomPubConstants.EditMedia; item.Links.Add(resourceMediaLink); item.Content = new UrlSyndicationContent(mediaUri, mediaFile.MimeType); } else { ResourceProperty urlContent = GetResourceProperty(resource, AtomPubConstants.ContentUrlProperty); if (null != urlContent && !string.IsNullOrEmpty(urlContent.Value)) { item.Content = GetContent <UrlSyndicationContent>(urlContent.Value, resource.ResourceProperties, AtomPubConstants.DescriptionTypeProperty, false); } else { item.Content = GetContent <SyndicationContent>(resource.Description, resource.ResourceProperties, AtomPubConstants.DescriptionTypeProperty, true); } } // Add resource Edit link Uri resourceUri = AtomPubHelper.AtomPubTemplates[AtomPubRequestType.EditMember].BindByName(baseUri, parameters); SyndicationLink resourceEditLink = new SyndicationLink(resourceUri); resourceEditLink.RelationshipType = AtomPubConstants.Edit; item.Links.Add(resourceEditLink); if (null != resource.Container) { var relatedItems = resource.Container.ContainedWorks.OfType <ScholarlyWorkContainer>() .SelectMany(tuple => tuple.ContainedWorks) .Where(tuple => !(tuple is ScholarlyWorkContainer)); foreach (ScholarlyWork containedItem in relatedItems) { parameters.Set(AtomPubParameterType.CollectionName.ToString(), containedItem.GetType().Name); parameters.Set(AtomPubParameterType.Id.ToString(), containedItem.Id.ToString()); resourceUri = AtomPubHelper.AtomPubTemplates[AtomPubRequestType.EditMember].BindByName(baseUri, parameters); SyndicationLink containsEditLink = new SyndicationLink(resourceUri); containsEditLink.RelationshipType = AtomPubConstants.Related; item.Links.Add(containsEditLink); } } AtomEntryDocument entry = new AtomEntryDocument(item); IEnumerable <ResourceProperty> links = ZentityAtomPubStoreReader.GetResourceProperties(resource, AtomPubConstants.LinksProperty); if (null != links) { foreach (ResourceProperty link in links) { entry.XmlLinks.Add(link.Value); } } ResourceProperty source = GetResourceProperty(resource, AtomPubConstants.SourceProperty); if (null != source) { entry.Source = source.Value; } using (XmlReader reader = new XmlTextReader(entry.AtomEntry, XmlNodeType.Document, null)) { item = SyndicationItem.Load(reader); } }