/// <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> /// Processes the request. /// </summary> /// <param name="context">The HttpContext for the incoming HTTP request.</param> /// <param name="statusCode">The HTTP Status Code that must be returned to the client.</param> /// <returns>The response that must be sent to the client.</returns> public override string ProcessRequest(HttpContext context, out HttpStatusCode statusCode) { if (!AtomPubHelper.ValidatePrecondition(context, base.BaseUri, out statusCode)) { if (HttpStatusCode.PreconditionFailed == statusCode) { return(Properties.Resources.ATOMPUB_PRECONDITION_FAILED); } else { return(Properties.Resources.ATOMPUB_RESOURCE_NOT_MODIFIED); } } string errorMessage = string.Empty; // used to hold updated member metadata. AtomEntryDocument atomDocument = null; AtomPubRequestType requestType = AtomPubHelper.GetAtomPubRequestType(context, base.BaseUri); try { switch (requestType) { case AtomPubRequestType.EditMember: atomDocument = UpdateMember(context); break; case AtomPubRequestType.EditMedia: atomDocument = UpdateMedia(context); break; case AtomPubRequestType.ServiceDocument: case AtomPubRequestType.Collection: case AtomPubRequestType.CollectionWithPageNo: case AtomPubRequestType.Unknwon: default: statusCode = HttpStatusCode.BadRequest; errorMessage = Resources.ATOMPUB_INVALID_URL; break; } } catch (ResourceNotFoundException) { statusCode = HttpStatusCode.NotFound; return(Properties.Resources.ATOMPUB_RESOURCE_NOT_FOUND); } if (null != atomDocument) { statusCode = HttpStatusCode.OK; string memberId = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.Id); string eTag = AtomPubHelper.CalculateETag(memberId); context.Response.AddHeader(AtomPubConstants.KeyETag, eTag); return(atomDocument.AtomEntry); } else { return(errorMessage); } }
/// <summary> /// Gets the AtomEntryDocument from the specified collection and for the specified member resource. /// </summary> /// <param name="collectionName">The collection name.</param> /// <param name="memberResourceId">The Id of the member resource.</param> /// <returns>An AtomEntryDocument containing information for the member resource.</returns> private AtomEntryDocument GetAtomEntryDocument(string collectionName, string memberResourceId) { IAtomPubStoreReader storeReader = AtomPubStoreFactory.GetAtomPubStoreReader(base.BaseUri.OriginalString); SyndicationItem syndicationItem = storeReader.GetMember(collectionName, memberResourceId); AtomEntryDocument atomEntryDoc = new AtomEntryDocument(syndicationItem); return(atomEntryDoc); }
/// <summary> /// Creates a member resource using the information present in the HttpContext. /// </summary> /// <param name="context">The HttpContext for the incoming HTTP request.</param> /// <returns>An AtomEntryDocument corresponding to the newly created member resource.</returns> private AtomEntryDocument CreateMember(HttpContext context) { string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); //Get AtomEntryDocument for request to update the member information. AtomEntryDocument atomEntry = new AtomEntryDocument(context.Request.InputStream); IAtomPubStoreWriter atomPubStoreWriter = AtomPubStoreFactory.GetAtomPubStoreWriter(base.BaseUri.OriginalString); SyndicationItem item = atomPubStoreWriter.CreateMember(collectionName, atomEntry); // Create atom entry document from syndication item. return(new AtomEntryDocument(item)); }
/// <summary> /// Updates a member resource using the information present in the HttpContext. /// </summary> /// <param name="context">The HttpContext for the incoming HTTP request.</param> /// <returns>An AtomEntryDocument corresponding to the updated member resource.</returns> private AtomEntryDocument UpdateMember(HttpContext context) { // Gets the atom request template match result to get requested collection name. string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); string memberId = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.Id); IAtomPubStoreWriter atomPubStoreWriter = AtomPubStoreFactory.GetAtomPubStoreWriter(base.BaseUri.OriginalString); //Get AtomEntryDocument for request to update the member information. AtomEntryDocument atomDocument = new AtomEntryDocument(context.Request.InputStream); SyndicationItem item = atomPubStoreWriter.UpdateMemberInfo(collectionName, memberId, atomDocument); // Get AtomEntryDocument for response. return(new AtomEntryDocument(item)); }
/// <summary> /// Handles the POST request send to the collection Uri. The method assumes that the request is /// already validated using ValidateRequest method. /// </summary> /// <param name="context">HttpContext containing the request object.</param> /// <param name="statusCode">returns the status of the request.</param> /// <returns>A string containing the response for the specified AtomPub request.</returns> public override string ProcessRequest(HttpContext context, out System.Net.HttpStatusCode statusCode) { string response = string.Empty; AtomEntryDocument atomEntryDocument = null; bool isAtomEntryType = AtomPubHelper.IsAtomEntryMediaType(context.Request.ContentType); if (isAtomEntryType) { // If request stream contains AtomEntryDocument, then client wants to create new Member. atomEntryDocument = this.CreateMember(context); } else { // If request stream contains something other than AtomEntryDocument, // then client wants to create new member with Media. atomEntryDocument = this.CreateMedia(context); } // Add Location Header SyndicationLink editLink = atomEntryDocument.Links .Where(link => link.RelationshipType == AtomPubConstants.Edit) .FirstOrDefault(); if (null != editLink) { context.Response.AddHeader(AtomPubConstants.KeyLocation, editLink.Uri.AbsoluteUri); } // Add ETag header string[] memberIds = atomEntryDocument.Id.Split(new string[] { AtomPubConstants.IdPrefix }, StringSplitOptions.RemoveEmptyEntries); if (0 < memberIds.Length) { string eTag = AtomPubHelper.CalculateETag(memberIds[0]); context.Response.AddHeader(AtomPubConstants.KeyETag, eTag); } response = atomEntryDocument.AtomEntry; statusCode = HttpStatusCode.Created; return(response); }
/// <summary> /// Creates a media resource using the information present in the HttpContext. /// </summary> /// <param name="context">The HttpContext for the incoming HTTP request.</param> /// <returns>An AtomEntryDocument corresponding to the newly created media resource.</returns> private AtomEntryDocument CreateMedia(HttpContext context) { SyndicationItem item = null; string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); // Get byte array to update media. BinaryReader reader = new BinaryReader(context.Request.InputStream); byte[] media = new byte[context.Request.InputStream.Length]; reader.Read(media, 0, media.Length); string fileExtention = string.Empty; if (context.Request.Headers.AllKeys.Contains("Content-Disposition")) { fileExtention = AtomPubHelper.GetFileExtentionFromContentDisposition( context.Request.Headers["Content-Disposition"]); } IAtomPubStoreWriter swordStoreWriter = AtomPubStoreFactory.GetSwordStoreWriter(); item = swordStoreWriter.CreateMedia(collectionName, context.Request.ContentType, media, fileExtention); AtomEntryDocument atomEntryDocument = null; if (null != item) { // Add <sword:treatment>Successfully created a {Collection Name}</sword:treatment> element. SwordPostProcessor.AddTreatmentElement(collectionName, item); // Create atom entry document from syndication item. atomEntryDocument = new AtomEntryDocument(item); } return(atomEntryDocument); }
/// <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> /// 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> /// Handles the POST request send to the collection Uri. The method assumes that the request is /// already validated using ValidateRequest method. /// </summary> /// <param name="context">HttpContext containing the request.</param> /// <param name="statusCode">Contains the status of the request.</param> /// <returns>A string containing the response for the specified AtomPub request.</returns> /// <remarks>If a zip file is sent with the POST request to the collection uri, /// the contents of the zip file are extracted and the individual files will be uploaded /// in the repository. /// The zip file should contain the mets.xml containing the metadata of the individual files. /// If mets.xml is not found in the specified zip file, status code 'PreconditionFailed' will /// be returned. /// </remarks> public override string ProcessRequest(HttpContext context, out System.Net.HttpStatusCode statusCode) { string response = string.Empty; AtomEntryDocument atomEntryDocument = null; bool isAtomEntryType = AtomPubHelper.IsAtomEntryMediaType(context.Request.ContentType); try { if (isAtomEntryType) { response = base.ProcessRequest(context, out statusCode); System.Xml.XmlTextReader responseReader = null; try { responseReader = new System.Xml.XmlTextReader(response, System.Xml.XmlNodeType.Document, null); SyndicationItem responseItem = SyndicationItem.Load(responseReader); string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); // Add <sword:treatment>Successfully created a {Collection Name}</sword:treatment> element. SwordPostProcessor.AddTreatmentElement(collectionName, responseItem); // Create atom entry document from syndication item. atomEntryDocument = new AtomEntryDocument(responseItem); } finally { responseReader.Close(); } context.Response.ContentType = AtomPubConstants.AtomEntryContentType; } else { // If request stream contains something other than AtomEntryDocument, // then client wants to create new member with Media. atomEntryDocument = this.CreateMedia(context); // Done this separately because if AtomEntry is null due to some reasons, // then also it will set the content type. context.Response.ContentType = AtomPubConstants.AtomEntryContentType; } // return the atom entry response. if (null != atomEntryDocument) { response = atomEntryDocument.AtomEntry; statusCode = System.Net.HttpStatusCode.Created; } else { statusCode = System.Net.HttpStatusCode.InternalServerError; } } catch (MetsException ex) { statusCode = System.Net.HttpStatusCode.InternalServerError; response = ex.Message; } catch (SwordException ex) { statusCode = System.Net.HttpStatusCode.UnsupportedMediaType; response = ex.Message; } finally { string zipExtractedPath = context.Items[SwordConstants.ZipExtractedPath] as string; if (!string.IsNullOrEmpty(zipExtractedPath) && Directory.Exists(zipExtractedPath)) { Directory.Delete(zipExtractedPath, true); context.Items[SwordConstants.ZipExtractedPath] = null; } } return(response); }
/// <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); } }