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; } }
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; } }
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; } }
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; }
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; }
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; } }
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; } }