示例#1
0
        public override Task <object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            return(Task.Factory.StartNew(() =>
            {
                MemoryStream stream = new MemoryStream();
                readStream.CopyTo(stream);

                IEnumerable <string> xContentHeader;
                var success = content.Headers.TryGetValues("X-Content-Type", out xContentHeader);

                if (!success)
                {
                    throw new SparkException(System.Net.HttpStatusCode.BadRequest, "POST to binary must provide a Content-Type header");
                }

                string contentType = xContentHeader.FirstOrDefault();

                Binary binary = new Binary();
                binary.Content = stream.ToArray();
                binary.ContentType = contentType;

                ResourceEntry entry = ResourceEntry.Create(binary);
                entry.Tags = content.Headers.GetFhirTags();
                return (object)entry;
            }));
        }
示例#2
0
        internal static ResourceEntry CreateResourceEntryFromResource(Resource resource,
                                                                      string location, string category = null, string lastModified = null)
        {
            ResourceEntry result = ResourceEntry.Create(resource);

            if (!String.IsNullOrEmpty(location))
            {
                ResourceIdentity reqId = new ResourceIdentity(location);
                result.Id = reqId.WithoutVersion();

                if (reqId.VersionId != null)
                {
                    result.SelfLink = reqId;
                }
            }

            if (!String.IsNullOrEmpty(lastModified))
            {
                result.LastUpdated = DateTimeOffset.Parse(lastModified);
            }

            if (!String.IsNullOrEmpty(category))
            {
                result.Tags = ParseCategoryHeader(category);
            }

            result.Title = "A " + resource.GetType().Name + " resource";

            return(result);
        }
示例#3
0
        public override Task <object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            return(Task.Factory.StartNew <object>(() =>
            {
                try
                {
                    var body = base.ReadBodyFromStream(readStream, content);

                    if (type == typeof(ResourceEntry))
                    {
                        Resource resource = FhirParser.ParseResourceFromJson(body);
                        ResourceEntry entry = ResourceEntry.Create(resource);
                        entry.Tags = content.Headers.GetFhirTags();
                        return entry;
                    }
                    else if (type == typeof(Bundle))
                    {
                        return FhirParser.ParseBundleFromJson(body);
                    }
                    else if (type == typeof(TagList))
                    {
                        return FhirParser.ParseTagListFromJson(body);
                    }
                    else
                    {
                        throw new NotSupportedException(String.Format("Cannot read unsupported type {0} from body", type.Name));
                    }
                }
                catch (FormatException exc)
                {
                    throw new SparkException(HttpStatusCode.BadRequest, "Body parsing failed: " + exc.Message);
                }
            }));
        }
示例#4
0
        public static ResourceEntry SingleResourceResponse(string body, byte[] data, string contentType,
                                                           string requestUri = null, string location     = null,
                                                           string category   = null, string lastModified = null)
        {
            Resource resource = null;

            if (body != null)
            {
                resource = parseBody <Resource>(body, contentType,
                                                (b, e) => FhirParser.ParseResourceFromXml(b, e),
                                                (b, e) => FhirParser.ParseResourceFromJson(b, e));
            }
            else
            {
                resource = Util.MakeBinary(data, contentType);
            }

            ResourceEntry result = ResourceEntry.Create(resource);
            string        versionIdInRequestUri = null;

            if (!String.IsNullOrEmpty(requestUri))
            {
                ResourceLocation reqLoc = new ResourceLocation(requestUri);
                versionIdInRequestUri = reqLoc.VersionId;
                ResourceLocation idLoc = new ResourceLocation(reqLoc.ServiceUri);
                idLoc.Collection = reqLoc.Collection;
                idLoc.Id         = reqLoc.Id;
                result.Id        = idLoc.ToUri();
            }

            if (!String.IsNullOrEmpty(location))
            {
                result.SelfLink = new Uri(location, UriKind.Absolute);
            }
            else
            {
                // Try to get the SelfLink from the requestUri (might contain specific version id)
                if (!String.IsNullOrEmpty(versionIdInRequestUri))
                {
                    var rl = new ResourceLocation(result.Id);
                    rl.VersionId    = versionIdInRequestUri;
                    result.SelfLink = rl.ToUri();
                }
            }

            if (!String.IsNullOrEmpty(lastModified))
            {
                result.LastUpdated = DateTimeOffset.Parse(lastModified);
            }

            if (!String.IsNullOrEmpty(category))
            {
                result.Tags = ParseCategoryHeader(category);
            }

            result.Title = "A " + resource.GetType().Name + " resource";

            return(result);
        }
