예제 #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
 public bool PokeObject(ObjDigital obj)
 {
     try
     {
         manager.modifyObject(obj.pid, null, null, null, "Poke no objecto para refrescamento.");
         obj.state = State.unchanged;
         return true;
     }
     catch (Exception ex)
     {
         Trace.WriteLine(ex.ToString());
         return false;
     }
 }
예제 #3
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;
            }
        }
예제 #4
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;
        }
예제 #5
0
 private bool AtomicIngest(ObjDigital objDigital)
 {
     if (objDigital.state == State.modified)
     {
         return Update(objDigital);
     }
     else if (objDigital.state == State.added)
     {
         return AddObject(objDigital);
     }
     else if (objDigital.state == State.deleted)
     {
         return ChangeState(objDigital, ObjectState.Deleted, false);
     }
     else if (objDigital.state == State.poked)
     {
         return PokeObject(objDigital);
     }
     else return true;
 }
예제 #6
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;
            }
        }
예제 #7
0
        public bool ChangeState(ObjDigital obj, ObjectState newState, bool updateObject)
        {
            string stringNewState = null;
            switch(newState) 
            {
                case ObjectState.Active: stringNewState = "A"; break;
                case ObjectState.Inactive: stringNewState = "I"; break;
                case ObjectState.Deleted: stringNewState = "D"; break;
                default: stringNewState = null; break;
            }

            try
            {
                manager.modifyObject(obj.pid, stringNewState, null, null, "Estado do objecto alterado para '" + stringNewState + "'");
                if(updateObject)
                    obj.state = State.unchanged;
                return true;
            }
            catch (Exception ex) 
            {
                Trace.WriteLine(ex.ToString());
                return false;
            }
        }