// // DataSetInfo.java // /* This source file is part of the edu.wisc.ssec.mcidas package and is Copyright (C) 1998 - 2017 by Tom Whittaker, Tommy Jasmin, Tom Rink, Don Murray, James Kelly, Bill Hibbard, Dave Glowacki, Curtis Rueden and others. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ package edu.wisc.ssec.mcidas.adde; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; /** * DataSetInfo interface for McIDAS ADDE data sets. Simulates a * McIDAS DSINFO request using an ADDE URL. * * <pre> * URLs must all have the following format * adde://host/datasetinfo?keyword_1=value_1&keyword_2=value_2 * * there can be any valid combination of the following supported keywords: * * group - ADDE group name * type - ADDE data type. Must be one of the following: * image, point, grid, text, nav * the default is the image type. * * the following keywords are required: * * group * * an example URL might look like: * adde://viper/datasetinfo?group=gvar&type=image * </pre> * * @author Don Murray * */ public class DataSetInfo { // load protocol for ADDE URLs // See java.net.URL for explanation of URL handling static { try { String handlers = System.getProperty("java.protocol.handler.pkgs"); String newProperty = null; if (handlers == null) newProperty = "edu.wisc.ssec.mcidas"; else if (handlers.indexOf("edu.wisc.ssec.mcidas") < 0) newProperty = "edu.wisc.ssec.mcidas | " + handlers; if (newProperty != null) // was set above System.setProperty("java.protocol.handler.pkgs", newProperty); } catch (Exception e) { System.out.println( "Unable to set System Property: java.protocol.handler.pkgs"); } } private int status=0; // read status private char[] data; // data returned from server private Hashtable descriptorTable; private boolean debug = false; // debug /** Descriptors returned from server. */ private List<String> descriptorList; /** Comments returned from server. */ private List<String> commentList; /** * creates a DataSetInfo object that allows reading * * @param request ADDE URL to read from. See class javadoc. * * <pre> * an example URL might look like: * adde://viper/datasetinfo?group=gvar&type=image * </pre> * * @exception AddeURLException if there are no datasets of the particular * type or there is an error reading data * */ public DataSetInfo(String request) throws AddeURLException { URLConnection urlc; BufferedReader reader; debug = debug || request.indexOf("debug=true") >= 0; try { URL url = new URL(request); urlc = url.openConnection(); reader = new BufferedReader( new InputStreamReader( urlc.getInputStream())); } catch (AddeURLException ae) { status = -1; throw new AddeURLException("No datasets found", ae); } catch (Exception e) { status = -1; throw new AddeURLException("Error opening connection", e); } int numBytes = ((AddeURLConnection) urlc).getInitialRecordSize(); if (debug) System.out.println("DataSetInfo: numBytes = " + numBytes); if (numBytes == 0) { status = -1; throw new AddeURLException("No datasets found"); } else { data = new char[numBytes]; try { int start = 0; while (start < numBytes) { int numRead = reader.read(data, start, (numBytes - start)); if (debug) System.out.println("bytes read = " + numRead); start += numRead; } } catch (IOException e) { status = -1; throw new AddeURLException("Error reading dataset info", e); } int numNames = data.length/80; descriptorTable = new Hashtable(numNames); descriptorList = new ArrayList<String>(numNames); commentList = new ArrayList<String>(numNames); if (debug) System.out.println("Number of descriptors = " + numNames); for (int i = 0; i < numNames; i++) { String temp = new String(data, i*80, 80); if (debug) System.out.println("Parsing: >"+temp+"<"); if (temp.trim().isEmpty()) continue; String descriptor = temp.substring(0,12).trim(); if (debug) System.out.println("Descriptor = " + descriptor); String comment = descriptor; int pos = temp.indexOf('"'); if (debug) System.out.println("Found quote at " + pos); if (pos >= 23) { comment = temp.substring(pos + 1).trim(); if (comment.isEmpty()) comment = descriptor; } if (debug) System.out.println("Comment = " + comment); descriptorTable.put(comment, descriptor); descriptorList.add(descriptor); commentList.add(comment); } } } /** * Returns the list of descriptors. * * @return Either an ArrayList or {@code null}. Note that if an * {@code ArrayList} is returned, it should have the same number of * elements as the results of {@link #getCommentList()}. */ public List<String> getDescriptorList() { return descriptorList; } /** * Returns the list of descriptor contents. * * @return Either an {@link ArrayList} or {@code null}. Note that if an * {@code ArrayList} is returned, it should have the same number of * elements as the results of {@link #getDescriptorList()}. */ public List<String> getCommentList() { return commentList; } /** * Return the data sent by the server * * @return array of the data. Data is in the format of a McIDAS DSINFO * (LWPR) request. * * @exception AddeURLException if there was an error reading data */ public char[] getData() throws AddeURLException { if (status < 0) throw new AddeURLException("No data available"); return data; } /** * Return a hashtable of descriptive names and ADDE dataset descriptors * Descriptive names are the keys. If there is no descriptive name, * the dataset descriptor is used. * * @return hashtable of names/desciptors * * @exception AddeURLException if there was an error reading data */ public Hashtable getDescriptionTable() throws AddeURLException { if (status < 0) throw new AddeURLException("No data available"); return descriptorTable; } /** * Return a sorted list of the dataset descriptors * * @return sorted list * * @exception AddeURLException if there was an error reading data */ public String[] getDescriptors() throws AddeURLException { if (status < 0) throw new AddeURLException("No data available"); String[] list = new String[descriptorTable.size()]; Enumeration elements = descriptorTable.elements(); int i = 0; while (elements.hasMoreElements()) { list[i] = (String) elements.nextElement(); i++; } Arrays.sort(list); return list; } /** * Return a formated string of the returned data * * @return formatted string representing the data. */ public String toString() { if (status < 0) return new String("No data Available"); String header = new String( "Name NumPos Content\n" + "------------ ------ --------------------------------------\n"); StringBuffer buf = new StringBuffer(header); for (int i = 0; i < data.length/80; i++) { StringBuffer sb = new StringBuffer(" "); String line = new String(data, i*80, 80); sb.insert(0,line.substring(0,12)); int brange = 0; int erange = 0; try { brange = Integer.parseInt(line.substring(12,18).trim()); } catch (NumberFormatException ne) { brange = 0; } try { erange = Integer.parseInt(line.substring(18,23).trim()); } catch (NumberFormatException ne) { erange = 0; } if (erange == 0) erange = brange; int numPos = (erange-brange) + 1; int insertPos = 17; if (numPos >= 10 && numPos < 100) insertPos = 16; else if (numPos >= 100 && numPos < 1000) insertPos = 15; else if (numPos > 1000) insertPos = 14; sb.insert(insertPos,String.valueOf(numPos)); int pos = line.indexOf('"'); if (pos >= 23) sb.insert(22, line.substring(pos+1)); buf.append(sb.toString().trim()); buf.append("\n"); } return buf.toString(); } /** test by running 'java edu.wisc.ssec.mcidas.adde.DataSetInfo' */ public static void main (String[] args) throws Exception { System.out.println("\nDataset Names:\n"); String request = (args.length == 0) ? "adde://adde.unidata.ucar.edu/datasetinfo?group=blizzard&type=image" : args[0]; DataSetInfo dsinfo = new DataSetInfo(request); System.out.println(dsinfo.toString()); String[] descriptors = dsinfo.getDescriptors(); System.out.println("Sorted list of Descriptors:"); for (int i = 0; i < descriptors.length; i++) System.out.println(descriptors[i]); } }