예제 #1
0
        private string GetRecordType(object rec)
        {
            var tri = (object[])rec;

            object[] tduple = (object[])(((object[])tri[1]).FirstOrDefault(pair => (int)((object[])pair)[0] == store.cod_rdftype));
            if (tduple == null)
            {
                return(null);
            }
            return(store.DecodeEntity((int)tduple[1]));
        }
        public TripleStoreProfile(TripleRecordStore store)
        {
            _store = store;
            // Вычисление "важных" кодов
            cod_rdftype = store.CodeEntity("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); // Зафиксирован? 0;
            cod_delete  = store.CodeEntity("http://fogid.net/o/delete");
            cod_name    = store.CodeEntity("http://fogid.net/o/name");
            CreateMap <object, RecordField>().ConstructUsing((triples, context) =>
            {
                if (!(triples is object[] dup))
                {
                    return(null);
                }
                return(new RecordField()
                {
                    Property = store.Decode((int)dup[0]),
                    Value = (string)dup[1]
                });
            });
            CreateMap <object, RecordProperty>().ConstructUsing((triples, context) =>
            {
                if (!(triples is object[] dup))
                {
                    return(null);
                }
                return(new RecordProperty()
                {
                    Property = store.DecodeEntity((int)dup[0]),
                    Value = new Record()
                    {
                        Id = store.DecodeEntity((int)dup[1])
                    }
                });
            });
            CreateMap <object, RecordInverseProperty>().ConstructUsing((source, context) =>
            {
                if (!(source is object[] triples))
                {
                    return(null);
                }
                int cid        = (int)triples[0];
                object[] found = ((object[])triples[1]).Cast <object[]>().FirstOrDefault(dup => (int)dup[1] == cid);
                return(new RecordInverseProperty()
                {
                    Property = store.DecodeEntity((int)found[0]),
                    Value = new Record()
                    {
                        Id = store.DecodeEntity((int)triples[0])
                    }
                });
            });

            CreateMap <object, Record>().ConstructUsing((source, context) =>
            {
                if (!(source is object[] triples))
                {
                    return(null);
                }
                if (context.Options.Items["Format"] is RecordFormat format)
                {
                    //todo use format recursive
                    return(new Record()
                    {
                        Id = store.DecodeEntity((int)triples[0]),
                        Type = GetRecordType(source),
                        Fields = context.Mapper.Map <RecordField[]>(((object[])triples[2])),
                        Directs = context.Mapper.Map <RecordProperty[]>((object[])triples[1])
                    });
                }

                return(new Record()
                {
                    Id = store.DecodeEntity((int)triples[0]),
                    Type = GetRecordType(source),
                    Fields = context.Mapper.Map <RecordField[]>((object[])triples[2]),
                    Directs = context.Mapper.Map <RecordProperty[]>((object[])triples[1])
                });
            });
            CreateMap <object, RecordWithInverses>().ConstructUsing((source, context) =>
            {
                if (!(source is object[] triples))
                {
                    return(null);
                }
                return(new RecordWithInverses()
                {
                    Id = store.DecodeEntity((int)triples[0]),
                    Type = GetRecordType(source),
                    Fields = context.Mapper.Map <RecordField[]>((object[])triples[2]),
                    Directs = context.Mapper.Map <RecordProperty[]>((object[])triples[1]),
                    Inverses =
                        context.Mapper.Map <IEnumerable <RecordInverseProperty> >(store.GetRefers((int)triples[0]))
                        ?.ToArray()
                });
            });

            CreateMap <Record, XElement>().ConvertUsing((record, context) =>
            {
                if (record == null)
                {
                    return(null);
                }
                XElement xres = new XElement("record",
                                             new XAttribute("id", record.Id), record.Type == null ? null : new XAttribute("type", record.Type),
                                             record.Fields?.Select(dup => new XElement("field", new XAttribute("prop", dup.Property), dup.Value)),
                                             record.Directs?.Select(dup => new XElement("direct", new XAttribute("prop", dup.Property),
                                                                                        new XElement("record", new XAttribute("id", dup.Value.Id)))));

                return(xres);
            });
            CreateMap <RecordWithInverses, XElement>().ConvertUsing((record, context) => record == null
                ? null
                : new XElement("record",
                               new XAttribute("id", record.Id),
                               record.Type == null ? null : new XAttribute("type", record.Type),
                               record.Fields?.Select(dup =>
                                                     new XElement("field", new XAttribute("prop", dup.Property), dup.Value)),
                               record.Directs?.Select(dup => new XElement("direct", new XAttribute("prop", dup.Property),
                                                                          new XElement("record", new XAttribute("id", dup.Value.Id)))),
                               record.Inverses?.Select(dup => new XElement("direct", new XAttribute("prop", dup.Property),
                                                                           new XElement("record", new XAttribute("id", dup.Value.Id))))));


            // ============================== Редактирование ================================
            CreateMap <Record, object>().ConvertUsing((record, context) =>
            {
                int cid = store.CodeEntity(record.Id);
                return(new object[]
                {
                    cid,
                    Enumerable.Repeat(new object[] { cod_rdftype, store.CodeEntity(record.Type) }, 1)
                    .Concat(record.Directs
                            .Select(el => new object[]
                    {
                        store.CodeEntity(el.Property),
                        store.CodeEntity(el.Value.Id)
                    })).ToArray(),
                    record.Fields
                    .Select(el => new object[]
                            { store.CodeEntity(el.Property), el.Value }).ToArray()
                });
            });

            CreateMap <XElement, Record>().ConvertUsing((xRecord, context) =>
            {
                var xAbout = xRecord.Attribute("{http://www.w3.org/1999/02/22-rdf-syntax-ns#}about");
                if (xAbout == null)
                {
                    return(null);
                }
                var props = xRecord.Elements().Select(x =>
                                                      (x,
                                                       resource: x.Attribute("{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource"),
                                                       property: "http://fogid.net/o/" + x.Name.LocalName))
                            .GroupBy(el => el.resource != null)
                            .ToArray();
                string id = xAbout.Value;
                string tp = "http://fogid.net/o/" + xRecord.Name.LocalName;
                return(new Record()
                {
                    Id = id,
                    Type = tp,
                    Fields = props.Where(g => !g.Key).SelectMany(x => x)
                             .Select(el => new RecordField
                    {
                        Property = el.property,
                        Value = el.x.Value
                    })
                             .ToArray(),
                    Directs = props.Where(g => g.Key).SelectMany(x => x)
                              .Select(el => new RecordProperty
                    {
                        Property = el.property,
                        Value = new Record
                        {
                            Id = el.resource.Value
                        }
                    }).ToArray(),
                });
            });
        }