ICEpdf
  1. ICEpdf
  2. PDF-618

errors in annotation handling

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 5.0.2
    • Fix Version/s: 5.1
    • Component/s: Core/Parsing
    • Labels:
      None
    • Environment:
      win xp prof

      Description

      When saving annotations to a external txt file it's often not possible to reload them correctly again. Code, screenshots and sample files will be provided.
      1. Activator.java
        10 kB
        Stefan Franz
      2. AnnotationTester.java
        3 kB
        Stefan Franz
      3. FileViewer.java
        40 kB
        Stefan Franz
      4. mist.pdf
        49 kB
        Stefan Franz
      5. mist.pdf.txt
        1 kB
        Stefan Franz
      6. MySwingController.java
        9 kB
        Stefan Franz
      7. MySwingController.java
        5 kB
        Stefan Franz
      8. MySwingViewBuilder.java
        1 kB
        Stefan Franz
      9. reader_overview.pdf
        953 kB
        Stefan Franz
      10. reader_overview.pdf.txt
        162 kB
        Stefan Franz
      1. screenshot-1.jpg
        391 kB
      2. screenshot-2.jpg
        338 kB
      3. screenshot-3.jpg
        610 kB

        Issue Links

          Activity

          Hide
          Stefan Franz added a comment -

          annotations created on pages 2 and 3 of the sample document. different types of annotations created. these annotations are saved in reader_overview.pdf.txt

          Show
          Stefan Franz added a comment - annotations created on pages 2 and 3 of the sample document. different types of annotations created. these annotations are saved in reader_overview.pdf.txt
          Hide
          Stefan Franz added a comment -

          annotations reloaded from file (reader_overview.pdf.txt). annotations from page 3 (right) are completely missing. some annotations from page 2 (left) are inivisble or incorrect formatted.

          Show
          Stefan Franz added a comment - annotations reloaded from file (reader_overview.pdf.txt). annotations from page 3 (right) are completely missing. some annotations from page 2 (left) are inivisble or incorrect formatted.
          Hide
          Stefan Franz added a comment -

          original pdf file

          Show
          Stefan Franz added a comment - original pdf file
          Hide
          Stefan Franz added a comment -

          saved annotations file

          Show
          Stefan Franz added a comment - saved annotations file
          Hide
          Stefan Franz added a comment -

          stack trace:

          16.07.2013 09:16:37 org.icepdf.core.pobjects.Catalog <clinit>
          INFO: ICEsoft ICEpdf Core 5.0.1
          16.07.2013 09:16:37 org.icepdf.core.pobjects.fonts.nfont.Font <clinit>
          INFO: ICEsoft ICEpdf Pro 5.0.2 P01
          16.07.2013 09:16:42 org.icepdf.core.util.Parser getObject
          WARNUNG: IO reading error.
          java.util.ConcurrentModificationException
          at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
          at java.util.AbstractList$Itr.next(Unknown Source)
          at test.MySwingController.loadMarkupFile(MySwingController.java:85)
          at test.MySwingController.openURL(MySwingController.java:178)
          at org.icepdf.ri.common.SwingController$8.run(SwingController.java:3672)
          at java.awt.event.InvocationEvent.dispatch(Unknown Source)
          at java.awt.EventQueue.dispatchEvent(Unknown Source)
          at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
          at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
          at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
          at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
          at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
          at java.awt.EventDispatchThread.run(Unknown Source)

          Show
          Stefan Franz added a comment - stack trace: 16.07.2013 09:16:37 org.icepdf.core.pobjects.Catalog <clinit> INFO: ICEsoft ICEpdf Core 5.0.1 16.07.2013 09:16:37 org.icepdf.core.pobjects.fonts.nfont.Font <clinit> INFO: ICEsoft ICEpdf Pro 5.0.2 P01 16.07.2013 09:16:42 org.icepdf.core.util.Parser getObject WARNUNG: IO reading error. java.util.ConcurrentModificationException at java.util.AbstractList$Itr.checkForComodification(Unknown Source) at java.util.AbstractList$Itr.next(Unknown Source) at test.MySwingController.loadMarkupFile(MySwingController.java:85) at test.MySwingController.openURL(MySwingController.java:178) at org.icepdf.ri.common.SwingController$8.run(SwingController.java:3672) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source)
          Hide
          Stefan Franz added a comment -

          Overrides saveFile() method for saving the annotations to an external file and openURL() method to reload the annotations.

          Show
          Stefan Franz added a comment - Overrides saveFile() method for saving the annotations to an external file and openURL() method to reload the annotations.
          Hide
          Patrick Corless added a comment -

          The SerializerText.java import code was meant to execute before a page component was initialized. Changes to the example need to be made to enable annotations to be loaded after a page component has been created.

          It would be preferable to load the annotations to the document object directly, before the Viewer RI builds out the components. Does this match your expected usage case?

          Show
          Patrick Corless added a comment - The SerializerText.java import code was meant to execute before a page component was initialized. Changes to the example need to be made to enable annotations to be loaded after a page component has been created. It would be preferable to load the annotations to the document object directly, before the Viewer RI builds out the components. Does this match your expected usage case?
          Hide
          Patrick Corless added a comment -

          Related sub issue.

          Show
          Patrick Corless added a comment - Related sub issue.
          Hide
          Patrick Corless added a comment -

          Could you provide more detail on the preferred work flow with regards to:

          1) opening the annotation without annotations
          2) injection of annotation information form external data source.
          3) display of merged document with annotation data.

          There are several ways of implementing this with the ICEpdf API and it is important the calls are made in the correct order to display the merged document correctly.

          Show
          Patrick Corless added a comment - Could you provide more detail on the preferred work flow with regards to: 1) opening the annotation without annotations 2) injection of annotation information form external data source. 3) display of merged document with annotation data. There are several ways of implementing this with the ICEpdf API and it is important the calls are made in the correct order to display the merged document correctly.
          Hide
          Stefan Franz added a comment -

          We integrated the ICEpdf in a existing eclipse rcp plugin and normally the user opens a document freh from our content management system without any annotations. Now he can add same markups and after that the annoations should be extracted and saved as a separate file in our cms. When he or another user opens that document again, both document and annation should be merged together and displayed in the viewer. I will provide you my implementation of the ICEpdf viewer ri.
          1. Activator java starts the viewer plugin
          2. FileViewer is the implementation of the surrounding JFrame
          3. MySwingController overrides the original ICEpdf SwingController
          4. MySwingViewBuilder ...same

          Show
          Stefan Franz added a comment - We integrated the ICEpdf in a existing eclipse rcp plugin and normally the user opens a document freh from our content management system without any annotations. Now he can add same markups and after that the annoations should be extracted and saved as a separate file in our cms. When he or another user opens that document again, both document and annation should be merged together and displayed in the viewer. I will provide you my implementation of the ICEpdf viewer ri. 1. Activator java starts the viewer plugin 2. FileViewer is the implementation of the surrounding JFrame 3. MySwingController overrides the original ICEpdf SwingController 4. MySwingViewBuilder ...same
          Hide
          Stefan Franz added a comment -

          Implementation of our eclipse rcp viewer plugin.

          Show
          Stefan Franz added a comment - Implementation of our eclipse rcp viewer plugin.
          Hide
          Patrick Corless added a comment -

          A bug was found with the existing annotation import code. The bug prevented an annotations content stream from being correctly parsed and painted. The resulting state did not provided enough information for the viewer to properly construct the annotations appearance stream.

          The changes needed to correct this issue require changes to the core but with these changes the process of importing annotations has been simplified.
          Assuming the call:

          _ICEpdfController.openDocument("../reader_overview.pdf");
          _ICEpdfController.loadExternalObjects();

          Where loadExternalObjects() is defined as:

          public void loadExternalObjects() {

          try {
          SeekableInput rafis =
          RandomAccessFileInputStream.build(
          new File(this.getDocument()
          .getDocumentOrigin()
          + ".txt"));

          Document document = this.getDocument();
          Library library = document.getCatalog().getLibrary();
          StateManager stateManager = library.getStateManager();

          Parser parser = new Parser(rafis);
          ArrayList<PObject> libraryObjects = new ArrayList<PObject>();
          PObject object;
          for (Object streamObject = parser.getObject(library); streamObject != null; streamObject = parser
          .getObject(library))

          { object = (PObject) streamObject; stateManager.addChange(object); library.addObject(object.getObject(), object.getReference()); libraryObjects.add((PObject) streamObject); }

          // re-initialized page's and the annotations
          document.getPageTree().resetInitializedState();
          for (PObject pObject : libraryObjects) {
          Object tmp = pObject.getObject();
          if (tmp instanceof Page)

          { ((Page)tmp).resetInitializedState(); }

          if (tmp instanceof Dictionary)

          { ((Dictionary) tmp).init(); }

          }

          rafis.close();
          } catch (FileNotFoundException e)

          { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }

          this.updateDocumentView();

          }

          Show
          Patrick Corless added a comment - A bug was found with the existing annotation import code. The bug prevented an annotations content stream from being correctly parsed and painted. The resulting state did not provided enough information for the viewer to properly construct the annotations appearance stream. The changes needed to correct this issue require changes to the core but with these changes the process of importing annotations has been simplified. Assuming the call: _ICEpdfController.openDocument("../reader_overview.pdf"); _ICEpdfController.loadExternalObjects(); Where loadExternalObjects() is defined as: public void loadExternalObjects() { try { SeekableInput rafis = RandomAccessFileInputStream.build( new File(this.getDocument() .getDocumentOrigin() + ".txt")); Document document = this.getDocument(); Library library = document.getCatalog().getLibrary(); StateManager stateManager = library.getStateManager(); Parser parser = new Parser(rafis); ArrayList<PObject> libraryObjects = new ArrayList<PObject>(); PObject object; for (Object streamObject = parser.getObject(library); streamObject != null; streamObject = parser .getObject(library)) { object = (PObject) streamObject; stateManager.addChange(object); library.addObject(object.getObject(), object.getReference()); libraryObjects.add((PObject) streamObject); } // re-initialized page's and the annotations document.getPageTree().resetInitializedState(); for (PObject pObject : libraryObjects) { Object tmp = pObject.getObject(); if (tmp instanceof Page) { ((Page)tmp).resetInitializedState(); } if (tmp instanceof Dictionary) { ((Dictionary) tmp).init(); } } rafis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } this.updateDocumentView(); }
          Hide
          Stefan Franz added a comment -

          Hi Patrick,

          the following method dosn't exist:

          document.getPageTree().resetInitializedState();

          Show
          Stefan Franz added a comment - Hi Patrick, the following method dosn't exist: document.getPageTree().resetInitializedState();
          Hide
          Patrick Corless added a comment -

          I'll be getting you a developer drop after the call which contains the new methods and fixes to the core. I've been testing locally and things look good but would like for you feedback before we do a full patch release.

          Show
          Patrick Corless added a comment - I'll be getting you a developer drop after the call which contains the new methods and fixes to the core. I've been testing locally and things look good but would like for you feedback before we do a full patch release.
          Hide
          Patrick Corless added a comment -

          Changes have been checked into the 5.0.1 branch and trunk.

          Show
          Patrick Corless added a comment - Changes have been checked into the 5.0.1 branch and trunk.
          Hide
          Stefan Franz added a comment - - edited

          Dear Patrick,

          I downloaded the developer drop and tested a little bit. Reloading of the annotations seems better now. Unfortunatly I'am not able to change the once made annotations. If I reload them in the viewer I have to made a new annotation first. After that I'am able to change or delete the old ones. After saving these changed annotations I tried to reload them a second time but this failed with the following stacktrace:

          22.07.2013 10:40:51 org.icepdf.core.pobjects.Catalog <clinit>
          INFO: ICEsoft ICEpdf Core 5.0.1
          22.07.2013 10:40:51 org.icepdf.core.pobjects.fonts.nfont.Font <clinit>
          INFO: ICEsoft ICEpdf Pro 5.0.1
          22.07.2013 10:41:02 org.icepdf.core.util.Parser getObject
          WARNUNG: IO reading error.
          22.07.2013 10:41:02 org.icepdf.core.util.content.NContentParser parse
          WARNUNG: Error parsing content stream.
          java.util.EmptyStackException
          at java.util.Stack.peek(Unknown Source)
          at java.util.Stack.pop(Unknown Source)
          at org.icepdf.core.util.content.AbstractContentParser.consume_d(AbstractContentParser.java:642)
          at org.icepdf.core.util.content.NContentParser.parse(Unknown Source)
          at org.icepdf.core.pobjects.Form.init(Form.java:168)
          at org.icepdf.core.pobjects.annotations.Annotation.init(Annotation.java:643)
          at org.icepdf.core.pobjects.annotations.MarkupAnnotation.init(MarkupAnnotation.java:172)
          at org.icepdf.core.pobjects.annotations.TextMarkupAnnotation.init(TextMarkupAnnotation.java:150)
          at test.MySwingController.loadExternalObjects(MySwingController.java:223)
          at test.MySwingController.openURL(MySwingController.java:187)
          at org.icepdf.ri.common.SwingController$8.run(SwingController.java:3672)
          at java.awt.event.InvocationEvent.dispatch(Unknown Source)
          at java.awt.EventQueue.dispatchEvent(Unknown Source)
          at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
          at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
          at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
          at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
          at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
          at java.awt.EventDispatchThread.run(Unknown Source)
          22.07.2013 10:41:02 org.icepdf.core.util.content.NContentParser parse
          WARNUNG: Error parsing content stream.
          java.util.EmptyStackException
          at java.util.Stack.peek(Unknown Source)
          at java.util.Stack.pop(Unknown Source)
          at org.icepdf.core.util.content.AbstractContentParser.consume_K(AbstractContentParser.java:203)
          at org.icepdf.core.util.content.NContentParser.parse(Unknown Source)
          at org.icepdf.core.pobjects.Form.init(Form.java:168)
          at org.icepdf.core.pobjects.annotations.Annotation.init(Annotation.java:643)
          at org.icepdf.core.pobjects.annotations.MarkupAnnotation.init(MarkupAnnotation.java:172)
          at org.icepdf.core.pobjects.annotations.TextMarkupAnnotation.init(TextMarkupAnnotation.java:150)
          at test.MySwingController.loadExternalObjects(MySwingController.java:223)
          at test.MySwingController.openURL(MySwingController.java:187)
          at org.icepdf.ri.common.SwingController$8.run(SwingController.java:3672)
          at java.awt.event.InvocationEvent.dispatch(Unknown Source)
          at java.awt.EventQueue.dispatchEvent(Unknown Source)
          at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
          at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
          at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
          at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
          at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
          at java.awt.EventDispatchThread.run(Unknown Source)

          This is my SwingController Implementation:

          package test;

          import java.io.File;
          import java.io.FileNotFoundException;
          import java.io.FileOutputStream;
          import java.util.ArrayList;

          import javax.swing.JOptionPane;

          import org.icepdf.core.io.RandomAccessFileInputStream;
          import org.icepdf.core.io.SeekableInput;
          import org.icepdf.core.pobjects.Dictionary;
          import org.icepdf.core.pobjects.Document;
          import org.icepdf.core.pobjects.PObject;
          import org.icepdf.core.pobjects.Page;
          import org.icepdf.core.pobjects.StateManager;
          import org.icepdf.core.util.IncrementalUpdater;
          import org.icepdf.core.util.Library;
          import org.icepdf.core.util.Parser;
          import org.icepdf.ri.common.SwingController;

          public class MySwingController extends SwingController {

          public MySwingController()

          { super(); }

          public void saveMarkupFile() throws Exception {

          byte[][] updates = IncrementalUpdater.getUpdatedDocumentObjects(this
          .getDocument());
          String sFile = this.getDocument().getDocumentOrigin() + ".txt";
          System.out.println("File: " + sFile);
          FileOutputStream fileOutputStream = new FileOutputStream(sFile);

          for (byte[] update : updates)

          { fileOutputStream.write(update); }

          fileOutputStream.close();
          }

          @Override
          public void saveFile() {

          if (!this.getDocument().getStateManager().isChanged()
          && !Document.foundIncrementalUpdater)

          { org.icepdf.ri.util.Resources.showMessageDialog(this .getViewerFrame(), JOptionPane.INFORMATION_MESSAGE, this .getMessageBundle(), "viewer.dialog.saveAs.noUpdates.title", "viewer.dialog.saveAs.noUpdates.msg"); return; }

          try

          { saveMarkupFile(); }

          catch (Exception e)

          { // TODO Auto-generated catch block e.printStackTrace(); }

          }

          @Override
          public void openURL() {

          try { this.loadExternalObjects(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }

          }

          public void loadExternalObjects() {
          try {
          SeekableInput rafis = RandomAccessFileInputStream.build(new File(
          this.getDocument().getDocumentOrigin() + ".txt"));
          Document document = this.getDocument();
          Library library = document.getCatalog().getLibrary();
          StateManager stateManager = library.getStateManager();
          Parser parser = new Parser(rafis);
          ArrayList<PObject> libraryObjects = new ArrayList<PObject>();
          PObject object;
          for (Object streamObject = parser.getObject(library); streamObject != null; streamObject = parser
          .getObject(library))

          { object = (PObject) streamObject; stateManager.addChange(object); library.addObject(object.getObject(), object.getReference()); libraryObjects.add((PObject) streamObject); }

          // re-initialized page's and the annotations
          document.getPageTree().resetInitializedState();
          for (PObject pObject : libraryObjects) {
          Object tmp = pObject.getObject();
          if (tmp instanceof Page)

          { ((Page) tmp).resetInitializedState(); }

          if (tmp instanceof Dictionary)

          { ((Dictionary) tmp).init(); }

          }
          rafis.close();
          } catch (FileNotFoundException e)

          { e.printStackTrace(); return; }

          catch (Exception e)

          { e.printStackTrace(); }

          this.updateDocumentView();
          }
          }

          Show
          Stefan Franz added a comment - - edited Dear Patrick, I downloaded the developer drop and tested a little bit. Reloading of the annotations seems better now. Unfortunatly I'am not able to change the once made annotations. If I reload them in the viewer I have to made a new annotation first. After that I'am able to change or delete the old ones. After saving these changed annotations I tried to reload them a second time but this failed with the following stacktrace: 22.07.2013 10:40:51 org.icepdf.core.pobjects.Catalog <clinit> INFO: ICEsoft ICEpdf Core 5.0.1 22.07.2013 10:40:51 org.icepdf.core.pobjects.fonts.nfont.Font <clinit> INFO: ICEsoft ICEpdf Pro 5.0.1 22.07.2013 10:41:02 org.icepdf.core.util.Parser getObject WARNUNG: IO reading error. 22.07.2013 10:41:02 org.icepdf.core.util.content.NContentParser parse WARNUNG: Error parsing content stream. java.util.EmptyStackException at java.util.Stack.peek(Unknown Source) at java.util.Stack.pop(Unknown Source) at org.icepdf.core.util.content.AbstractContentParser.consume_d(AbstractContentParser.java:642) at org.icepdf.core.util.content.NContentParser.parse(Unknown Source) at org.icepdf.core.pobjects.Form.init(Form.java:168) at org.icepdf.core.pobjects.annotations.Annotation.init(Annotation.java:643) at org.icepdf.core.pobjects.annotations.MarkupAnnotation.init(MarkupAnnotation.java:172) at org.icepdf.core.pobjects.annotations.TextMarkupAnnotation.init(TextMarkupAnnotation.java:150) at test.MySwingController.loadExternalObjects(MySwingController.java:223) at test.MySwingController.openURL(MySwingController.java:187) at org.icepdf.ri.common.SwingController$8.run(SwingController.java:3672) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) 22.07.2013 10:41:02 org.icepdf.core.util.content.NContentParser parse WARNUNG: Error parsing content stream. java.util.EmptyStackException at java.util.Stack.peek(Unknown Source) at java.util.Stack.pop(Unknown Source) at org.icepdf.core.util.content.AbstractContentParser.consume_K(AbstractContentParser.java:203) at org.icepdf.core.util.content.NContentParser.parse(Unknown Source) at org.icepdf.core.pobjects.Form.init(Form.java:168) at org.icepdf.core.pobjects.annotations.Annotation.init(Annotation.java:643) at org.icepdf.core.pobjects.annotations.MarkupAnnotation.init(MarkupAnnotation.java:172) at org.icepdf.core.pobjects.annotations.TextMarkupAnnotation.init(TextMarkupAnnotation.java:150) at test.MySwingController.loadExternalObjects(MySwingController.java:223) at test.MySwingController.openURL(MySwingController.java:187) at org.icepdf.ri.common.SwingController$8.run(SwingController.java:3672) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) This is my SwingController Implementation: package test; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.util.ArrayList; import javax.swing.JOptionPane; import org.icepdf.core.io.RandomAccessFileInputStream; import org.icepdf.core.io.SeekableInput; import org.icepdf.core.pobjects.Dictionary; import org.icepdf.core.pobjects.Document; import org.icepdf.core.pobjects.PObject; import org.icepdf.core.pobjects.Page; import org.icepdf.core.pobjects.StateManager; import org.icepdf.core.util.IncrementalUpdater; import org.icepdf.core.util.Library; import org.icepdf.core.util.Parser; import org.icepdf.ri.common.SwingController; public class MySwingController extends SwingController { public MySwingController() { super(); } public void saveMarkupFile() throws Exception { byte[][] updates = IncrementalUpdater.getUpdatedDocumentObjects(this .getDocument()); String sFile = this.getDocument().getDocumentOrigin() + ".txt"; System.out.println("File: " + sFile); FileOutputStream fileOutputStream = new FileOutputStream(sFile); for (byte[] update : updates) { fileOutputStream.write(update); } fileOutputStream.close(); } @Override public void saveFile() { if (!this.getDocument().getStateManager().isChanged() && !Document.foundIncrementalUpdater) { org.icepdf.ri.util.Resources.showMessageDialog(this .getViewerFrame(), JOptionPane.INFORMATION_MESSAGE, this .getMessageBundle(), "viewer.dialog.saveAs.noUpdates.title", "viewer.dialog.saveAs.noUpdates.msg"); return; } try { saveMarkupFile(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void openURL() { try { this.loadExternalObjects(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void loadExternalObjects() { try { SeekableInput rafis = RandomAccessFileInputStream.build(new File( this.getDocument().getDocumentOrigin() + ".txt")); Document document = this.getDocument(); Library library = document.getCatalog().getLibrary(); StateManager stateManager = library.getStateManager(); Parser parser = new Parser(rafis); ArrayList<PObject> libraryObjects = new ArrayList<PObject>(); PObject object; for (Object streamObject = parser.getObject(library); streamObject != null; streamObject = parser .getObject(library)) { object = (PObject) streamObject; stateManager.addChange(object); library.addObject(object.getObject(), object.getReference()); libraryObjects.add((PObject) streamObject); } // re-initialized page's and the annotations document.getPageTree().resetInitializedState(); for (PObject pObject : libraryObjects) { Object tmp = pObject.getObject(); if (tmp instanceof Page) { ((Page) tmp).resetInitializedState(); } if (tmp instanceof Dictionary) { ((Dictionary) tmp).init(); } } rafis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); return; } catch (Exception e) { e.printStackTrace(); } this.updateDocumentView(); } }
          Hide
          Patrick Corless added a comment -

          Thanks for the feedback, I've updated my test to test for multiple saves during the same session. Two problem were discovered.

          The first is that we were not correctly incremented the next available object numbers when doing the data import which was messing up the expected object hierarchy. This was the result of not have an updated xref table which would be the normal when saving the whole PDF document.

          The second issue was related to re-saving a stream that as part of the import but not altered. The unaltered content streams were then recompressed and unreadable the next time around.

          Show
          Patrick Corless added a comment - Thanks for the feedback, I've updated my test to test for multiple saves during the same session. Two problem were discovered. The first is that we were not correctly incremented the next available object numbers when doing the data import which was messing up the expected object hierarchy. This was the result of not have an updated xref table which would be the normal when saving the whole PDF document. The second issue was related to re-saving a stream that as part of the import but not altered. The unaltered content streams were then recompressed and unreadable the next time around.
          Hide
          Patrick Corless added a comment -

          A new developer build has been prepped for testing.

          Show
          Patrick Corless added a comment - A new developer build has been prepped for testing.
          Hide
          Stefan Franz added a comment - - edited

          some annotations still missing, here: blue circle annotation where you can see the "invisible" frame (small dotted line) around the annotation but not the annotation itself

          Show
          Stefan Franz added a comment - - edited some annotations still missing, here: blue circle annotation where you can see the "invisible" frame (small dotted line) around the annotation but not the annotation itself
          Hide
          Stefan Franz added a comment - - edited

          Okay, thank you for the new test build. Some errors still occured:

          • When I load annotations from stream now they won't be rendered immediately. Sometimes it took some seconds until they are visible.
          • Existing rectangles and circles are not rendered sometimes (screenshot)
          • There are some errors in log: 23.07.2013 14:37:07 org.icepdf.core.util.Parser getObject WARNUNG: IO reading error.
          Show
          Stefan Franz added a comment - - edited Okay, thank you for the new test build. Some errors still occured: When I load annotations from stream now they won't be rendered immediately. Sometimes it took some seconds until they are visible. Existing rectangles and circles are not rendered sometimes (screenshot) There are some errors in log: 23.07.2013 14:37:07 org.icepdf.core.util.Parser getObject WARNUNG: IO reading error.
          Hide
          Patrick Corless added a comment -

          Stefan, thanks for the feedback, could you post you test import file?

          Show
          Patrick Corless added a comment - Stefan, thanks for the feedback, could you post you test import file?
          Hide
          Stefan Franz added a comment -

          I uploaded mist.pdf + annotation. The sample from the screenshot is from our content management system and could not saved localy.

          Show
          Stefan Franz added a comment - I uploaded mist.pdf + annotation. The sample from the screenshot is from our content management system and could not saved localy.
          Hide
          Patrick Corless added a comment -

          Marking as resolved.

          Show
          Patrick Corless added a comment - Marking as resolved.

            People

            • Assignee:
              Patrick Corless
              Reporter:
              Stefan Franz
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: