001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2024
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas/
009 * 
010 * All Rights Reserved
011 * 
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.  
014 * 
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 * 
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023 * GNU Lesser Public License for more details.
024 * 
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program.  If not, see https://www.gnu.org/licenses/.
027 */
028
029package edu.wisc.ssec.mcidasv.data;
030
031import java.awt.Dimension;
032import java.awt.Font;
033import java.io.File;
034import java.io.IOException;
035import java.io.StringWriter;
036import java.rmi.RemoteException;
037import java.util.ArrayList;
038import java.util.Hashtable;
039import java.util.List;
040
041import javax.swing.JScrollPane;
042import javax.swing.JTabbedPane;
043import javax.swing.JTextArea;
044
045import ucar.unidata.data.DataCategory;
046import ucar.unidata.data.DataChoice;
047import ucar.unidata.data.DataSelection;
048import ucar.unidata.data.DataSourceDescriptor;
049import ucar.unidata.data.DataSourceImpl;
050import ucar.unidata.ui.TextSearcher;
051import ucar.unidata.util.GuiUtils;
052import ucar.unidata.util.WrapperException;
053import visad.Data;
054import visad.VisADException;
055
056public class HydraDataSource extends DataSourceImpl  {
057
058    /** List of sources files */
059    protected List sources = new ArrayList();
060
061    public static String request;
062
063    /** List of sources files */
064    protected List adapters;
065
066    /** for unpersistence */
067    protected String oldSourceFromBundles;
068
069    /**
070     * Default constructor
071     */
072    public HydraDataSource() {}
073
074    /**
075     * Create a HydraDataSource
076     *
077     * @param descriptor The datasource descriptor
078     * @param newSources List of files or urls
079     * @param description The long name
080     * @param properties properties
081     *
082     * @throws VisADException  couldn't create the data
083     */
084    public HydraDataSource(DataSourceDescriptor descriptor, List newSources,
085                           String description, Hashtable properties) 
086            throws VisADException {
087
088        super(descriptor, "Hydra", "Hydra", properties);
089/*
090        System.out.println("HydraDataSource:");
091        System.out.println("    descriptor=" + descriptor);
092        System.out.println("    sources=" + newSources);
093        System.out.println("    description=" + description);
094        System.out.println("    properties=" + properties);
095*/
096        if (newSources != null)
097            sources.addAll(newSources);
098    }
099
100    /**
101     * Can this data source save its dat to local disk
102     *
103     * @return can save to local disk
104     */
105    public boolean canSaveDataToLocalDisk() {
106        return !isFileBased() && (getProperty(PROP_SERVICE_HTTP) != null);
107    }
108
109    /**
110     * Are we getting data from a file or from server
111     * 
112     * @return is the data from files
113     */
114    protected boolean isFileBased() {
115        if (sources.isEmpty())
116            return false;
117
118        return (new File(sources.get(0).toString())).exists();
119    }
120
121    /**
122     * This is called when the CacheManager detects the need ot clear memory.
123     * It is intended to be overwritten by derived classes that are holding cached
124     * data that is not in the normal putCache facilities provided by this class
125     * since that data is actually managed by the CacheManager
126     */
127    public void clearCachedData() {
128        super.clearCachedData();
129    }
130
131    /**
132     * Create, if needed, and return the list of adapters.
133     * Will return null if there are no valid adapters.
134     *
135     * @return List of adapters or null
136     */
137    protected List getAdapters() {
138        if ((adapters == null) || (adapters.size() == 0)) {
139            try {
140                makeAdapters(sources);
141            } catch (Exception exc) {
142                setInError(true);
143                throw new WrapperException(exc);
144            }
145        }
146        if (adapters.size() == 0) {
147            adapters = null;
148        }
149        return adapters;
150    }
151
152    /**
153     * Make the adapters for the given list of files
154     *
155     * @param files Data files
156     *
157     * @throws Exception When bad things happen
158     */
159    private void makeAdapters(List files) throws Exception {
160        adapters = new ArrayList();
161    }
162
163    /**
164     * Create the list of times associated with this DataSource.
165     * @return list of times.
166     */
167    protected List doMakeDateTimes() {
168        List times = new ArrayList();
169        return times;
170    }
171
172/*
173    public boolean canDoGeoSelection() {
174       return true;
175    }
176*/
177
178    /**
179     * Get the data for the given DataChoice and selection criteria.
180     * @param dataChoice         DataChoice for selection
181     * @param category           DataCategory for the DataChoice (not used)
182     * @param subset             subsetting criteria
183     * @param requestProperties  extra request properties
184     * @return  the Data object for the request
185     *
186     * @throws RemoteException couldn't create a remote data object
187     * @throws VisADException  couldn't create the data
188     */
189    protected Data getDataInner(DataChoice dataChoice, DataCategory category,
190                                DataSelection subset,
191                                Hashtable requestProperties)
192            throws VisADException, RemoteException {
193        return null;
194    }
195    
196    @Override public void addPropertiesTabs(JTabbedPane tabbedPane) {
197        super.addPropertiesTabs(tabbedPane);
198        if (sources == null) {
199            return;
200        }
201        
202        int height = 300;
203        int width  = 400;
204        
205        Dimension windowSize = new Dimension(width, height);
206        
207        JTextArea dumpText = new JTextArea();
208        dumpText.setEditable(false);
209    
210        TextSearcher searcher = new TextSearcher(dumpText);
211        dumpText.setFont(Font.decode("monospaced"));
212        
213        StringWriter bos = new StringWriter();
214        try {
215            for (Object source : sources) {
216                ucar.nc2.NCdumpW.print(source.toString(), bos, null);
217                bos.write("\n");
218            }
219        } catch (IOException ioe) {
220            logException("Dumping netcdf file", ioe);
221        }
222        dumpText.setText(bos.toString());
223        JScrollPane scroller = GuiUtils.makeScrollPane(dumpText, width, height);
224        scroller.setPreferredSize(windowSize);
225        scroller.setMinimumSize(windowSize);
226        tabbedPane.add("Metadata",
227            GuiUtils.inset(GuiUtils.centerBottom(scroller,
228                searcher), 5));
229    }
230}