示例#5
0
文件: Test.cs 项目: schellack/spark
        public static Bundle Bundle()
        {
            Bundle      bundle = new Bundle();
            Patient     p      = Test.Patient();
            BundleEntry entry  = ResourceEntry.Create(p);

            bundle.Entries.Add(entry);
            return(bundle);
        }
示例#6
0
        internal static ResourceEntry CreateFromResource(Resource resource, Uri id, DateTimeOffset updated, string title = null)
        {
            var result = ResourceEntry.Create(resource);

            initializeResourceEntry(result, id, updated, title);

            result.Resource = resource;

            return(result);
        }
        public static ResourceEntry CreateResourceEntryFromId(Uri id)
        {
            // Figure out the resource type from the id
            ResourceIdentity rid = new ResourceIdentity(id);

            if (rid.Collection != null)
            {
                var inspector    = SerializationConfig.Inspector;
                var classMapping = inspector.FindClassMappingForResource(rid.Collection);
                return(ResourceEntry.Create(classMapping.NativeType));
            }
            else
            {
                throw Error.Format("BundleEntry's id '{0}' does not specify the type of resource: cannot determine Resource type in parser.", null, id.ToString());
            }
        }
示例#8
0
        private ResourceEntry createResourceEntry(string resourceType)
        {
            Resource resource = null;

            if (resourceType == "Binary")
            {
                resource = makeBinary(Body, ContentType);
            }
            else
            {
                resource = parseBody <Resource>(BodyAsString(), ContentType,
                                                b => FhirParser.ParseResourceFromXml(b),
                                                b => FhirParser.ParseResourceFromJson(b));
            }

            ResourceEntry result = ResourceEntry.Create(resource);

            var location = Location ?? ContentLocation ?? ResponseUri.OriginalString;

            if (!String.IsNullOrEmpty(location))
            {
                ResourceIdentity reqId = new ResourceIdentity(location);

                // Set the id to the location, without the version specific part
                result.Id = reqId.WithoutVersion();

                // If the content location has version information, set to SelfLink to it
                if (reqId.VersionId != null)
                {
                    result.SelfLink = reqId;
                }
            }

            if (!String.IsNullOrEmpty(LastModified))
            {
                result.LastUpdated = DateTimeOffset.Parse(LastModified);
            }

            if (!String.IsNullOrEmpty(Category))
            {
                result.Tags = HttpUtil.ParseCategoryHeader(Category);
            }

            result.Title = "A " + resource.GetType().Name + " resource";

            return(result);
        }
示例#9
0
        /// <summary>
        /// Reinitializes the (database of) the server to its initial state
        /// </summary>
        /// <returns></returns>
        /// <remarks>Quite a destructive operation, mostly useful in debugging situations</remarks>
        public OperationOutcome Initialize()
        {
            //Note: also clears the counters collection, so id generation starts anew and
            //clears all stored binaries at Amazon S3.
            Stopwatch w = new Stopwatch();

            w.Start();
            _store.Clean();
            //_store.EraseData();
            //_store.EnsureIndices();

            _index.Clean();

            w.Stop();
            long cleaning = w.ElapsedMilliseconds;

            //Insert our own conformance statement into Conformance collection

            ResourceEntry conformanceentry = ResourceEntry.Create(ConformanceBuilder.Build());

            _service.Create(ConformanceBuilder.CONFORMANCE_COLLECTION_NAME, conformanceentry, ConformanceBuilder.CONFORMANCE_ID);

            //Insert standard examples
            w.Restart();
            var examples = loadExamples();


            var count = examples.Entries.OfType <Condition>().Count();

            w.Stop();
            long loadex = w.ElapsedMilliseconds;

            w.Restart();
            _service.Transaction(examples);
            w.Stop();
            var batch = w.ElapsedMilliseconds;


            //Start numbering new resources at an id higher than the examples (we hope)
            //EK: I like the convention of examples having id <10000, and new records >10.000, so please retain
            _store.EnsureNextSequenceNumberHigherThan(9999);


            string message = String.Format("Database was succesfully re-initialized: cleaning {0}, examples {1}, storage {2} ms", cleaning, loadex, batch);

            return(new OperationOutcome().Message(message));
        }
