예제 #1
0
        public bool AddObject(ObjDigital objDigital)
        {
            try 
            { 
                string newPid = manager.getNextPID("1", serverNamespace)[0];
                if (objDigital.pid == "-1") objDigital.pid = newPid;
                FoxmlExporter foxml;
                if (objDigital.GetType() == typeof(ObjDigSimples)) foxml = new FoxmlExporter(objDigital as ObjDigSimples, gisaOperator, newPid, serverNamespace);
                else foxml = new FoxmlExporter(objDigital as ObjDigComposto, gisaOperator, newPid, ((ObjDigComposto)objDigital).objSimples, serverNamespace);

                if (Ingest(foxml, newPid) != null)
                {
                    Trace.WriteLine(newPid + " foi ingerido.");
                    objDigital.pid = newPid;
                    objDigital.state = State.unchanged;
                    return true;
                }

                Trace.WriteLine(newPid + " não foi ingerido.");
                return false;
            }
            catch (Exception ex) 
            { 
                Trace.WriteLine(ex.ToString());
                return false;
            }
        }
예제 #2
0
        private bool UpdateMetadata(ObjDigital obj, string[] logMessage, out string newTimestamp)
        {
            DublinCoreExporter dcExporter;
            MetsExporter       metsExporter;

            newTimestamp = null;

            try
            {
                // Create new versions of XML for METS and DC
                if (obj.GetType() == typeof(ObjDigComposto))
                {
                    var objComposto = obj as ObjDigComposto;
                    dcExporter   = new DublinCoreExporter(objComposto);
                    metsExporter = new MetsExporter(objComposto, gisaOperator, logMessage);
                }
                else
                {
                    var objSimples = obj as ObjDigSimples;
                    dcExporter   = new DublinCoreExporter(objSimples);
                    metsExporter = new MetsExporter(objSimples, gisaOperator, logMessage);
                }
            }
            catch (Exception ex)
            {
                Trace.Write("Erro ao recriar DC/METS do " + obj.pid + ": ");
                Trace.WriteLine(ex.ToString());
                return(false);
            }

            // Reingerir o DC e o METS
            try {
                manager.modifyDatastreamByValue(obj.pid, "DC", null, null, "text/xml", null, ConvertToBytes(dcExporter.DublinCore), "MD5", null, "Atualização de metadados", false);
                newTimestamp = manager.modifyDatastreamByValue(obj.pid, "METS", null, null, "text/xml", null, ConvertToBytes(metsExporter.METS), "MD5", null, "Atualização de metadados", false);
                return(true);
            } catch (Exception ex) {
                Trace.Write("Erro ao reingerir DC/METS do " + obj.pid + ": ");
                Trace.WriteLine(ex.ToString());
                return(false);
            }
        }
예제 #3
0
        public bool AddObject(ObjDigital objDigital)
        {
            try
            {
                string newPid = manager.getNextPID("1", serverNamespace)[0];
                if (objDigital.pid == "-1")
                {
                    objDigital.pid = newPid;
                }
                FoxmlExporter foxml;
                if (objDigital.GetType() == typeof(ObjDigSimples))
                {
                    foxml = new FoxmlExporter(objDigital as ObjDigSimples, gisaOperator, newPid, serverNamespace);
                }
                else
                {
                    foxml = new FoxmlExporter(objDigital as ObjDigComposto, gisaOperator, newPid, ((ObjDigComposto)objDigital).objSimples, serverNamespace);
                }

                if (Ingest(foxml, newPid) != null)
                {
                    Trace.WriteLine(newPid + " foi ingerido.");
                    objDigital.pid   = newPid;
                    objDigital.state = State.unchanged;
                    return(true);
                }

                Trace.WriteLine(newPid + " não foi ingerido.");
                return(false);
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.ToString());
                return(false);
            }
        }
