org.apache.fop.fo.flow.ExternalGraphic 捕获并记录我想自己处理的 ImageException

org.apache.fop.fo.flow.ExternalGraphic catches and logs ImageException I want to handle myself

出于测试目的,我正在将图像转换为 pdf。

为了确保图像与以后的打印过程兼容,我在上传过程中运行进行了快速测试打印。

我正在使用转换器创建一个简单的 Test-PDF。当我尝试打印格式不兼容的图像时,转换器的 ImageManager 抛出 ImageException,从 preloadImage() 函数开始:

  public ImageInfo preloadImage(String uri, Source src)
            throws ImageException, IOException {
        Iterator iter = registry.getPreloaderIterator();
        while (iter.hasNext()) {
            ImagePreloader preloader = (ImagePreloader)iter.next();
            ImageInfo info = preloader.preloadImage(uri, src, imageContext);
            if (info != null) {
                return info;
            }
        }
        throw new ImageException("The file format is not supported. No ImagePreloader found for "
                + uri);
    }

扔给:

   public ImageInfo needImageInfo(String uri, ImageSessionContext session, ImageManager manager)
                throws ImageException, IOException {
            //Fetch unique version of the URI and use it for synchronization so we have some sort of
            //"row-level" locking instead of "table-level" locking (to use a database analogy).
            //The fine locking strategy is necessary since preloading an image is a potentially long
            //operation.
            if (isInvalidURI(uri)) {
                throw new FileNotFoundException("Image not found: " + uri);
            }
            String lockURI = uri.intern();
            synchronized (lockURI) {
                ImageInfo info = getImageInfo(uri);
                if (info == null) {
                    try {
                        Source src = session.needSource(uri);
                        if (src == null) {
                            registerInvalidURI(uri);
                            throw new FileNotFoundException("Image not found: " + uri);
                        }
                        info = manager.preloadImage(uri, src);
                        session.returnSource(uri, src);
                    } catch (IOException ioe) {
                        registerInvalidURI(uri);
                        throw ioe;
                    } catch (ImageException e) {
                        registerInvalidURI(uri);
                        throw e;
                    }
                    putImageInfo(info);
                }
                return info;
            }
        }

扔给 :

public ImageInfo getImageInfo(String uri, ImageSessionContext session)
                throws ImageException, IOException {
        if (getCache() != null) {
            return getCache().needImageInfo(uri, session, this);
        } else {
            return preloadImage(uri, session);
        }
    }

最终它被捕获并记录在 ExternalGraphic.class:

 /** {@inheritDoc} */
    public void bind(PropertyList pList) throws FOPException {
        super.bind(pList);
        src = pList.get(PR_SRC).getString();

        //Additional processing: obtain the image's intrinsic size and baseline information
        url = URISpecification.getURL(src);
        FOUserAgent userAgent = getUserAgent();
        ImageManager manager = userAgent.getFactory().getImageManager();
        ImageInfo info = null;
        try {
            info = manager.getImageInfo(url, userAgent.getImageSessionContext());
        } catch (ImageException e) {
            ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
                    getUserAgent().getEventBroadcaster());
            eventProducer.imageError(this, url, e, getLocator());
        } catch (FileNotFoundException fnfe) {
            ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
                    getUserAgent().getEventBroadcaster());
            eventProducer.imageNotFound(this, url, fnfe, getLocator());
        } catch (IOException ioe) {
            ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
                    getUserAgent().getEventBroadcaster());
            eventProducer.imageIOError(this, url, ioe, getLocator());
        }
        if (info != null) {
            this.intrinsicWidth = info.getSize().getWidthMpt();
            this.intrinsicHeight = info.getSize().getHeightMpt();
            int baseline = info.getSize().getBaselinePositionFromBottom();
            if (baseline != 0) {
                this.intrinsicAlignmentAdjust
                    = FixedLength.getInstance(-baseline);
            }
        }
    }

这样我就无法在使用转换器的代码中访问它。

我尝试使用自定义 ErrorListener,但转换器仅将 fatalErrors 注册到 ErrorListener。

有没有办法在不修改库代码的情况下访问异常并自己处理?

这比我想象的要容易。在调用转换之前,我向正在使用的 Fop 的用户代理注册了一个 Costum EventListener。这个 Listener 只存储触发了哪种事件的信息,所以如果是 ImageError 我可以抛出异常。

我的听众:

import org.apache.fop.events.Event;
import org.apache.fop.events.EventListener;

public class ImageErrorListener implements EventListener
{

       private String eventKey = "";
private boolean imageError = false;

@Override
public void processEvent(Event event)
{
eventKey = event.getEventKey();
if(eventKey.equals("imageError")) {
    imageError = true;
}
}


public String getEventKey()
{
    return eventKey;
}


public void setEventKey(String eventKey)
{
    this.eventKey = eventKey;
}


public boolean isImageError()
{
    return imageError;
}


public void setImageError(boolean imageError)
{
    this.imageError = imageError;
}    
}

侦听器的使用:

// Start XSLT transformation and FOP processing
    ImageErrorListener imageListener = new ImageErrorListener();

    fop.getUserAgent().getEventBroadcaster().addEventListener(imageListener);
    if (res != null)
    {

        transformer.transform(xmlDomStreamSource, res);
    }

    if(imageListener.isImageError()) {
        throw new ImageException("");
    }

fop 是 Fop 类型,xmlDomStreamSource 是我要转换的 xml-Source,res 是我的 SAXResult。