public virtual AtomEntry Annotate(Id entryId, AtomEntry entry, string slug) { LogService.Info("AnnotateService.Annotate entryId={0} slug={1}", entryId, slug); //authorization if (!AuthorizeService.IsAuthorized(GetUser(), entryId.ToScope(), AuthAction.Annotate)) throw new UserNotAuthorizedException(GetUser().Name, AuthAction.Annotate.ToString()); AppCollection coll = AppService.GetCollection(entryId); //make sure type is accepted if (!coll.CanAccept(Atom.ContentTypeEntry)) throw new InvalidContentTypeException(Atom.ContentTypeEntry); entry.SetNamespaces(); //TODO: is there a better place for this? //build id onto parent's id AtomEntry parent = AtomPubService.GetEntry(entryId); entry.Id = new Id(parent.Id.Owner, parent.Id.Date, parent.Id.Collection, entry.BuildPath(parent.Id.EntryPath, slug)); var url = new UrlHelper(Container.GetInstance<RequestContext>()); //this annotation is a reply to the parent entry, TODO: leave off href for later calc based on id? entry.InReplyTo = new ThreadInReplyTo() { Ref = parent.Id, Href = parent.IsExternal ? parent.Content.Src : url.RouteIdUri("AtomPubEntry", entry.Id, AbsoluteMode.Force), Type = parent.IsExternal ? parent.Content.Type : Atom.ContentTypeEntry }; if (!entry.Published.HasValue) entry.Published = DateTimeOffset.UtcNow; entry.Updated = DateTimeOffset.UtcNow; entry.Edited = DateTimeOffset.UtcNow; if (entry.Authors.Count() == 0) entry.SetPerson(AuthorizeService, true); //entry.IdChanged += (e) => e.UpdateLinks(UrlHelper.RouteIdUri); //OnAnnotate(parent, entryId, entry, slug); if (AnnotatingEntry != null) AnnotatingEntry(entryId, entry, slug); if (entry.Authors.Count() == 0 || entry.Authors.First().Name == null) throw new AnnotationNotAllowedException(entry.Id, entry.AnnotationType, "the author cannot be determined"); entry = AtomEntryRepository.CreateEntry(entry); if (EntryAnnotated != null) EntryAnnotated(entry); return entry; }