org.apache.fop.fo.flow.ExternalGraphic ловит и регистрирует ImageException Я хочу справиться сам - PullRequest
2 голосов
/ 12 марта 2019

Я преобразую изображение в 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.

Есть ли способ получить доступ к Исключению и обработать его самостоятельно, не изменяя код библиотеки?

1 Ответ

1 голос
/ 12 марта 2019

Это было проще, чем я думал.Прежде чем я вызову преобразование, я регистрирую Costum EventListener в пользовательском агенте Fop, который я использую.Этот слушатель просто хранит информацию о том, какое событие было вызвано, поэтому я могу выдать исключение, если это ошибка 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...