示例#10
0
        private static void AddTaggedPatient()
        {
            IFhirStore store   = Spark.Store.MongoStoreFactory.GetMongoFhirStore();
            var        patient = new Patient();

            patient.Id   = "Patient/tagged";
            patient.Name = new List <HumanName>();
            patient.Name.Add(new HumanName()
            {
                Given = new string[] { "Truus" }, Family = new string[] { "Tagged" }
            });
            ResourceEntry patientRE = ResourceEntry.Create(patient);

            patientRE.Id       = new Uri("Patient/tagged", UriKind.Relative);
            patientRE.SelfLink = new Uri("Patient/tagged", UriKind.Relative);
            patientRE.Tags.Add(new Tag(_otherTag, Tag.FHIRTAGSCHEME_GENERAL, "dummy"));
            store.Add(patientRE);
            index.Process(patientRE);
        }
        public override Task <object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            return(Task.Factory.StartNew <object>(() =>
            {
                try
                {
                    var body = base.ReadBodyFromStream(readStream, content);

                    if (type == typeof(Profile))
                    {
                        Profile resource = (Profile)FhirParser.ParseResourceFromXml(body);
                        return resource;
                    }
                    else if (type == typeof(ResourceEntry))
                    {
                        Resource resource = FhirParser.ParseResourceFromXml(body);
                        ResourceEntry entry = ResourceEntry.Create(resource);
                        return entry;
                    }
                    else if (type == typeof(Bundle))
                    {
                        if (XmlSignatureHelper.IsSigned(body))
                        {
                            if (!XmlSignatureHelper.VerifySignature(body))
                            {
                                throw new Exception("Digital signature in body failed verification");
                            }
                        }

                        return FhirParser.ParseBundleFromXml(body);
                    }
                    else
                    {
                        throw new NotSupportedException(String.Format("Cannot read unsupported type {0} from body", type.Name));
                    }
                }
                catch (FormatException exc)
                {
                    throw new Exception("Body parsing failed: " + exc.Message);
                }
            }));
        }
示例#12
0
        /// <summary>
        /// Reinitializes the (database of) the server to its initial state
        /// </summary>
        /// <returns></returns>
        /// <remarks>Quite a destructive operation, mostly useful in debugging situations</remarks>

        public string Initialize(bool extract)
        {
            //Note: also clears the counters collection, so id generation starts anew and
            //clears all stored binaries at Amazon S3.
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            store.Clean();
            index.Clean();
            stopwatch.Stop();
            double time_cleaning = stopwatch.Elapsed.Seconds;

            //Insert our own conformance statement into Conformance collection

            ResourceEntry conformanceentry = ResourceEntry.Create(ConformanceBuilder.Build());

            service.Upsert(conformanceentry, ConformanceBuilder.CONFORMANCE_COLLECTION_NAME, ConformanceBuilder.CONFORMANCE_ID);

            //Insert standard examples
            stopwatch.Restart();
            var examples = loadExamples(extract);

            stopwatch.Stop();
            double time_loading = stopwatch.Elapsed.Seconds;

            stopwatch.Restart();
            service.Transaction(examples);
            stopwatch.Stop();
            double time_storing = stopwatch.Elapsed.Seconds;

            //Start numbering new resources at an id higher than the examples (we hope)
            //EK: I like the convention of examples having id <10000, and new records >10.000, so please retain
            //_store.EnsureNextSequenceNumberHigherThan(9999);

            string message = String.Format(
                "Database was succesfully re-initialized. \nTime spent:" +
                "\nCleaning: {0}sec \nLoading examples: {1}sec, \nStoring: {2}sec",
                time_cleaning, time_loading, time_storing);

            return(message);
        }
