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}