예제 #4
0
        private void DoTheFOXML(ObjDigital obj)
        {
            var title = obj.titulo;

            // Construir os headers
            foxml            = new FoxmlDigitalObject("1.1", this.pid);
            foxml.properties = new FoxmlObjectProperties();
            foxml.properties.AddProperty(new FoxmlProperty("info:fedora/fedora-system:def/model#state", "A"));
            foxml.properties.AddProperty(new FoxmlProperty("info:fedora/fedora-system:def/model#label", title));

            // Add the DC datastream
            DublinCoreExporter dcXml;
            MetsExporter       metsXml;

            if (obj.GetType() == typeof(ObjDigSimples))
            {
                ObjDigSimples objSimples = obj as ObjDigSimples;
                metsXml = new MetsExporter(objSimples, userName, new string[] { "Ingestão do documento " + this.pid });
                dcXml   = new DublinCoreExporter(obj as ObjDigSimples);
            }
            else
            {
                ObjDigComposto objComposto = obj as ObjDigComposto;
                metsXml = new MetsExporter(objComposto, userName, new string[] { "Ingestão do documento " + this.pid });
                dcXml   = new DublinCoreExporter(obj as ObjDigComposto);
            }

            FoxmlDatastream        dcStream  = new FoxmlDatastream("DC", FoxmlDatastreamState.Active, FoxmlControlGroup.InlineXML, true);
            FoxmlDatastreamVersion dcStream1 = new FoxmlDatastreamVersion("DC.0", "http://www.openarchives.org/OAI/2.0/oai_dc/", "text/xml", "Metadados em Dublin Core", null, null);

            dcStream1.inlineXML     = dcXml.DublinCore;
            dcStream1.contentDigest = new FoxmlContentDigest(FoxmlChecksumTypes.DEFAULT, null);
            dcStream.AddVersion(dcStream1);
            foxml.AddDatastream(dcStream);

            // Add the RELS-EXT datastream
            FoxmlDatastream        relsStream  = new FoxmlDatastream("RELS-EXT", FoxmlDatastreamState.Active, FoxmlControlGroup.InlineXML, true);
            FoxmlDatastreamVersion relsStream1 = new FoxmlDatastreamVersion("RELS-EXT.0", "info:fedora/fedora-system:FedoraRELSExt-1.0", "application/rdf+xml", "RDF Statements about this object", null, null);

            relsStream1.inlineXML = GetRdf(this.pid, this.nmspace);
            relsStream.AddVersion(relsStream1);
            foxml.AddDatastream(relsStream);

            // Add the METS datastream for this document
            FoxmlDatastream        metsStream  = new FoxmlDatastream("METS", FoxmlDatastreamState.Active, FoxmlControlGroup.InlineXML, true);
            FoxmlDatastreamVersion metsStream1 = new FoxmlDatastreamVersion("METS.0", "http://www.loc.gov/METS/", "text/xml", "Metadados adicionais em METS", null, null);

            metsStream1.inlineXML     = metsXml.METS;
            metsStream1.contentDigest = new FoxmlContentDigest(FoxmlChecksumTypes.DEFAULT, null);
            metsStream.AddVersion(metsStream1);
            foxml.AddDatastream(metsStream);

            // Add the content datastreams
            FoxmlDatastream        datastream;
            FoxmlDatastreamVersion dsversion;

            if (obj.GetType() == typeof(ObjDigSimples))
            {
                int           cnt        = 1;
                ObjDigSimples objSimples = obj as ObjDigSimples;

                foreach (Anexo s in objSimples.fich_associados)
                {
                    string uName = s.dataStreamID;
                    datastream = new FoxmlDatastream(uName, FoxmlDatastreamState.Active, FoxmlControlGroup.ExternallyReferenceContent, true);
                    dsversion  = new FoxmlDatastreamVersion(uName + ".0", null, s.mimeType, null, null, null);
                    dsversion.contentLocation = new FoxmlContentLocation(s.url, "URL");
                    dsversion.contentDigest   = new FoxmlContentDigest(FoxmlChecksumTypes.DEFAULT, null);
                    datastream.AddVersion(dsversion);
                    foxml.AddDatastream(datastream);
                    cnt++;
                }
            }
        }
