edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil.java Source code

Java tutorial

Introduction

Here is the source code for edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil.java

Source

/* $This file is distributed under the terms of the license in /doc/license.txt$ */

package edu.cornell.mannlib.vitro.webapp.web.images;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Map.Entry;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

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

import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;

/**
 * A utility for finding the URL of the correct Placeholder image.
 * 
 * The mapping of image URLs to classes is created at startup, and stored in the
 * ServletContext.
 */
public class PlaceholderUtil {
    private static final Log log = LogFactory.getLog(PlaceholderUtil.class);

    private static final String ATTRIBUTE_NAME = PlaceholderUtil.class.getName();
    private static final String PROPERTIES_FILE_PATH = "/images/placeholders/placeholders.properties";
    private static final String DEFAULT_IMAGE_PATH = "/images/placeholders/thumbnail.jpg";

    // ----------------------------------------------------------------------
    // Static methods
    // ----------------------------------------------------------------------

    /**
     * If we have a placeholder image for this exact type, return it. Otherwise,
     * return the default.
     */
    public static String getPlaceholderImagePathForType(VitroRequest vreq, String typeUri) {
        PlaceholderUtil pu = getPlaceholderUtil(vreq);
        if (pu == null) {
            return DEFAULT_IMAGE_PATH;
        } else {
            return pu.getPlaceholderImagePathForType(typeUri);
        }
    }

    /**
     * If there is a placeholder image for any type that this Individual
     * instantiates, return that image. Otherwise, return the default.
     */
    public static String getPlaceholderImagePathForIndividual(VitroRequest vreq, String individualUri) {
        PlaceholderUtil pu = getPlaceholderUtil(vreq);
        if (pu == null) {
            return DEFAULT_IMAGE_PATH;
        } else {
            IndividualDao iDao = vreq.getWebappDaoFactory().getIndividualDao();
            return pu.getPlaceholderImagePathForIndividual(iDao, individualUri);
        }
    }

    /** Get the PlaceholderUtil instance from the context, or null if none. */
    private static PlaceholderUtil getPlaceholderUtil(VitroRequest vreq) {
        if (vreq == null) {
            return null;
        }
        ServletContext ctx = vreq.getSession().getServletContext();
        Object attrib = ctx.getAttribute(ATTRIBUTE_NAME);
        if (attrib instanceof PlaceholderUtil) {
            return (PlaceholderUtil) attrib;
        } else {
            log.warn("Looked for a PlaceholerUtil, but found " + attrib);
            return null;
        }
    }

    // ----------------------------------------------------------------------
    // The object
    // ----------------------------------------------------------------------

    private final Map<String, String> mapUrlsByClass;

    private PlaceholderUtil(Map<String, String> map) {
        this.mapUrlsByClass = Collections.unmodifiableMap(new HashMap<String, String>(map));
    }

    /**
     * If we have a placeholder image for this exact type, return it. Otherwise,
     * return the default.
     */
    private String getPlaceholderImagePathForType(String typeUri) {
        if (typeUri == null) {
            log.debug("getPlaceholderImagePathForType: typeUri is null");
            return DEFAULT_IMAGE_PATH;
        }
        String url = mapUrlsByClass.get(typeUri);
        if (url == null) {
            log.debug("getPlaceholderImagePathForType: no value for '" + typeUri + "'");
            return DEFAULT_IMAGE_PATH;
        }
        log.debug("getPlaceholderImagePathForType: value for '" + typeUri + "' is '" + url + "'");
        return url;
    }

    /**
     * If there is a placeholder image for any type that this Individual
     * instantiates, return that image. Otherwise, return the default.
     */
    private String getPlaceholderImagePathForIndividual(IndividualDao iDao, String individualUri) {
        if (individualUri == null) {
            log.debug("getPlaceholderImagePathForIndividual: " + "individualUri is null");
            return DEFAULT_IMAGE_PATH;
        }
        for (String classUri : mapUrlsByClass.keySet()) {
            String imageUrl = mapUrlsByClass.get(classUri);
            if (iDao.isIndividualOfClass(classUri, individualUri)) {
                log.debug("getPlaceholderImagePathForIndividual: individual '" + individualUri + "' is of class '"
                        + classUri + "', value is '" + imageUrl + "'");
                return imageUrl;
            }
        }
        log.debug("getPlaceholderImagePathForIndividual: individual '" + individualUri
                + "' is not of any recognized class");
        return DEFAULT_IMAGE_PATH;
    }

    // ----------------------------------------------------------------------
    // Classes used for setup
    // ----------------------------------------------------------------------

    public static class Setup implements ServletContextListener {
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            ServletContext ctx = sce.getServletContext();
            StartupStatus ss = StartupStatus.getBean(ctx);

            try {
                File propertiesFile = confirmRealPath(ctx, PROPERTIES_FILE_PATH);
                Map<String, String> map = loadPropertiesToMap(propertiesFile);
                confirmImagesArePresent(ctx, map);
                ctx.setAttribute(ATTRIBUTE_NAME, new PlaceholderUtil(map));
            } catch (SetupException e) {
                if (e.getCause() == null) {
                    ss.warning(this, e.getMessage());
                } else {
                    ss.warning(this, e.getMessage(), e.getCause());
                }
            }
        }

        private Map<String, String> loadPropertiesToMap(File propertiesFile) throws SetupException {
            Properties props = new Properties();
            try {
                props.load(new FileReader(propertiesFile));
            } catch (IOException e) {
                throw new SetupException("Can't load properties from the file at '" + PROPERTIES_FILE_PATH
                        + "'. Is it in a valid format?", e);
            }

            Map<String, String> map = new HashMap<String, String>();
            for (Enumeration<Object> keys = props.keys(); keys.hasMoreElements();) {
                String key = (String) keys.nextElement();
                String value = props.getProperty(key);
                map.put(key, value);
            }

            return map;
        }

        private void confirmImagesArePresent(ServletContext ctx, Map<String, String> map) throws SetupException {
            Set<String> imageUrls = new HashSet<String>();
            imageUrls.add(DEFAULT_IMAGE_PATH);
            imageUrls.addAll(map.values());
            for (String imageUrl : imageUrls) {
                confirmRealPath(ctx, imageUrl);
            }

        }

        private File confirmRealPath(ServletContext ctx, String url) throws SetupException {
            String path = ctx.getRealPath(url);
            if (path == null) {
                throw new SetupException("Can't translate to real path: '" + url + "'");
            }
            File file = new File(path);
            if (!file.exists()) {
                throw new SetupException("No file found at '" + url + "'.");
            }
            if (!file.canRead()) {
                throw new SetupException("Can't read the file at '" + url + "'.");
            }
            return file;
        }

        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            sce.getServletContext().removeAttribute(ATTRIBUTE_NAME);
        }

    }

    private static class SetupException extends Exception {
        public SetupException(String message) {
            super(message);
        }

        public SetupException(String message, Throwable cause) {
            super(message, cause);
        }
    }
}