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