예제 #5
0
        private void DoTheMETS(ObjDigital obj, string[] logMessage)
        {
            var idsGisa = new string[] { obj.gisa_id };
            var title   = obj.titulo;
            var type    = obj.tipologia;

            // Ficheiro METS
            mets = new MetsFile(null, null, title, type, null);

            // Header - criador, hora de criação, e IDs alternativos
            mets.header = new MetsHeaderSection(null, null, Utility.Now(), null, null);
            mets.header.AddAgent(new MetsAgent(null, MetsAgentRole.Archivist, null, MetsAgentType.Individual, null, userName, logMessage));
            foreach (string s in idsGisa.Where(id => id.Length > 0))
            {
                string typeID = s.Substring(0, s.IndexOf(':'));
                mets.header.AddAltID(new MetsAlternativeIdentifier(null, typeID, s));
            }

            // Criar a secção de Ficheiros
            mets.fileSection = new MetsFileSection(null);
            MetsFileGroup fileGrp = new MetsFileGroup(null, null, null, "Conteúdos");

            mets.fileSection.AddFileGroupElement(fileGrp);

            MetsStructMap      structa   = null;
            MetsStructDivision largeFile = null;

            if (obj.GetType() == typeof(ObjDigSimples))
            {
                ObjDigSimples objSimples = obj as ObjDigSimples;
                structa   = new MetsStructMap(null, "PHYSICAL", "Estruturação em imagens do " + title);
                largeFile = new MetsStructDivision(null, type, title, null, null, null, null, null, null);

                for (int i = 0; i < objSimples.fich_associados.Count; i++)
                {
                    Anexo ficheiro = objSimples.fich_associados[i];

                    if (ficheiro.dataStreamID == null)
                    {
                        ficheiro.dataStreamID = "IMG" + objSimples.nextDatastreamId;
                        objSimples.nextDatastreamId++;
                    }
                    string uName = ficheiro.dataStreamID;

                    MetsFileElement file = new MetsFileElement(uName, ficheiro.mimeType, (i + 1).ToString(), null, null, null, MetsChecksumType.NONE, null, null, null, null, null);
                    file.AddFLocat(new MetsXLinkElement(null, null, MetsLocatorType.Other, "Nome de Datastream", uName, null, null, null, null, null));
                    fileGrp.AddFileElement(file);

                    MetsStructDivision div = new MetsStructDivision(null, ficheiro.mimeType, title, null, null, (i + 1).ToString(), null, null, null);
                    div.AddFilePointer(new MetsFilePointer(null, uName, null));
                    largeFile.AddDivision(div);
                }
            }
            else
            {
                ObjDigComposto objComposto = obj as ObjDigComposto;
                structa   = new MetsStructMap(null, "LOGICAL", "Estruturação em partes do " + title);
                largeFile = new MetsStructDivision(null, type, title, null, null, null, null, null, null);
                foreach (ObjDigSimples sd in objComposto.objSimples)
                {
                    // Apenas queremos fazer isto se o objecto não estiver marcado como apagado
                    if (sd.state != State.deleted)
                    {
                        string             pid = sd.pid;
                        MetsStructDivision div = new MetsStructDivision(null, sd.tipologia, sd.titulo, null, null, (objComposto.objSimples.IndexOf(sd) + 1).ToString(), null, null, null);
                        div.AddFilePointer(new MetsFilePointer(null, pid, null));
                        largeFile.AddDivision(div);
                    }
                }
            }

            structa.AddDivision(largeFile);
            mets.AddStructMap(structa);
        }
예제 #6
0
        private bool UpdateMetadata(ObjDigital obj, string[] logMessage, out string newTimestamp) 
        {
            DublinCoreExporter dcExporter;
            MetsExporter metsExporter;
            newTimestamp = null;

            try
            {
                // Create new versions of XML for METS and DC
                if (obj.GetType() == typeof(ObjDigComposto))
                {
                    var objComposto = obj as ObjDigComposto;
                    dcExporter = new DublinCoreExporter(objComposto);
                    metsExporter = new MetsExporter(objComposto, gisaOperator, logMessage);
                }
                else
                {
                    var objSimples = obj as ObjDigSimples;
                    dcExporter = new DublinCoreExporter(objSimples);
                    metsExporter = new MetsExporter(objSimples, gisaOperator, logMessage);
                }
            }
            catch (Exception ex)
            {
                Trace.Write("Erro ao recriar DC/METS do " + obj.pid + ": ");
                Trace.WriteLine(ex.ToString());
                return false;
            }

            // Reingerir o DC e o METS
            try { 
                manager.modifyDatastreamByValue(obj.pid, "DC", null, null, "text/xml", null, ConvertToBytes(dcExporter.DublinCore), "MD5", null, "Atualização de metadados", false);
                newTimestamp = manager.modifyDatastreamByValue(obj.pid, "METS", null, null, "text/xml", null, ConvertToBytes(metsExporter.METS), "MD5", null, "Atualização de metadados", false);
                return true;
            } catch(Exception ex) {
                Trace.Write("Erro ao reingerir DC/METS do " + obj.pid + ": ");
                Trace.WriteLine(ex.ToString());
                return false;
            }
        }
