简体   繁体   English

使用PDFClown的展平表单抛出IndexOutOfBounds异常

[英]Flattening form using PDFClown throws IndexOutOfBounds exception

I'm using PDFClown-0.2.0 to flatten this pdf file. 我正在使用PDFClown-0.2.0来展平 pdf文件。 This is the code I have: 这是我的代码:

import org.pdfclown.documents.Document;
import org.pdfclown.files.File;
import org.pdfclown.files.SerializationModeEnum;
import org.pdfclown.tools.FormFlattener;

public class Sample {
    public static void main(String args[]){
        try {
            File f = new File("label.pdf");
            Document doc = f.getDocument();

            FormFlattener formFlattener = new FormFlattener();
            formFlattener.flatten(doc);
            f.save(SerializationModeEnum.Standard);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

I'm following the instruction provided at http://pdfclown.org/2014/09/12/waiting-for-pdf-clown-0-2-0-release/#FormFlattening . 我正在按照http://pdfclown.org/2014/09/12/waiting-for-pdf-clown-0-2-0-release/#FormFlattening提供的说明进行操作。 However, when I run the code, I get the following error: 但是,当我运行代码时,出现以下错误:

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.get(ArrayList.java:429)
    at org.pdfclown.objects.PdfArray.get(PdfArray.java:314)
    at org.pdfclown.documents.interaction.forms.FieldWidgets.get(FieldWidgets.java:135)
    at org.pdfclown.documents.interaction.forms.FieldWidgets$1.next(FieldWidgets.java:380)
    at org.pdfclown.documents.interaction.forms.FieldWidgets$1.next(FieldWidgets.java:1)
    at org.pdfclown.tools.FormFlattener.flatten(FormFlattener.java:74)
    at com.narvar.webservices.returns.retailers.Sample.main(Sample.java:18)

What am I doing wrong? 我究竟做错了什么? Just a note that the pdf was generated using PDFBox, and I had made the form fields readonly. 请注意,pdf是使用PDFBox生成的,而我已将表单字段设置为只读。

Having debugged into the code it looks like a PdfClown bug: 调试完代码后,它看起来像是一个PdfClown错误:

The Iterator returned by org.pdfclown.documents.interaction.forms.FieldWidgets.iterator() does not recognize that the widget collection underneath has changed (gotten smaller) and so tries to read beyond its size. org.pdfclown.documents.interaction.forms.FieldWidgets.iterator()返回的Iterator无法识别下方的小部件集合已更改(变小了),因此尝试读取超出其大小的内容。

In detail: 详细:

org.pdfclown.tools.FormFlattener.flatten(Document) iterates over the widgets of a field: org.pdfclown.tools.FormFlattener.flatten(Document)遍历字段的小部件:

  for(Widget widget : field.getWidgets())

but inside this loop it removes the current widget from the Kids of the current field: 但在此循环中,它将从当前字段的“ 孩子”中删除当前小部件:

    // Removing the field references relating the widget...
    PdfDictionary fieldPartDictionary = widget.getBaseDataObject();
    while (fieldPartDictionary != null)
    {
      [...]
      kidsArray.remove(fieldPartDictionary.getReference());
      [...]
    }

Thus, the collection over which the outer for iterates changes. 因此, for外部迭代的集合会发生变化。 Unfortunately the Iterator used here is not aware of changes in the base collection 不幸的是,此处使用的Iterator并不了解基本集合中的更改

return new Iterator<Widget>()
{
  /** Index of the next item. */
  private int index = 0;
  /** Collection size. */
  private final int size = size();

  @Override
  public boolean hasNext( )
  {return (index < size);}

  @Override
  public Widget next( )
  {
    if(!hasNext()) throw new NoSuchElementException();
    return get(index++);
  }

  @Override
  public void remove( )
  {throw new UnsupportedOperationException();}
};

As you see it not merely neither is informed nor is checking itself the base collection, it even has its own idea about the collection size which is the size of the collection at Iterator generation set in size . 如您所见,它不仅不通知基础集合,也不对其自身进行检查,它甚至对集合大小有自己的想法,这是在Iterator生成时将size设置为size集合的size

Such an Iterator implementation is ok for non-changing collections which can be enforced by architecture or by contract. 对于可以通过体系结构或合同强制实施的不变集合,这样的Iterator实现是可以的。 But in the case at hand here I see neither, the architecture obviously allows the collection to change, and there is no hint that the iterator in question may be used only for stable base collections. 但是在这里的情况下,我看不到任何东西,该体系结构显然允许更改集合,并且没有暗示所讨论的迭代器仅可用于稳定的基本集合。

This should be fixed. 这应该是固定的。

A solution approach 解决方案

A solution can be attempted by changing FormFlattener.flatten to retrieve a local copy of the widgets and iterate over this copy, eg by replacing 可以通过更改FormFlattener.flatten来尝试解决方案,以检索小部件的本地副本并在该副本上进行迭代,例如通过替换

  for(Widget widget : field.getWidgets())

with

  List<Widget> widgets = new ArrayList<Widget>(field.getWidgets());
  for(Widget widget : widgets)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM