    001/*****************************************************************************
    002 * Copyright by The HDF Group.                                               *
    003 * Copyright by the Board of Trustees of the University of Illinois.         *
    004 * All rights reserved.                                                      *
    005 *                                                                           *
    006 * This file is part of the HDF Java Products distribution.                  *
    007 * The full copyright notice, including terms governing use, modification,   *
    008 * and redistribution, is contained in the COPYING file, which can be found  *
    009 * at the root of the source code distribution tree,                         *
    010 * or in https://www.hdfgroup.org/licenses.                                  *
    011 * If you do not have access to either file, you may request a copy from     *
    012 * help@hdfgroup.org.                                                        *
    013 ****************************************************************************/
    014
    015package hdf.view.DataView;
    016
    017import java.util.List;
    018
    019import org.slf4j.Logger;
    020import org.slf4j.LoggerFactory;
    021
    022import hdf.view.Tools;
    023import hdf.view.ViewProperties;
    024import hdf.view.ViewProperties.DataViewType;
    025import hdf.view.ImageView.DefaultImageViewFactory;
    026import hdf.view.MetaDataView.DefaultMetaDataViewFactory;
    027import hdf.view.PaletteView.DefaultPaletteViewFactory;
    028import hdf.view.TableView.DefaultTableViewFactory;
    029import hdf.view.TreeView.DefaultTreeViewFactory;
    030
    031/**
    032 * Following the Abstract Factory Pattern, represents a class to produce
    033 * different types of DataView factory classes depending on the given
    034 * DataViewType enum value.
    035 *
    036 * @author jhenderson
    037 * @version 1.0 4/17/2018
    038 */
    039public class DataViewFactoryProducer {
    040
    041    private static final Logger log = LoggerFactory.getLogger(DataViewFactoryProducer.class);
    042
    043    /**
    044     * get the requested DataViewFactory
    045     *
    046     *
    047     * @param viewType
    048     *             The data view type requested
    049     *
    050     * @throws Exception
    051     *             If there is an error getting the class for a data view factory.
    052     *
    053     * @return the data view factory.
    054     */
    055    public static DataViewFactory getFactory(DataViewType viewType) throws Exception {
    056        String factoryClassName = null;
    057        DataViewFactory theFactory = null;
    058        List<?> moduleList = null;
    059
    060        /*
    061         * First determine if we are using the default module for the requested DataViewFactory
    062         * class. If not, we will attempt to load the given DataViewFactory class.
    063         */
    064        switch (viewType) {
    065            case TABLE:
    066                /* Retrieve the "currently selected" TableViewFactory class to use */
    067                moduleList = ViewProperties.getTableViewList();
    068                if ((moduleList == null) || (moduleList.size() <= 0)) {
    069                    return null;
    070                }
    071
    072                factoryClassName = (String) moduleList.get(0);
    073
    074                if (factoryClassName.equals(ViewProperties.DEFAULT_MODULE_TEXT)) {
    075                    log.trace("getFactory(): returning default TableView factory instance");
    076                    return new DefaultTableViewFactory();
    077                }
    078
    079                break;
    080
    081            case IMAGE:
    082                /* Retrieve the "currently selected" ImageViewFactory class to use */
    083                moduleList = ViewProperties.getImageViewList();
    084                if ((moduleList == null) || (moduleList.size() <= 0)) {
    085                    return null;
    086                }
    087
    088                factoryClassName = (String) moduleList.get(0);
    089
    090                if (factoryClassName.equals(ViewProperties.DEFAULT_MODULE_TEXT)) {
    091                    log.trace("getFactory(): returning default ImageView factory instance");
    092                    return new DefaultImageViewFactory();
    093                }
    094
    095                break;
    096
    097            case PALETTE:
    098                /* Retrieve the "currently selected" PaletteViewFactory class to use */
    099                moduleList = ViewProperties.getPaletteViewList();
    100                if ((moduleList == null) || (moduleList.size() <= 0)) {
    101                    return null;
    102                }
    103
    104                factoryClassName = (String) moduleList.get(0);
    105
    106                if (factoryClassName.equals(ViewProperties.DEFAULT_MODULE_TEXT)) {
    107                    log.trace("getFactory(): returning default PaletteView factory instance");
    108                    return new DefaultPaletteViewFactory();
    109                }
    110
    111                break;
    112
    113            case METADATA:
    114                /* Retrieve the "currently selected" MetaDataViewFactory class to use */
    115                moduleList = ViewProperties.getMetaDataViewList();
    116                if ((moduleList == null) || (moduleList.size() <= 0)) {
    117                    return null;
    118                }
    119
    120                factoryClassName = (String) moduleList.get(0);
    121
    122                if (factoryClassName.equals(ViewProperties.DEFAULT_MODULE_TEXT)) {
    123                    log.trace("getFactory(): returning default MetaDataView factory instance");
    124                    return new DefaultMetaDataViewFactory();
    125                }
    126
    127                break;
    128
    129            case TREEVIEW:
    130                /* Retrieve the "currently selected" TreeViewFactory class to use */
    131                moduleList = ViewProperties.getTreeViewList();
    132                if ((moduleList == null) || (moduleList.size() <= 0)) {
    133                    return null;
    134                }
    135
    136                factoryClassName = (String) moduleList.get(0);
    137
    138                if (factoryClassName.equals(ViewProperties.DEFAULT_MODULE_TEXT)) {
    139                    log.trace("getFactory(): returning default TreeView factory instance");
    140                    return new DefaultTreeViewFactory();
    141                }
    142
    143                break;
    144
    145            default:
    146                throw new Exception("getFactory(): invalid DataViewType");
    147        }
    148
    149        Class<?> theClass = null;
    150        try {
    151            log.trace("getFactory(): ViewProperties.loadExtClass().loadClass({})", factoryClassName);
    152
    153            /* Attempt to load the class as an external module */
    154            theClass = ViewProperties.loadExtClass().loadClass(factoryClassName);
    155        }
    156        catch (Exception ex) {
    157            log.debug("getFactory(): ViewProperties.loadExtClass().loadClass({}) failure:", factoryClassName, ex);
    158
    159            try {
    160                log.trace("getFactory(): Class.forName({})", factoryClassName);
    161
    162                /* Attempt to load the class directly by the given name */
    163                theClass = Class.forName(factoryClassName);
    164            }
    165            catch (Exception ex2) {
    166                log.debug("getFactory(): Class.forName({}) failure:", factoryClassName, ex);
    167
    168                /* At this point, we have no choice but to fall back to the default modules */
    169                switch (viewType) {
    170                    case TABLE:
    171                        log.trace("getFactory(): returning default TableView factory instance");
    172                        return new DefaultTableViewFactory();
    173                    case IMAGE:
    174                        log.trace("getFactory(): returning default ImageView factory instance");
    175                        return new DefaultImageViewFactory();
    176                    case PALETTE:
    177                        log.trace("getFactory(): returning default PaletteView factory instance");
    178                        return new DefaultPaletteViewFactory();
    179                    case METADATA:
    180                        log.trace("getFactory(): returning default MetaDataView factory instance");
    181                        return new DefaultMetaDataViewFactory();
    182                    case TREEVIEW:
    183                        log.trace("getFactory(): returning default TreeView factory instance");
    184                        return new DefaultTreeViewFactory();
    185                    default:
    186                        throw new Exception("getFactory(): invalid DataViewType");
    187                }
    188            }
    189        }
    190
    191        if (theClass == null) throw new ClassNotFoundException();
    192
    193        try {
    194            theFactory = (DataViewFactory) Tools.newInstance(theClass, null);
    195
    196            log.trace("getFactory(): returning DataViewFactory instance {}", theFactory);
    197        }
    198        catch (Exception ex) {
    199            log.debug("getFactory(): Error instantiating class:", ex);
    200            theFactory = null;
    201        }
    202
    203        return theFactory;
    204    }
    205}