예제 #7
0
        private bool Update(ObjDigital objDigital)
        {
            bool success = true;
            bool update = false;
            var original = objDigital.original;
            List<string> changeset = new List<string>();

            // Se objecto não tem modificações, não fazer nada
            if (objDigital.state != State.modified) return true;

            // Mesmo pid?
            if (original.pid != objDigital.pid || original.GetType() != objDigital.GetType())
            {
                Trace.WriteLine("Objecto a atualizar não tem o mesmo PID do objecto original.");
                return false;
            }

            // Se for simples, verificar imagens
            if (objDigital.GetType() == typeof(ObjDigSimples))
            {
                // Verificar se é um simples e se mexemos nas imagens
                var simpleOriginal = original as ObjDigSimples;
                var simpleChanged = objDigital as ObjDigSimples;

                // Detectar alterações na ordem (pelo menos dos documentos que se mantiverem da versão anterior)
                for (int i = 0; i < simpleOriginal.fich_associados.Count; i++)
                {
                    if (i + 1 > simpleChanged.fich_associados.Count) break;
                    if (simpleChanged.fich_associados[i].url != simpleOriginal.fich_associados[i].url)
                    {
                        AddChange(IMAGES_ORDER, out update, changeset);
                        break;
                    }

                }

                // Adicionar novas datastreams
                if (simpleChanged.fich_associados.Exists(fich => fich.dataStreamID == null))
                {
                    AddChange(IMAGES_NEW, out update, changeset);
                    foreach (Anexo anexo in simpleChanged.fich_associados.Where(anx => anx.dataStreamID == null))
                    {
                        try
                        {
                            anexo.dataStreamID = manager.addDatastream(simpleChanged.pid, "IMG" + simpleChanged.nextDatastreamId, null, null, true, anexo.mimeType, null, anexo.url, "E", "A", "MD5", null, "Adição de imagem");
                            simpleChanged.nextDatastreamId++;
                        }
                        catch (Exception ex)
                        {
                            Trace.WriteLine(ex.ToString());
                            return false;
                        }
                    }
                }

                // Detectar remoções feitas no objecto
                if (!simpleOriginal.fich_associados.TrueForAll(anexoOriginal => simpleChanged.fich_associados.Exists(anexoNovo => anexoNovo.url == anexoOriginal.url && anexoNovo.dataStreamID == anexoOriginal.dataStreamID)))
                {
                    changeset.Add(IMAGES_DELETE);
                    update = true;
                }

                /* if (simpleOriginal.fich_associados.Count > simpleChanged.fich_associados.Count)
                {
                    changeset.Add(IMAGES_DELETE);
                    update = true;
                } */
            } 
            else if (objDigital.GetType() == typeof(ObjDigComposto))
            {
                // Se for um composto, verificar também se alteramos o título / tipologia de um dos simples
                var compostoOriginal = original as ObjDigComposto;
                var compostoChanged = objDigital as ObjDigComposto;

                // Vemos se o composto tem o mesmo número de objectos simples que o original
                if (compostoChanged.objSimples.Count == compostoOriginal.objSimples.Count)
                {
                    for (int i = 0; i < compostoChanged.objSimples.Count; i++)
                    {
                        ObjDigSimples simples = compostoChanged.objSimples[i];
                        ObjDigSimples simplesOriginal = compostoOriginal.objSimples[i];

                        if (simples.pid != simplesOriginal.pid)
                        {
                            AddChange(DOCUMENT_ORDER, out update, changeset);
                            break;
                        }
                    }

                    // Verificamos se algum dos simples associados a este composto teve o seu título ou tipologia alterada
                    foreach (ObjDigSimples simples in compostoChanged.objSimples)
                    {
                        ObjDigSimples simplesOriginal = simples.original as ObjDigSimples;
                        if (simplesOriginal == null || simples.titulo != simplesOriginal.titulo || simples.tipologia != simplesOriginal.tipologia)
                        {
                            AddChange(METADATA_CHILD, out update, changeset);
                            break;
                        }
                    }

                    // Actualizações ao estado de publicação não ficam registados como nova versão
                    if (compostoChanged.publicado != compostoOriginal.publicado)
                        PokeObject(compostoChanged);
                    else
                    {
                        foreach (ObjDigSimples simples in compostoChanged.objSimples)
                        {
                            ObjDigSimples simplesOriginal = simples.original as ObjDigSimples;
                            if (simplesOriginal != null && simples.publicado != simplesOriginal.publicado)
                            {
                                PokeObject(compostoChanged);
                                break;
                            }
                        }
                    }
                }
                else
                {
                    // Neste caso, ou adicionamos novos sub-documentos, ou os removemos
                    if (compostoChanged.objSimples.Count > compostoOriginal.objSimples.Count) AddChange(DOCUMENT_CHILD_NEW, out update, changeset);
                    else AddChange(DOCUMENT_CHILD_DELETE, out update, changeset);
                    update = true;
                }
            }

            // Verificar alteração na lista de assuntos
            if (original.assuntos.Count != objDigital.assuntos.Count || !objDigital.assuntos.TrueForAll(assunto => original.assuntos.Contains(assunto)))
                AddChange(DOCUMENT_THEME, out update, changeset);

            // A tipologia foi alterada?
            if (original.tipologia != objDigital.tipologia)
                AddChange(DOCUMENT_TYPE, out update, changeset);

            // O título foi alterado?
            if (original.titulo != objDigital.titulo)
                AddChange(DOCUMENT_TITLE, out update, changeset);

            if (update)
            {
                if (changeset.Count == 0) changeset.Add(METADATA_DEFAULT);

                // Refazer DC e METS
                string newStamp;
                success = UpdateMetadata(objDigital, changeset.ToArray(), out newStamp);

                // Actualizar versão, se tudo correu bem
                if (success)
                {
                    objDigital.version = newStamp;
                    objDigital.state = State.unchanged;
                }
            }

            return success;
        }
