ome.formats.enums.IQueryEnumProvider.java Source code

Java tutorial

Introduction

Here is the source code for ome.formats.enums.IQueryEnumProvider.java

Source

/*
 * ome.formats.enums.IQueryEnumProvider
 *
 *------------------------------------------------------------------------------
 *  Copyright (C) 2006-2008 University of Dundee. All rights reserved.
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *------------------------------------------------------------------------------
 */

package ome.formats.enums;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import omero.RLong;
import omero.RString;
import omero.ServerError;
import omero.api.IQueryPrx;
import ome.formats.enums.handler.EnumHandlerFactory;
import ome.formats.enums.handler.EnumerationHandler;
import omero.model.IObject;

/**
 * An enumeration provider which uses IQuery and a cache to fulfill the
 * contract of an EnumerationProvider.
 *
 * @author Chris Allan <callan at blackcat dot ca>
 *
 */
public class IQueryEnumProvider implements EnumerationProvider {
    /** Logger for this class. */
    private static Log log = LogFactory.getLog(IQueryEnumProvider.class);

    /** Enumeration cache. */
    private Map<Class<? extends IObject>, HashMap<String, IObject>> enumCache = new HashMap<Class<? extends IObject>, HashMap<String, IObject>>();

    /** Query service. */
    private IQueryPrx iQuery;

    /** Enumeration handler factory. */
    private EnumHandlerFactory enumHandlerFactory = new EnumHandlerFactory();

    /**
     * Default IQuery based enumeration provider constructor.
     * @param iQuery OMERO query service to use for enumeration lookups.
     */
    public IQueryEnumProvider(IQueryPrx iQuery) {
        this.iQuery = iQuery;
    }

    /**
     * Creates an unloaded copy of an enumeration object.
     * @param enumeration Enumeration to copy.
     * @return See above.
     */
    private IObject copyEnumeration(IObject enumeration) {
        Class<? extends IObject> klass = enumeration.getClass();
        try {
            Constructor<? extends IObject> constructor = klass
                    .getDeclaredConstructor(new Class[] { RLong.class, boolean.class });
            return (IObject) constructor.newInstance(new Object[] { enumeration.getId(), false });
        } catch (Exception e) {
            String m = "Unable to copy enumeration: " + enumeration;
            log.error(m, e);
            throw new EnumerationException(m, klass, getValue(enumeration));
        }
    }

    private String getValue(IObject enumeration) {
        Class<? extends IObject> klass = enumeration.getClass();
        try {
            Method method = klass.getMethod("getValue");
            RString value = (RString) method.invoke(enumeration);
            return value.getValue();
        } catch (Exception e) {
            String m = "Unable to get value of enumeration: " + enumeration;
            log.error(m, e);
            throw new EnumerationException(m, klass, "");
        }
    }

    /* (non-Javadoc)
     * @see ome.formats.enums.EnumerationProvider#getEnumeration(java.lang.Class, java.lang.String, boolean)
     */
    public <T extends IObject> T getEnumeration(Class<T> klass, String value, boolean loaded) {
        if (klass == null)
            throw new NullPointerException("Expecting not-null klass.");
        if (value == null) {
            log.warn("Enumeration " + klass + " with value of null.");
        } else if (value.length() == 0) {
            log.warn("Enumeration " + klass + " with value of zero length.");
        }

        HashMap<String, T> enumerations = getEnumerations(klass);
        EnumerationHandler handler = enumHandlerFactory.getHandler(klass);
        IObject otherEnumeration = enumerations.get("Other");
        // Step 1, check if we've got an exact match for our enumeration value.
        if (enumerations.containsKey(value)) {
            log.debug(String.format("Returning %s exact match for: %s", klass.toString(), value));
            if (!loaded) {
                return (T) copyEnumeration(enumerations.get(value));
            }
            return enumerations.get(value);
        }
        // Step 2, check if our enumeration handler can find a match.
        IObject enumeration = handler.findEnumeration((HashMap<String, IObject>) enumerations, value);
        if (enumeration != null) {
            log.debug(String.format("Handler found %s match for: %s", klass.toString(), value));
            if (!loaded) {
                return (T) copyEnumeration(enumeration);
            }
            return (T) enumeration;
        }
        // Step 3, fall through to an "Other" enumeration if we have one.
        if (otherEnumeration != null) {
            log.warn("Enumeration '" + value + "' does not exist in '" + klass + "' setting to 'Other'");
            return (T) otherEnumeration;
        }
        // Step 4, warn we have no enumeration to return.
        log.warn("Enumeration '" + value + "' does not exist in '" + klass + "' returning 'null'");
        return (T) enumeration;
    }

    /* (non-Javadoc)
     * @see ome.formats.enums.EnumerationProvider#getEnumerations(java.lang.Class)
     */
    public <T extends IObject> HashMap<String, T> getEnumerations(Class<T> klass) {
        if (!enumCache.containsKey(klass)) {
            List<IObject> enumerationList;
            try {
                enumerationList = (List<IObject>) iQuery.findAll(klass.getName(), null);
            } catch (ServerError e) {
                throw new RuntimeException(e);
            }

            if (enumerationList == null)
                throw new EnumerationException("Problem finding enumeration: ", klass, null);

            HashMap<String, IObject> enumerations = new HashMap<String, IObject>();
            for (IObject enumeration : enumerationList) {
                enumerations.put(getValue(enumeration), enumeration);
            }
            enumCache.put(klass, enumerations);
        }
        return (HashMap<String, T>) enumCache.get(klass);
    }
}