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.io.File;
032
033import java.util.ArrayList;
034import java.util.Hashtable;
035import java.util.List;
036
037/**
038 * {@literal "Base"} class that represents several different types of header
039 * files.
040 */
041public class HeaderInfo {
042
043    // Enumerate some constants
044    public static final int kFormatUnknown = -1;
045    public static final int kFormatASCII = 0;
046    public static final int kFormat1ByteUInt = 1;
047    public static final int kFormat2ByteSInt = 2;
048    public static final int kFormat4ByteSInt = 3;
049    public static final int kFormat4ByteFloat = 4;
050    public static final int kFormat8ByteDouble = 5;
051    public static final int kFormat2x8Byte = 9;
052    public static final int kFormat2ByteUInt = 12;
053    public static final int kFormatImage = 8080;
054
055    public static final int kNavigationUnknown = -1;
056    public static final int kNavigationBounds = 1;
057    public static final int kNavigationFiles = 2;
058
059    public static final String kInterleaveSequential = "BSQ";
060    public static final String kInterleaveByLine = "BIL";
061    public static final String kInterleaveByPixel = "BIP";
062
063    public static final String DESCRIPTION = "description";
064    public static final String ELEMENTS = "elements";
065    public static final String LINES = "lines";
066    public static final String UNIT = "unit";
067    public static final String OFFSET = "offset";
068    public static final String DATATYPE = "dataType";
069    public static final String MISSINGVALUE = "missingValue";
070    public static final String BANDNAMES = "bandNames";
071    public static final String BANDFILES = "bandFiles";
072    public static final String INTERLEAVE = "interleave";
073    public static final String BYTEORDER = "byteOrder";
074    public static final String BIGENDIAN = "bigEndian";
075    public static final String NAVBOUNDS = "navBounds";
076    public static final String NAVFILES = "navFiles";
077
078    /** Path to header file. */
079    private String headerFile = "";
080    
081    /** Map containing relevant parameters and values in {@code headerFile}. */
082    private Hashtable parameters = new Hashtable();
083
084    /**
085     * Ctor for xml encoding
086     */
087    public HeaderInfo() {}
088
089    /**
090     * CTOR
091     *
092     * @param thisFile File to use. Cannot be {@code null}.
093     */
094    public HeaderInfo(File thisFile) {
095        this(thisFile.getAbsolutePath());
096    }
097
098    /**
099     * CTOR
100     *
101     * @param filename File containing header information.
102     */
103    public HeaderInfo(String filename) {
104        setFilename(filename);
105    }
106
107    /**
108     * Set the file name to be used.
109     *
110     * @param filename File containing header information.
111     */
112    public void setFilename(String filename) {
113        parameters = new Hashtable();
114        headerFile = filename;
115    }
116
117    /**
118     * Get the file being used.
119     * 
120     * @return File in use.
121     */
122    public String getFilename() {
123        return headerFile;
124    }
125
126    /**
127     * Get the current header's band count.
128     * 
129     * @return Number of bands.
130     */
131    public int getBandCount() {
132        if (!haveParsed()) {
133            parseHeader();
134        }
135        List bandNames = getParameter(BANDNAMES, new ArrayList());
136        return bandNames.size();
137    }
138
139    /**
140     * Return {@code String} value associated with {@code parameter}.
141     * 
142     * @param parameter Parameter name.
143     * @param defaultValue Value to return if {@code parameter} does not exist.
144     *
145     * @return Either the {@code List} associated with {@code parameter}, or 
146     *         {@code defaultValue}.
147     */
148    public String getParameter(String parameter, String defaultValue) {
149        parseHeader();
150        Object hashedValue = parameters.get(parameter);
151        if (hashedValue == null || !(hashedValue instanceof String)) {
152            return defaultValue;
153        }
154        return (String)hashedValue;
155    }
156
157    /**
158     * Return {@code Integer} value associated with {@code parameter}.
159     *
160     * @param parameter Parameter name.
161     * @param defaultValue Value to return if {@code parameter} does not exist.
162     *
163     * @return Either the {@code Integer} associated with {@code parameter}, or 
164     *         {@code defaultValue}.
165     */
166    public Integer getParameter(String parameter, Integer defaultValue) {
167        parseHeader();
168        Object hashedValue = parameters.get(parameter);
169        if (hashedValue == null || !(hashedValue instanceof Integer)) {
170            return defaultValue;
171        }
172        return (Integer)hashedValue;
173    }
174
175    /**
176     * Return {@code Float} value associated with {@code parameter}.
177     *
178     * @param parameter Parameter name.
179     * @param defaultValue Value to return if {@code parameter} does not exist.
180     *
181     * @return Either the {@code Float} associated with {@code parameter}, or 
182     *         {@code defaultValue}.
183     */
184    public Float getParameter(String parameter, Float defaultValue) {
185        parseHeader();
186        Object hashedValue = parameters.get(parameter);
187        if (hashedValue == null || !(hashedValue instanceof Float)) {
188            return defaultValue;
189        }
190        return (Float)hashedValue;
191    }
192
193    /**
194     * Return {@code Boolean} value associated with {@code parameter}.
195     *
196     * @param parameter Parameter name.
197     * @param defaultValue Value to return if {@code parameter} does not exist.
198     *
199     * @return Either the {@code Boolean} associated with {@code parameter}, or 
200     *         {@code defaultValue}.
201     */
202    public Boolean getParameter(String parameter, Boolean defaultValue) {
203        parseHeader();
204        Object hashedValue = parameters.get(parameter);
205        if (hashedValue == null || !(hashedValue instanceof Boolean)) {
206            return defaultValue;
207        }
208        return (Boolean)hashedValue;
209    }
210
211    /**
212     * Return {@code List} associated with {@code parameter}.
213     * 
214     * @param parameter Parameter name.
215     * @param defaultValue Value to return if {@code parameter} does not exist.
216     * 
217     * @return Either the {@code List} associated with {@code parameter}, or 
218     *         {@code defaultValue}.
219     */
220    public List getParameter(String parameter, List defaultValue) {
221        parseHeader();
222        Object hashedValue = parameters.get(parameter);
223        if (hashedValue == null || !(hashedValue instanceof List)) {
224            return defaultValue;
225        }
226        return (List)hashedValue;
227    }
228
229    /**
230     * Set a parsed parameter value.
231     * 
232     * @param parameter Parameter name.
233     * @param value Value associated with {@code parameter}.
234     */
235    public void setParameter(String parameter, Object value) {
236        parameters.put(parameter, value);
237    }
238
239    /**
240     * Have we already parsed once?
241     * 
242     * @return {@code true} if {@link #parameters} has at least entry.
243     */
244    public boolean haveParsed() {
245        return parameters.size() > 0;
246    }
247
248    /**
249     * Does the file we are pointing to even exist?
250     * 
251     * @return Whether or not {@link #headerFile} exists.
252     */
253    public boolean doesExist() {
254        File checkFile = new File(headerFile);
255        return checkFile.exists();
256    }
257
258    /**
259     * Override this when extending for a specific header type
260     */
261    protected void parseHeader() {}
262}