/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id: ImageHandlerRegistry.java 1780541 2017-01-27 11:27:04Z ssteiner $ */

package org.apache.fop.render;

import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.util.Service;

This class holds references to various image handlers. It also supports automatic discovery of additional handlers available through the class path.
/** * This class holds references to various image handlers. It also * supports automatic discovery of additional handlers available through * the class path. */
public class ImageHandlerRegistry {
the logger
/** the logger */
private static Log log = LogFactory.getLog(ImageHandlerRegistry.class); private static final Comparator<ImageHandler> HANDLER_COMPARATOR = new Comparator<ImageHandler>() { public int compare(ImageHandler o1, ImageHandler o2) { ImageHandler h1 = o1; ImageHandler h2 = o2; return h1.getPriority() - h2.getPriority(); } };
Map containing image handlers for various Image subclasses.
/** Map containing image handlers for various {@link Image} subclasses. */
private Map<Class<? extends Image>, ImageHandler> handlers = new java.util.HashMap<Class<? extends Image>, ImageHandler>();
List containing the same handlers as above but ordered by priority
/** List containing the same handlers as above but ordered by priority */
private List<ImageHandler> handlerList = new java.util.LinkedList<ImageHandler>(); private int handlerRegistrations;
Default constructor.
/** * Default constructor. */
public ImageHandlerRegistry() { discoverHandlers(); }
Add an PDFImageHandler. The handler itself is inspected to find out what it supports.
Params:
  • classname – the fully qualified class name
/** * Add an PDFImageHandler. The handler itself is inspected to find out what it supports. * @param classname the fully qualified class name */
public void addHandler(String classname) { try { ImageHandler handlerInstance = (ImageHandler)Class.forName(classname).getDeclaredConstructor().newInstance(); addHandler(handlerInstance); } catch (ClassNotFoundException e) { throw new IllegalArgumentException("Could not find " + classname); } catch (InstantiationException e) { throw new IllegalArgumentException("Could not instantiate " + classname); } catch (IllegalAccessException e) { throw new IllegalArgumentException("Could not access " + classname); } catch (ClassCastException e) { throw new IllegalArgumentException(classname + " is not an " + ImageHandler.class.getName()); } catch (NoSuchMethodException e) { throw new IllegalArgumentException(e); } catch (InvocationTargetException e) { throw new IllegalArgumentException(e); } }
Add an image handler. The handler itself is inspected to find out what it supports.
Params:
  • handler – the ImageHandler instance
/** * Add an image handler. The handler itself is inspected to find out what it supports. * @param handler the ImageHandler instance */
public synchronized void addHandler(ImageHandler handler) { Class<? extends Image> imageClass = handler.getSupportedImageClass(); //List this.handlers.put(imageClass, handler); //Sorted insert (sort by priority) ListIterator<ImageHandler> iter = this.handlerList.listIterator(); while (iter.hasNext()) { ImageHandler h = iter.next(); if (HANDLER_COMPARATOR.compare(handler, h) < 0) { iter.previous(); break; } } iter.add(handler); this.handlerRegistrations++; }
Returns an ImageHandler which handles an specific image type given the MIME type of the image.
Params:
  • targetContext – the target rendering context that is used for identifying compatibility
  • image – the Image to be handled
Returns:the image handler responsible for handling the image or null if none is available
/** * Returns an {@link ImageHandler} which handles an specific image type given the MIME type * of the image. * @param targetContext the target rendering context that is used for identifying compatibility * @param image the Image to be handled * @return the image handler responsible for handling the image or null if none is available */
public ImageHandler getHandler(RenderingContext targetContext, Image image) { for (ImageHandler h : this.handlerList) { if (h.isCompatible(targetContext, image)) { //Return the first handler in the prioritized list that is compatible return h; } } return null; }
Returns the ordered array of supported image flavors. The array needs to be ordered by priority so the image loader framework can return the preferred image type.
Params:
  • context – the rendering context
Returns:the array of image flavors
/** * Returns the ordered array of supported image flavors. The array needs to be ordered by * priority so the image loader framework can return the preferred image type. * @param context the rendering context * @return the array of image flavors */
public synchronized ImageFlavor[] getSupportedFlavors(RenderingContext context) { //Extract all ImageFlavors into a single array List<ImageFlavor> flavors = new java.util.ArrayList<ImageFlavor>(); for (ImageHandler handler : this.handlerList) { if (handler.isCompatible(context, null)) { ImageFlavor[] f = handler.getSupportedImageFlavors(); Collections.addAll(flavors, f); } } return flavors.toArray(new ImageFlavor[flavors.size()]); }
Discovers ImageHandler implementations through the classpath and dynamically registers them.
/** * Discovers ImageHandler implementations through the classpath and dynamically * registers them. */
private void discoverHandlers() { // add mappings from available services Iterator providers = Service.providers(ImageHandler.class); if (providers != null) { while (providers.hasNext()) { ImageHandler handler = (ImageHandler)providers.next(); try { if (log.isDebugEnabled()) { log.debug("Dynamically adding ImageHandler: " + handler.getClass().getName()); } addHandler(handler); } catch (IllegalArgumentException e) { log.error("Error while adding ImageHandler", e); } } } } }