private Dictionary <AnnHistoryItemState, Dictionary <string, string> > ProcessAnnotationsHistory(LEADDocument document) { // Get the history (which is updated each time SetAnnotations/SaveToCache is called). AnnHistory history = document.Annotations.GetHistory(); if (history == null) { return(null); } // Condense the history to get all the changes since the last time the history was cleared in one list. history.Condense(); if (history.Items.Count == 0) { return(null); } string documentId = document.DocumentId; bool logging = _loggingLEADToIBM; if (logging) { Trace.WriteLine(string.Format("Logging: LEADTOOLS annotations to IBM annotations for document '{0}'", documentId)); Trace.WriteLine(" Condensed history of changes since last save/set:"); var items = (List <AnnHistoryItem>)history.Items; foreach (AnnHistoryItem item in items) { // You also have access to the user information here. Trace.WriteLine(string.Format(" {0} {1} {2}", item.Guid, item.State, item.Timestamp)); } } // Get all annotation containers (and the objects within them). AnnContainer[] containers = document.Annotations.GetAnnotations(false); // Process all the added objects. LEAD tracks both "Added" and "AddedAndModified" (cases // where annotations were added and then modified from the default). Here, we combine them // for a simple "ADDED" list. Dictionary <string, string> addedIBMObjects = new Dictionary <string, string>(); // Get the guids for the added objects from our history object. string[] guids = history.GetGuidForState(AnnHistoryItemState.Added); ProcessObjects(addedIBMObjects, documentId, guids, AnnHistoryItemState.Added, containers); guids = history.GetGuidForState(AnnHistoryItemState.AddedAndModified); ProcessObjects(addedIBMObjects, documentId, guids, AnnHistoryItemState.Added, containers); // Process all modified objects Dictionary <string, string> modifiedIBMObjects = new Dictionary <string, string>(); string[] modifiedGuids = history.GetGuidForState(AnnHistoryItemState.Modified); ProcessObjects(modifiedIBMObjects, documentId, modifiedGuids, AnnHistoryItemState.Modified, containers); // Process all deleted objects (note, we only get the guids for them; no IBM objects will be here) Dictionary <string, string> deletedIBMObjects = new Dictionary <string, string>(); guids = history.GetGuidForState(AnnHistoryItemState.Deleted); ProcessObjects(deletedIBMObjects, documentId, guids, AnnHistoryItemState.Deleted, containers); // Clear the history since we updated everything. history.Clear(); // Set the history again (so it will be saved in the cache for this document). document.Annotations.SetHistory(history); // List of converted IBM objects that has been modified Dictionary <AnnHistoryItemState, Dictionary <string, string> > ibmObjects = new Dictionary <AnnHistoryItemState, Dictionary <string, string> >(); ibmObjects.Add(AnnHistoryItemState.Added, addedIBMObjects); ibmObjects.Add(AnnHistoryItemState.Modified, modifiedIBMObjects); ibmObjects.Add(AnnHistoryItemState.Deleted, deletedIBMObjects); return(ibmObjects); }
public SetAnnotationsIBMResponse SetAnnotationsIBM(SetAnnotationsIBMRequest request) { if (request == null) { throw new ArgumentNullException("request"); } // Must have the documentId you'd like to add annotations to. // If you only have the document cache URI, DocumentFactory.LoadFromUri needs to be called. if (string.IsNullOrEmpty(request.DocumentId)) { throw new ArgumentNullException("documentId"); } // Check that we have annotations. if (request.Annotations == null) { throw new ArgumentNullException("annotations"); } var cache = ServiceHelper.Cache; using (var document = DocumentFactory.LoadFromCache(cache, request.DocumentId)) { // Ensure we have the document. DocumentHelper.CheckLoadFromCache(document); // If the document is read-only then we won't be able to modify its settings. Temporarily change this state. bool wasReadOnly = document.IsReadOnly; document.IsReadOnly = false; // Get the IBM annotations from the request. IBMAnnotation[] ibmAnnotationObjects = request.Annotations; // Start converting. We need a rendering engine instance to help with measuring font sizes. AnnRenderingEngine renderingEngine = ServiceHelper.GetAnnRenderingEngine(); // We have different options for reading the annotation... IBMP8ReadOptions readOptions = new IBMP8ReadOptions(); readOptions.RenderingEngine = renderingEngine; int pagesCount = document.Pages.Count; // We have all the IBM objects converted to LEAD; now, add them to their respective page containers. Dictionary <int, AnnContainer> modifiedContainers = new Dictionary <int, AnnContainer>(); for (int i = 0; i < ibmAnnotationObjects.Length; i++) { // Our IBM annotation, as an XML string. IBMAnnotation ibmObj = ibmAnnotationObjects[i]; if (ibmObj == null || string.IsNullOrEmpty(ibmObj.Annotation)) { continue; } try { // Before converting, get the target page number. string ibmPageNumberValue = AnnCodecs.ReadIBMP8PropDescAttr(ibmObj.Annotation, AnnCodecs.IBM_PAGENUMBER); int pageNumber = 1; if (!string.IsNullOrEmpty(ibmPageNumberValue)) { int.TryParse(ibmPageNumberValue, out pageNumber); } // Make sure the page exists. // If zero, set to page 1; if outside of the document range, disregard it. if (pageNumber == 0) { pageNumber = 1; } else if (pageNumber > pagesCount) { continue; } // Get its container (one per page) and add the object to it. DocumentPage documentPage = document.Pages[pageNumber - 1]; AnnContainer container = null; if (modifiedContainers.ContainsKey(pageNumber)) { container = modifiedContainers[pageNumber]; } else { container = documentPage.GetAnnotations(true); modifiedContainers.Add(pageNumber, container); } readOptions.Mapper = container.Mapper; // Convert to a LEADTOOLS AnnObject. // See "#REF IBM_Annotations_Support" for support info AnnObject leadObj = AnnCodecs.ConvertFromIBMP8(ibmObj.Annotation, readOptions); if (leadObj == null) { Trace.WriteLine("Conversion from IBM Annotation not supported for item at index " + i); continue; } // Add the supplied properties if (!string.IsNullOrEmpty(ibmObj.Password)) { leadObj.Lock(ibmObj.Password); } if (!string.IsNullOrEmpty(ibmObj.UserId)) { leadObj.UserId = ibmObj.UserId; Dictionary <string, string> metadata = leadObj.Metadata; string key = AnnObject.AuthorMetadataKey; if (metadata.ContainsKey(key)) { if (string.IsNullOrEmpty(metadata[key])) { metadata[key] = ibmObj.UserId; } } else { metadata.Add(key, ibmObj.UserId); } } container.Children.Add(leadObj); } catch (Exception e) { Trace.WriteLine(string.Format("Failed to convert IBM Annotation at index {0}: {1}", i, e.Message)); } } // Set the modified containers in the document. AnnContainer[] containers = modifiedContainers.Values.ToArray(); document.Annotations.SetAnnotations(containers); // Reset the read-only value from above before saving into the cache. document.IsReadOnly = wasReadOnly; // Enable history tracking from this point forward so that calls to retrieve the IBM Annotations will have a history from this set operation. document.History.AutoUpdate = true; // Clear any old history. AnnHistory history = document.Annotations.GetHistory(); if (history != null) { history.Clear(); document.Annotations.SetHistory(history); } document.SaveToCache(); return(new SetAnnotationsIBMResponse()); } }