示例#13
0
        private void importResource(string filename, Resource resource)
        {
            Match match = Regex.Match(filename, @"\w+\(([^\)]+)\)\..*");

            string id = null;

            if (match.Success)
            {
                id = match.Groups[1].Value;
            }

            if (id == null)
            {
                id = Guid.NewGuid().ToString();
            }

            System.Console.Out.WriteLine(filename + " is a single resource with id " + id);

            ResourceEntry newEntry = ResourceEntry.Create(resource);

            string collection = resource.GetCollectionName();

            // klopt het dat hier een hl7.org uri voor moet?
            Uri identity = ResourceIdentity.Build(new Uri("http://hl7.org/fhir"), collection, id);

            newEntry.Resource   = resource;
            newEntry.AuthorName = "(imported from file)";
            newEntry.Id         = identity;


            identity = ResourceIdentity.Build(new Uri("http://hl7.org/fhir"), collection, id, "1");
            // identity.VersionId = "1";

            newEntry.Links.SelfLink = identity;

            newEntry.LastUpdated = File.GetLastWriteTimeUtc(filename);
            newEntry.Published   = File.GetCreationTimeUtc(filename);
            newEntry.Title       = String.Format("{0} with id {1}", collection, id);

            add(newEntry);
        }
示例#14
0
        private void importResource(string filename, Resource resource)
        {
            System.Console.Out.WriteLine(filename + " is a single resource form filename: " + filename);

            ResourceEntry newEntry = ResourceEntry.Create(resource);

            newEntry.Resource   = resource;
            newEntry.AuthorName = "(imported from file)";

            Match  match      = Regex.Match(filename, @"\w+\(([^\)]+)\)\..*");
            string name       = match.Groups[1].Value;
            string id         = (match.Success) ? match.Groups[1].Value : null;
            string collection = resource.GetCollectionName();

            if (id != null)
            {
                Uri identity = ResourceIdentity.Build(hl7base, collection, id);
                newEntry.Id    = identity;
                newEntry.Title = String.Format("{0} with id {1}", collection, id);
            }
            else
            {
                newEntry.Title = String.Format("{0} from file {1}", collection, filename);
            }


            //identity = ResourceIdentity.Build(new Uri("http://hl7.org/fhir"), collection, id, "1");
            // identity.VersionId = "1";

            //newEntry.Links.SelfLink = identity;

            //newEntry.LastUpdated = File.GetLastWriteTimeUtc(filename);
            newEntry.Published = File.GetCreationTimeUtc(filename);

            add(newEntry);
        }
        private static BundleEntry loadEntry(XElement entry, ErrorList errors)
        {
            BundleEntry result;

            errors.DefaultContext = "An atom entry";

            try
            {
                if (entry.Name == XTOMBSTONE + XATOM_DELETED_ENTRY)
                {
                    result    = new DeletedEntry();
                    result.Id = Util.UriValueOrNull(entry.Attribute(XATOM_DELETED_REF));
                    if (result.Id != null)
                    {
                        errors.DefaultContext = String.Format("Entry '{0}'", result.Id.ToString());
                    }
                }
                else
                {
                    XElement content = entry.Element(XATOMNS + XATOM_CONTENT);
                    var      id      = Util.UriValueOrNull(entry.Element(XATOMNS + XATOM_ID));

                    if (id != null)
                    {
                        errors.DefaultContext = String.Format("Entry '{0}'", id.ToString());
                    }

                    if (content != null)
                    {
                        var parsed = getContents(content, errors);
                        if (parsed != null)
                        {
                            result = ResourceEntry.Create(parsed);
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("BundleEntry has empty content: cannot determine Resource type in parser.");
                    }

                    result.Id = id;
                }

                result.Links = getLinks(entry.Elements(XATOMNS + XATOM_LINK));
                result.Tags  = TagListParser.ParseTags(entry.Elements(XATOMNS + XATOM_CATEGORY));

                if (result is DeletedEntry)
                {
                    ((DeletedEntry)result).When = Util.InstantOrNull(entry.Attribute(XATOM_DELETED_WHEN));
                }
                else
                {
                    ResourceEntry re = (ResourceEntry)result;
                    re.Title       = Util.StringValueOrNull(entry.Element(XATOMNS + XATOM_TITLE));
                    re.LastUpdated = Util.InstantOrNull(entry.Element(XATOMNS + XATOM_UPDATED));
                    re.Published   = Util.InstantOrNull(entry.Element(XATOMNS + XATOM_PUBLISHED));
                    re.AuthorName  = entry.Elements(XATOMNS + XATOM_AUTHOR).Count() == 0 ? null :
                                     Util.StringValueOrNull(entry.Element(XATOMNS + XATOM_AUTHOR)
                                                            .Element(XATOMNS + XATOM_AUTH_NAME));
                    re.AuthorUri = entry.Elements(XATOMNS + XATOM_AUTHOR).Count() == 0 ? null :
                                   Util.StringValueOrNull(entry.Element(XATOMNS + XATOM_AUTHOR)
                                                          .Element(XATOMNS + XATOM_AUTH_URI));
                }
            }
            catch (Exception exc)
            {
                errors.Add("Exception while reading entry: " + exc.Message);
                return(null);
            }
            finally
            {
                errors.DefaultContext = null;
            }

            return(result);
        }
示例#16
0
        private static BundleEntry loadEntry(XElement entry)
        {
            BundleEntry result;

            try
            {
                if (entry.Name == XTOMBSTONE + XATOM_DELETED_ENTRY)
                {
                    result    = new DeletedEntry();
                    result.Id = SerializationUtil.UriValueOrNull(entry.Attribute(XATOM_DELETED_REF));
                }
                else
                {
                    XElement content = entry.Element(XATOMNS + XATOM_CONTENT);
                    var      id      = SerializationUtil.UriValueOrNull(entry.Element(XATOMNS + XATOM_ID));

                    if (content != null)
                    {
                        var parsed = getContents(content);
                        if (parsed != null)
                        {
                            result = ResourceEntry.Create(parsed);
                        }
                        else
                        {
                            throw Error.Format("BundleEntry has a content element without content", XmlDomFhirReader.GetLineInfo(content));
                        }
                    }
                    else
                    {
                        result = SerializationUtil.CreateResourceEntryFromId(id);
                    }

                    result.Id = id;
                }

                result.Links = getLinks(entry.Elements(XATOMNS + XATOM_LINK));
                result.Tags  = TagListParser.ParseTags(entry.Elements(XATOMNS + XATOM_CATEGORY));

                if (result is DeletedEntry)
                {
                    ((DeletedEntry)result).When = SerializationUtil.InstantOrNull(entry.Attribute(XATOM_DELETED_WHEN));
                }
                else
                {
                    ResourceEntry re = (ResourceEntry)result;
                    re.Title       = SerializationUtil.StringValueOrNull(entry.Element(XATOMNS + XATOM_TITLE));
                    re.LastUpdated = SerializationUtil.InstantOrNull(entry.Element(XATOMNS + XATOM_UPDATED));
                    re.Published   = SerializationUtil.InstantOrNull(entry.Element(XATOMNS + XATOM_PUBLISHED));
                    re.AuthorName  = entry.Elements(XATOMNS + XATOM_AUTHOR).Count() == 0 ? null :
                                     SerializationUtil.StringValueOrNull(entry.Element(XATOMNS + XATOM_AUTHOR)
                                                                         .Element(XATOMNS + XATOM_AUTH_NAME));
                    re.AuthorUri = entry.Elements(XATOMNS + XATOM_AUTHOR).Count() == 0 ? null :
                                   SerializationUtil.StringValueOrNull(entry.Element(XATOMNS + XATOM_AUTHOR)
                                                                       .Element(XATOMNS + XATOM_AUTH_URI));
                }
            }
            catch (Exception exc)
            {
                throw Error.Format("Exception while reading entry: " + exc.Message, XmlDomFhirReader.GetLineInfo(entry));
            }

            return(result);
        }
        private static BundleEntry loadEntry(JToken entry, ErrorList errors)
        {
            BundleEntry result;

            errors.DefaultContext = "An atom entry";

            try
            {
                if (entry.Value <DateTimeOffset?>(JATOM_DELETED) != null)
                {
                    result = new DeletedEntry();
                }
                else
                {
                    var content = entry[BundleXmlParser.XATOM_CONTENT];

                    if (content != null)
                    {
                        var parsed = getContents(content, errors);
                        if (parsed != null)
                        {
                            result = ResourceEntry.Create(parsed);
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("BundleEntry has empty content: cannot determine Resource type in parser");
                    }
                }

                result.Id = Util.UriValueOrNull(entry[BundleXmlParser.XATOM_ID]);
                if (result.Id != null)
                {
                    errors.DefaultContext = String.Format("Entry '{0}'", result.Id.ToString());
                }

                result.Links = getLinks(entry[BundleXmlParser.XATOM_LINK]);
                result.Tags  = TagListParser.ParseTags(entry[BundleXmlParser.XATOM_CATEGORY]);

                if (result is DeletedEntry)
                {
                    ((DeletedEntry)result).When = instantOrNull(entry[JATOM_DELETED]);
                }
                else
                {
                    var re = (ResourceEntry)result;
                    re.Title       = entry.Value <string>(BundleXmlParser.XATOM_TITLE);
                    re.LastUpdated = instantOrNull(entry[BundleXmlParser.XATOM_UPDATED]);
                    re.Published   = instantOrNull(entry[BundleXmlParser.XATOM_PUBLISHED]);
                    re.AuthorName  = entry[BundleXmlParser.XATOM_AUTHOR] as JArray != null ?
                                     entry[BundleXmlParser.XATOM_AUTHOR]
                                     .Select(auth => auth.Value <string>(BundleXmlParser.XATOM_AUTH_NAME))
                                     .FirstOrDefault() : null;
                    re.AuthorUri = entry[BundleXmlParser.XATOM_AUTHOR] as JArray != null ?
                                   entry[BundleXmlParser.XATOM_AUTHOR]
                                   .Select(auth => auth.Value <string>(BundleXmlParser.XATOM_AUTH_URI))
                                   .FirstOrDefault() : null;
                }
            }
            catch (Exception exc)
            {
                errors.Add("Exception while reading entry: " + exc.Message);
                return(null);
            }
            finally
            {
                errors.DefaultContext = null;
            }

            return(result);
        }
        private static BundleEntry loadEntry(JObject entry)
        {
            BundleEntry result;

            try
            {
                if (entry[JATOM_DELETED] != null)
                {
                    result    = new DeletedEntry();
                    result.Id = SerializationUtil.UriValueOrNull(entry[BundleXmlParser.XATOM_ID]);
                }
                else
                {
                    var content = entry[BundleXmlParser.XATOM_CONTENT];

                    var id = SerializationUtil.UriValueOrNull(entry[BundleXmlParser.XATOM_ID]);
                    if (id == null)
                    {
                        throw Error.Format("BundleEntry found without an id", null);
                    }

                    if (content != null)
                    {
                        var parsed = getContents(content);
                        if (parsed != null)
                        {
                            result = ResourceEntry.Create(parsed);
                        }
                        else
                        {
                            throw Error.Format("BundleEntry {0} has a content element without content", null, id);
                        }
                    }
                    else
                    {
                        result = SerializationUtil.CreateResourceEntryFromId(id);
                    }

                    result.Id = id;
                }

                result.Links = getLinks(entry[BundleXmlParser.XATOM_LINK]);
                result.Tags  = TagListParser.ParseTags(entry[BundleXmlParser.XATOM_CATEGORY]);

                if (result is DeletedEntry)
                {
                    ((DeletedEntry)result).When = instantOrNull(entry[JATOM_DELETED]);
                }
                else
                {
                    var re = (ResourceEntry)result;
                    re.Title       = entry.Value <string>(BundleXmlParser.XATOM_TITLE);
                    re.LastUpdated = instantOrNull(entry[BundleXmlParser.XATOM_UPDATED]);
                    re.Published   = instantOrNull(entry[BundleXmlParser.XATOM_PUBLISHED]);
                    re.AuthorName  = entry[BundleXmlParser.XATOM_AUTHOR] as JArray != null ?
                                     entry[BundleXmlParser.XATOM_AUTHOR]
                                     .Select(auth => auth.Value <string>(BundleXmlParser.XATOM_AUTH_NAME))
                                     .FirstOrDefault() : null;
                    re.AuthorUri = entry[BundleXmlParser.XATOM_AUTHOR] as JArray != null ?
                                   entry[BundleXmlParser.XATOM_AUTHOR]
                                   .Select(auth => auth.Value <string>(BundleXmlParser.XATOM_AUTH_URI))
                                   .FirstOrDefault() : null;
                }
            }
            catch (Exception exc)
            {
                throw Error.Format("Exception while reading entry: " + exc.Message, null);
            }

            return(result);
        }