예제 #8
0
        public IngestResult Ingest(ObjDigital obj)
        {
            if (obj.GetType() == typeof(ObjDigComposto))
            {
                var docComposto = obj as ObjDigComposto;
                bool updateComplex = false;
                bool allUnchanged = true;
                IngestResult result = IngestResult.Success;
                List<ObjDigSimples> toRemove = new List<ObjDigSimples>();

                //if (obj.state == State.notFound)
                //    return IngestResult.Error;

                //if (docComposto.objSimples.Count(od => od.state == State.notFound) > 0)
                //    return IngestResult.Error;

                foreach (var sd in docComposto.objSimples)
                {
                    // So olhamos para objectos que foram alterados
                    if (sd.state != State.unchanged)
                    {
                        allUnchanged = false;
                        if (AtomicIngest(sd)) 
                        {
                            updateComplex = true;
                            if (sd.state == State.deleted) toRemove.Add(sd);
                        }
                        else result = IngestResult.Partial;
                    }
                }

                if (allUnchanged && obj.state == State.unchanged) return IngestResult.Success;
                else if (updateComplex || (obj.state != State.unchanged))
                {
                    // Se houverem documentos que foram marcados como removidos, remover da lista do objecto composto
                    toRemove.ForEach(doc => docComposto.objSimples.Remove(doc));

                    // Tentar actualizar complexo
                    if (AtomicIngest(obj)) return result;
                    else return IngestResult.Error;
                }
                else return IngestResult.Error;
            }
            else
            {
                // Documento simples solto
                if (obj.state != State.notFound && AtomicIngest(obj)) return IngestResult.Success;
                else return IngestResult.Error;
            }
        }
