/*
* Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
*
* Portions of this software were developed by the Unidata Program at the
* University Corporation for Atmospheric Research.
*
* Access and use of this software shall impose the following obligations
* and understandings on the user. The user is granted the right, without
* any fee or cost, to use, copy, modify, alter, enhance and distribute
* this software, and any derivative works thereof, and its supporting
* documentation for any purpose whatsoever, provided that this entire
* notice appears in all copies of the software, derivative works and
* supporting documentation. Further, UCAR requests that the user credit
* UCAR/Unidata in any publications that result from the use of this
* software or in any product that includes this software. The names UCAR
* and/or Unidata, however, may not be used in any advertising or publicity
* to endorse or promote any products or commercial entity unless specific
* written permission is obtained from UCAR/Unidata. The user also
* understands that UCAR/Unidata is not obligated to provide the user with
* any support, consulting, training or assistance of any kind with regard
* to the use, operation and performance of this software nor to provide
* the user with any updates, revisions, new versions or "bug fixes."
*
* THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* User: rkambic
* Date: Nov 11, 2010
* Time: 3:55:40 PM
*/
package thredds.server.radarServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import thredds.catalog.query.Station;
import thredds.server.config.TdsContext;
import thredds.util.TdsPathUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller
public class StationRadarServerController extends AbstractController {
private org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(getClass());
// private static final String CREATE_VIEW = "forward:createstation.htm"; // The view to forward to in case an dataset needs to be created.
private static final String MODEL_KEY = "message"; // The model key used to retrieve the message from the model.
private static final String MSG_CODE = "message.create.station"; // The unique key for retrieving the text associated with this message.
@Autowired
private TdsContext tdsContext;
public StationRadarServerController() {
}
protected String getControllerPath() {
return "/radarServer/";
}
// @RequestMapping(value = {"/radarServer/**/stations.xml"}, method = {RequestMethod.GET, RequestMethod.HEAD})
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
DatasetRepository.init(tdsContext);
try {
// Gather diagnostics for logging request.
// setup
String path = TdsPathUtils.extractPath(request, getControllerPath());
if (path == null) path = "";
int pos = path.indexOf("/");
String type = (pos > 0) ? path.substring(0, pos) : "";
DatasetRepository.RadarType radarType;
try {
radarType = DatasetRepository.RadarType.valueOf(type);
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Bad radar type=" + type);
return null;
}
// return stations of dataset
Map<String, Object> model = new HashMap<>();
stationsXML(radarType, path, model);
if (model.size() == 0) {
return null;
//ModelAndView mav = new ModelAndView(CREATE_VIEW);
// mav.addObject(MODEL_KEY, MSG_CODE);
//return mav;
} else {
return new ModelAndView("stationXml", model);
}
} catch (RadarServerException e) {
throw e; // pass it onto Spring exceptionResolver
} catch (Throwable e) {
log.error("handleRequestInternal(): Problem handling request.", e);
throw new RadarServerException("handleRequestInternal(): Problem handling request.", e);
}
}
/*
* Create an ArrayList of station entries in model for radarType and path
*/
private void stationsXML(DatasetRepository.RadarType radarType, String path, Map<String, Object> model)
throws Exception {
// stations in this dataset, set by path
String[] stations = stationsDS(radarType, DatasetRepository.dataLocation.get(path));
if (path.contains("level3") && stations[0].length() == 4) {
for (int i = 0; i < stations.length; i++)
stations[i] = stations[i].substring(1);
}
makeStationDocument(stations, radarType, model);
}
/*
* Find the stations for this dataset in path directory
*/
private String[] stationsDS(DatasetRepository.RadarType radarType, String path) throws Exception {
String[] stations = null;
// Scan directory looking for actual stations
if (path != null) {
File dir = new File(path);
stations = dir.list();
// check for level3 stations
if (path.contains("level3")) {
dir = null;
if (radarType.equals(DatasetRepository.RadarType.nexrad)) {
for (String var : stations) {
if (var.equals("N0R")) {
dir = new File(path + "/N0R");
break;
}
}
} else if (radarType.equals(DatasetRepository.RadarType.terminal)) {
for (String var : stations) {
if (var.equals("TR0")) {
dir = new File(path + "/TR0");
break;
}
}
}
if (dir != null) {
stations = dir.list();
} else {
stations = null;
}
}
}
if (stations != null) {
// rescan stations array for removal of . files
ArrayList<String> tmp = new ArrayList<String>();
for (String station : stations) {
if (station.startsWith("."))
continue;
tmp.add(station);
}
if (stations.length != tmp.size()) {
stations = new String[tmp.size()];
stations = (String[]) tmp.toArray(stations);
}
}
// no stations found return all known stations for RadarType
if (stations == null || stations.length == 0) {
if (stations == null)
stations = new String[1];
if (radarType.equals(DatasetRepository.RadarType.nexrad))
stations = DatasetRepository.nexradMap.keySet().toArray(stations);
else
stations = DatasetRepository.terminalMap.keySet().toArray(stations);
}
return stations;
}
/**
* Create StationEntry objects in entries ArrayList
*
* @param stations
*/
private void makeStationDocument(String[] stations, DatasetRepository.RadarType radarType, Map<String, Object> model)
throws Exception {
/*
<station id="KTYX" state="NY" country="US">
<name>MONTAGUE/Fort_Drum</name>
<longitude>-75.76</longitude>
<latitude>43.76</latitude>
<elevation>562.0</elevation>
</station>
*/
List<StationEntry> entries = new ArrayList<StationEntry>();
for (String s : stations) {
Station stn = getStation(s, radarType);
StationEntry se = new StationEntry();
if (stn == null) { // stn not in table
se.setId(s);
se.setState("XXX");
se.setCountry("XX");
se.setName("Unknown");
se.setLongitude("0.0");
se.setLatitude("0.0");
se.setElevation("0.0");
continue;
}
// id
se.setId(s);
if (stn.getState() != null) {
se.setState(stn.getState());
}
if (stn.getCountry() != null) {
se.setCountry(stn.getCountry());
}
if (stn.getName() != null) {
se.setName(stn.getName());
}
se.setLongitude(ucar.unidata.util.Format.d(stn.getLocation().getLongitude(), 6));
se.setLatitude(ucar.unidata.util.Format.d(stn.getLocation().getLatitude(), 6));
if (!Double.isNaN(stn.getLocation().getElevation())) {
se.setElevation(ucar.unidata.util.Format.d(stn.getLocation().getElevation(), 6));
}
entries.add(se);
}
model.put("stations", entries);
}
/**
* returns station or null
*
* @param station
* @param radarType
* @return station
*/
public Station getStation(String station, DatasetRepository.RadarType radarType) {
Station stn = null;
if (station.length() == 3 && radarType.equals(DatasetRepository.RadarType.terminal)) { // terminal level3 station
stn = DatasetRepository.terminalMap.get("T" + station);
} else if (station.length() == 3) {
for (Station stn3 : DatasetRepository.nexradList) {
if (stn3.getValue().endsWith(station)) {
stn = stn3;
break;
}
}
} else if (radarType.equals(DatasetRepository.RadarType.terminal)) {
stn = DatasetRepository.terminalMap.get(station);
} else {
stn = DatasetRepository.nexradMap.get(station);
}
return stn;
}
/*
StationEntry provides the necessary information for a station entry below.
<station id="KTYX" state="NY" country="US">
<name>MONTAGUE/Fort_Drum</name>
<longitude>-75.76</longitude>
<latitude>43.76</latitude>
<elevation>562.0</elevation>
</station>
*/
public static class StationEntry {
private String id;
private String state;
private String country;
private String name;
private String longitude;
private String latitude;
private String elevation;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
public String getLatitude() {
return latitude;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
public String getElevation() {
return elevation;
}
public void setElevation(String elevation) {
this.elevation = elevation;
}
}
}