// check that parms have valid stations, vars and times private Boolean checkQueryParms( DatasetRepository.RadarType radarType, QueryParams qp, Boolean level2) throws IOException { if (qp.hasBB) { if (radarType.equals(DatasetRepository.RadarType.nexrad)) qp.stns = RadarServerUtil.getStationNames(qp.getBB(), DatasetRepository.nexradList); else qp.stns = RadarServerUtil.getStationNames(qp.getBB(), DatasetRepository.terminalList); if (qp.stns.size() == 0) { qp.errs.append("Bounding Box contains no stations "); return false; } if (!level2) qp.stns = RadarServerUtil.convert4to3stations(qp.stns); } if (qp.hasStns) { if (RadarServerUtil.isStationListEmpty(qp.stns, radarType)) { qp.errs.append("No valid stations specified, need 1 "); return false; } else if (level2) { for (String stn : qp.stns) { if (stn.length() == 3) { qp.errs.append("Need 4 character station names "); return false; } } } else if (!level2) qp.stns = RadarServerUtil.convert4to3stations(qp.stns); } if (qp.hasLatlonPoint) { qp.stns = new ArrayList<String>(); if (radarType.equals(DatasetRepository.RadarType.nexrad)) qp.stns.add( RadarServerUtil.findClosestStation(qp.lat, qp.lon, DatasetRepository.nexradList)); else qp.stns.add( RadarServerUtil.findClosestStation(qp.lat, qp.lon, DatasetRepository.terminalList)); if (!level2) qp.stns = RadarServerUtil.convert4to3stations(qp.stns); } else if (qp.fatal) { qp.errs.append("No valid stations specified 2 "); return false; } if (qp.stns == null || qp.stns.size() == 0) { qp.errs.append("No valid stations specified, need 1 "); return false; } boolean useAllStations = (qp.stns.get(0).toUpperCase().equals("ALL")); if (useAllStations) { if (radarType.equals(DatasetRepository.RadarType.nexrad)) qp.stns = RadarServerUtil.getStationNames(DatasetRepository.nexradList); // need station names else qp.stns = RadarServerUtil.getStationNames(DatasetRepository.terminalList); // need station names if (!level2) qp.stns = RadarServerUtil.convert4to3stations(qp.stns); } if (qp.hasTimePoint) { if (qp.time.isPresent()) { try { qp.time_end = new DateType("present", null, null); qp.time_start = epicDateType; } catch (java.text.ParseException e) { qp.errs.append("Illegal param= 'time' must be valid ISO Duration"); return false; } } else { qp.time_end = qp.time; qp.time_start = qp.time; } } else if (qp.hasDateRange) { DateRange dr = qp.getCalendarDateRange().toDateRange(); qp.time_start = dr.getStart(); qp.time_end = dr.getEnd(); } else { // get all times qp.time_latest = 1; // qp.hasDateRange = true; try { qp.time = new DateType("present", null, null); qp.time_end = new DateType("present", null, null); qp.time_start = epicDateType; } catch (java.text.ParseException e) { qp.errs.append("Illegal param= 'time' must be valid ISO Duration "); return false; } } if (level2) { qp.vars = null; // level2 can't select vars } else if (qp.vars == null) { // level 3 with no vars qp.errs.append("No vars selected "); return false; } else if (qp.vars.get(0).contains("/")) { // remove desc from vars ArrayList<String> tmp = new ArrayList<String>(); for (String var : qp.vars) { tmp.add(var.replaceFirst("/.*", "")); } qp.vars = tmp; } return true; }
// create catalog Header private Boolean createHeader( DatasetRepository.RadarType radarType, QueryParams qp, String pathInfo, Map<String, Object> model) throws IOException { Boolean level2 = pathInfo.contains("level2"); int level = (level2) ? 2 : 3; StringBuffer str = new StringBuffer(); str.append("Radar Level").append(level).append(" datasets in near real time"); model.put("name", str.toString()); str.setLength(0); str.append("/thredds/dodsC/").append(pathInfo).append("/"); model.put("base", str.toString()); str.setLength(0); str.append("RadarLevel").append(level).append(" datasets for available stations and times"); model.put("dname", str.toString()); str.setLength(0); str.append("accept=").append(qp.acceptType).append("&"); if (!level2 && qp.vars != null) { // add vars str.append("var="); for (int i = 0; i < qp.vars.size(); i++) { str.append(qp.vars.get(i)); if (i < qp.vars.size() - 1) { str.append(","); } } str.append("&"); } // use all stations if (qp.stns.get(0).toUpperCase().equals("ALL")) { str.append("stn=ALL&"); } else if (qp.hasStns) { for (String station : qp.stns) { str.append("stn=").append(station).append("&"); } } else if (qp.hasBB) { str.append("south=").append(qp.south).append("&north=").append(qp.north).append("&"); str.append("west=").append(qp.west).append("&east=").append(qp.east).append("&"); } // no time given if (qp.time_latest == 1) { // str.deleteCharAt( str.length() -1); str.append("time=present"); } else if (qp.hasDateRange) { if (qp.time_start.getDate() == null || qp.time_start.isBlank() || qp.time_end.getDate() == null || qp.time_end.isBlank()) { str.append("time_start=").append(qp.time_start.toString()); str.append("&time_end=").append(qp.time_end.toString()); qp.errs.append("need ISO time format "); return false; } else { str.append("time_start=").append(qp.time_start.toDateTimeStringISO()); str.append("&time_end=").append(qp.time_end.toDateTimeStringISO()); } } else if (qp.time.isPresent()) { str.append("time=present"); } else if (qp.hasTimePoint) { if (qp.time.getDate() == null || qp.time.isBlank()) { str.append("time=").append(qp.time.toString()); qp.errs.append("need ISO time format "); return false; } else { str.append("time=").append(qp.time.toDateTimeStringISO()); } } model.put("ID", str.toString()); if (level2) { model.put("type", "NEXRAD2"); } else if (radarType.equals(DatasetRepository.RadarType.nexrad)) { model.put("type", "NIDS"); } else { model.put("type", "TDWR"); } // at this point must have stations if (RadarServerUtil.isStationListEmpty(qp.stns, radarType)) { qp.errs.append("No station(s) meet query criteria "); return false; } return true; }
// get/check/process query public void radarQuery(HttpServletRequest req, HttpServletResponse res, Map<String, Object> model) throws ServletException, IOException, RadarServerException { // long startms = System.currentTimeMillis(); // long endms; DatasetRepository.RadarType radarType = DatasetRepository.RadarType.nexrad; // need to extract data according to the (dataset) given String pathInfo = req.getPathInfo(); if (pathInfo == null) pathInfo = ""; if (pathInfo.startsWith("/")) pathInfo = pathInfo.substring(1); try { String rt = pathInfo.substring(0, pathInfo.indexOf('/', 1)); radarType = DatasetRepository.RadarType.valueOf(rt); } catch (Exception e) { log.info("Invalid dataset url reference " + pathInfo); throw new RadarServerException("Invalid dataset url reference " + pathInfo); } Boolean level2 = pathInfo.contains("level2"); // parse the input QueryParams qp = new QueryParams(); if (!qp.parseQuery( req, res, new String[] {QueryParams.XML, QueryParams.HTML, QueryParams.RAW, QueryParams.NETCDF})) { // log.error( "parseQuery Failed "+ qp.errs.toString() + req.getQueryString() ); // throw new RadarServerException( qp.errs.toString() );//+ req.getQueryString() ); return; // TODO: uncomment above 2 lines when QueryParams exception is fixed } // endms = System.currentTimeMillis(); // System.out.println( "after QueryParams "+ (endms - startms)); // startms = System.currentTimeMillis(); // check Query Params if (!checkQueryParms(radarType, qp, level2)) { log.error("checkQueryParms Failed " + qp.errs.toString() + req.getQueryString()); throw new RadarServerException(qp.errs.toString()); // + req.getQueryString() ); } // endms = System.currentTimeMillis(); // System.out.println( "after checkQueryParms "+ (endms - startms)); // startms = System.currentTimeMillis(); // check type of output wanted XML html qp.acceptType = qp.acceptType.replaceFirst(".*/", ""); // creates first part of catalog if (!createHeader(radarType, qp, pathInfo, model)) { log.error("Write Header Failed " + qp.errs.toString() + req.getQueryString()); throw new RadarServerException(qp.errs.toString()); // req.getQueryString() ); } // endms = System.currentTimeMillis(); // System.out.println( "after writeHeader "+ (endms - startms)); // startms = System.currentTimeMillis(); // gets products according to stations, time, and variables boolean dataFound = false; List<DatasetEntry> entries = new ArrayList<DatasetEntry>(); if (qp.vars == null) { dataFound = processQuery(pathInfo, qp, null, entries); if (releaseDataset) DatasetRepository.removeRadarDatasetCollection(pathInfo, null); } else { int count = 0; for (String var : qp.vars) { dataFound = processQuery(pathInfo, qp, var, entries); if (dataFound) count++; if (releaseDataset) DatasetRepository.removeRadarDatasetCollection(pathInfo, var); } if (count > 0) dataFound = true; } // save entries model.put("datasets", entries); if (dataFound) { model.put("documentation", Integer.toString(entries.size()) + " datasets found for query"); } else if (qp.errs.length() > 0) { model.put("documentation", qp.errs.toString()); } else { model.put("documentation", "No data available for station(s) and time range"); } // endms = System.currentTimeMillis(); // System.out.println( "after radarQuery "+ (endms - startms)); // startms = System.currentTimeMillis(); } // end radarNexradQuery