예제 #9
0
        private bool Update(ObjDigital objDigital)
        {
            bool          success   = true;
            bool          update    = false;
            var           original  = objDigital.original;
            List <string> changeset = new List <string>();

            // Se objecto não tem modificações, não fazer nada
            if (objDigital.state != State.modified)
            {
                return(true);
            }

            // Mesmo pid?
            if (original.pid != objDigital.pid || original.GetType() != objDigital.GetType())
            {
                Trace.WriteLine("Objecto a atualizar não tem o mesmo PID do objecto original.");
                return(false);
            }

            // Se for simples, verificar imagens
            if (objDigital.GetType() == typeof(ObjDigSimples))
            {
                // Verificar se é um simples e se mexemos nas imagens
                var simpleOriginal = original as ObjDigSimples;
                var simpleChanged  = objDigital as ObjDigSimples;

                // Detectar alterações na ordem (pelo menos dos documentos que se mantiverem da versão anterior)
                for (int i = 0; i < simpleOriginal.fich_associados.Count; i++)
                {
                    if (i + 1 > simpleChanged.fich_associados.Count)
                    {
                        break;
                    }
                    if (simpleChanged.fich_associados[i].url != simpleOriginal.fich_associados[i].url)
                    {
                        AddChange(IMAGES_ORDER, out update, changeset);
                        break;
                    }
                }

                // Adicionar novas datastreams
                if (simpleChanged.fich_associados.Exists(fich => fich.dataStreamID == null))
                {
                    AddChange(IMAGES_NEW, out update, changeset);
                    foreach (Anexo anexo in simpleChanged.fich_associados.Where(anx => anx.dataStreamID == null))
                    {
                        try
                        {
                            anexo.dataStreamID = manager.addDatastream(simpleChanged.pid, "IMG" + simpleChanged.nextDatastreamId, null, null, true, anexo.mimeType, null, anexo.url, "E", "A", "MD5", null, "Adição de imagem");
                            simpleChanged.nextDatastreamId++;
                        }
                        catch (Exception ex)
                        {
                            Trace.WriteLine(ex.ToString());
                            return(false);
                        }
                    }
                }

                // Detectar remoções feitas no objecto
                if (!simpleOriginal.fich_associados.TrueForAll(anexoOriginal => simpleChanged.fich_associados.Exists(anexoNovo => anexoNovo.url == anexoOriginal.url && anexoNovo.dataStreamID == anexoOriginal.dataStreamID)))
                {
                    changeset.Add(IMAGES_DELETE);
                    update = true;
                }

                /* if (simpleOriginal.fich_associados.Count > simpleChanged.fich_associados.Count)
                 * {
                 *  changeset.Add(IMAGES_DELETE);
                 *  update = true;
                 * } */
            }
            else if (objDigital.GetType() == typeof(ObjDigComposto))
            {
                // Se for um composto, verificar também se alteramos o título / tipologia de um dos simples
                var compostoOriginal = original as ObjDigComposto;
                var compostoChanged  = objDigital as ObjDigComposto;

                // Vemos se o composto tem o mesmo número de objectos simples que o original
                if (compostoChanged.objSimples.Count == compostoOriginal.objSimples.Count)
                {
                    for (int i = 0; i < compostoChanged.objSimples.Count; i++)
                    {
                        ObjDigSimples simples         = compostoChanged.objSimples[i];
                        ObjDigSimples simplesOriginal = compostoOriginal.objSimples[i];

                        if (simples.pid != simplesOriginal.pid)
                        {
                            AddChange(DOCUMENT_ORDER, out update, changeset);
                            break;
                        }
                    }

                    // Verificamos se algum dos simples associados a este composto teve o seu título ou tipologia alterada
                    foreach (ObjDigSimples simples in compostoChanged.objSimples)
                    {
                        ObjDigSimples simplesOriginal = simples.original as ObjDigSimples;
                        if (simplesOriginal == null || simples.titulo != simplesOriginal.titulo || simples.tipologia != simplesOriginal.tipologia)
                        {
                            AddChange(METADATA_CHILD, out update, changeset);
                            break;
                        }
                    }

                    // Actualizações ao estado de publicação não ficam registados como nova versão
                    if (compostoChanged.publicado != compostoOriginal.publicado)
                    {
                        PokeObject(compostoChanged);
                    }
                    else
                    {
                        foreach (ObjDigSimples simples in compostoChanged.objSimples)
                        {
                            ObjDigSimples simplesOriginal = simples.original as ObjDigSimples;
                            if (simplesOriginal != null && simples.publicado != simplesOriginal.publicado)
                            {
                                PokeObject(compostoChanged);
                                break;
                            }
                        }
                    }
                }
                else
                {
                    // Neste caso, ou adicionamos novos sub-documentos, ou os removemos
                    if (compostoChanged.objSimples.Count > compostoOriginal.objSimples.Count)
                    {
                        AddChange(DOCUMENT_CHILD_NEW, out update, changeset);
                    }
                    else
                    {
                        AddChange(DOCUMENT_CHILD_DELETE, out update, changeset);
                    }
                    update = true;
                }
            }

            // Verificar alteração na lista de assuntos
            if (original.assuntos.Count != objDigital.assuntos.Count || !objDigital.assuntos.TrueForAll(assunto => original.assuntos.Contains(assunto)))
            {
                AddChange(DOCUMENT_THEME, out update, changeset);
            }

            // A tipologia foi alterada?
            if (original.tipologia != objDigital.tipologia)
            {
                AddChange(DOCUMENT_TYPE, out update, changeset);
            }

            // O título foi alterado?
            if (original.titulo != objDigital.titulo)
            {
                AddChange(DOCUMENT_TITLE, out update, changeset);
            }

            if (update)
            {
                if (changeset.Count == 0)
                {
                    changeset.Add(METADATA_DEFAULT);
                }

                // Refazer DC e METS
                string newStamp;
                success = UpdateMetadata(objDigital, changeset.ToArray(), out newStamp);

                // Actualizar versão, se tudo correu bem
                if (success)
                {
                    objDigital.version = newStamp;
                    objDigital.state   = State.unchanged;
                }
            }

            return(success);
        }
예제 #10
0
        public IngestResult Ingest(ObjDigital obj)
        {
            if (obj.GetType() == typeof(ObjDigComposto))
            {
                var                  docComposto   = obj as ObjDigComposto;
                bool                 updateComplex = false;
                bool                 allUnchanged  = true;
                IngestResult         result        = IngestResult.Success;
                List <ObjDigSimples> toRemove      = new List <ObjDigSimples>();

                //if (obj.state == State.notFound)
                //    return IngestResult.Error;

                //if (docComposto.objSimples.Count(od => od.state == State.notFound) > 0)
                //    return IngestResult.Error;

                foreach (var sd in docComposto.objSimples)
                {
                    // So olhamos para objectos que foram alterados
                    if (sd.state != State.unchanged)
                    {
                        allUnchanged = false;
                        if (AtomicIngest(sd))
                        {
                            updateComplex = true;
                            if (sd.state == State.deleted)
                            {
                                toRemove.Add(sd);
                            }
                        }
                        else
                        {
                            result = IngestResult.Partial;
                        }
                    }
                }

                if (allUnchanged && obj.state == State.unchanged)
                {
                    return(IngestResult.Success);
                }
                else if (updateComplex || (obj.state != State.unchanged))
                {
                    // Se houverem documentos que foram marcados como removidos, remover da lista do objecto composto
                    toRemove.ForEach(doc => docComposto.objSimples.Remove(doc));

                    // Tentar actualizar complexo
                    if (AtomicIngest(obj))
                    {
                        return(result);
                    }
                    else
                    {
                        return(IngestResult.Error);
                    }
                }
                else
                {
                    return(IngestResult.Error);
                }
            }
            else
            {
                // Documento simples solto
                if (obj.state != State.notFound && AtomicIngest(obj))
                {
                    return(IngestResult.Success);
                }
                else
                {
                    return(IngestResult.Error);
                }
            }
        }