Initial Commit
This commit is contained in:
7
.classpath
Normal file
7
.classpath
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||||
|
<classpathentry kind="src" path="/VisualForecast 1000"/>
|
||||||
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
</classpath>
|
||||||
26
.gitignore
vendored
Normal file
26
.gitignore
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Compiled class file
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# BlueJ files
|
||||||
|
*.ctxt
|
||||||
|
|
||||||
|
# Mobile Tools for Java (J2ME)
|
||||||
|
.mtj.tmp/
|
||||||
|
|
||||||
|
#Compiled binary directory
|
||||||
|
bin/
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.war
|
||||||
|
*.nar
|
||||||
|
*.ear
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
*.dat
|
||||||
13
.gitlab-ci.yml
Normal file
13
.gitlab-ci.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# You can override the included template(s) by including variable overrides
|
||||||
|
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
|
||||||
|
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
|
||||||
|
# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings
|
||||||
|
# Container Scanning customization: https://docs.gitlab.com/ee/user/application_security/container_scanning/#customizing-the-container-scanning-settings
|
||||||
|
# Note that environment variables can be set in several places
|
||||||
|
# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
|
||||||
|
stages:
|
||||||
|
- test
|
||||||
|
sast:
|
||||||
|
stage: test
|
||||||
|
include:
|
||||||
|
- template: Security/SAST.gitlab-ci.yml
|
||||||
17
.project
Normal file
17
.project
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>CanadaDatamartProvider</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
||||||
11
.settings/org.eclipse.jdt.core.prefs
Normal file
11
.settings/org.eclipse.jdt.core.prefs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.6
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package com.flaremicro.visualforecast.datamart;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import com.flaremicro.util.Util;
|
||||||
|
import com.flaremicro.visualforecast.PropertyManager;
|
||||||
|
import com.flaremicro.visualforecast.api.ForecastProvider;
|
||||||
|
import com.flaremicro.visualforecast.forecast.ForecastDetails;
|
||||||
|
|
||||||
|
public class CanadaDatamartProvider extends ForecastProvider {
|
||||||
|
boolean ready = false;
|
||||||
|
PropertyManager propertyManager;
|
||||||
|
ForecastProcessor forecastProcessor;
|
||||||
|
|
||||||
|
ArrayList<TownInfo> towns = new ArrayList<TownInfo>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
propertyManager = super.getOwnPropertyManager();
|
||||||
|
String byCode = propertyManager.getString("towns-by-code", "").toLowerCase();
|
||||||
|
String byNameAndProvince = propertyManager.getString("towns-by-name-and-province", "").toLowerCase();
|
||||||
|
|
||||||
|
if(byCode.isEmpty() && byNameAndProvince.isEmpty())
|
||||||
|
{
|
||||||
|
ready = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedReader bufferedReader = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HashSet<String> byCodes = new HashSet<String>(Arrays.asList(byCode.split(",")));
|
||||||
|
HashSet<String> byNameAndProvinces = new HashSet<String>(Arrays.asList(byNameAndProvince.split(";")));
|
||||||
|
URL url = new URL("https://dd.weather.gc.ca/citypage_weather/docs/site_list_towns_en.csv");
|
||||||
|
bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
|
||||||
|
String line;
|
||||||
|
int skip = 2;
|
||||||
|
while ((line = bufferedReader.readLine()) != null)
|
||||||
|
{
|
||||||
|
if (skip > 0)
|
||||||
|
{
|
||||||
|
skip--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String[] data = line.trim().split(",");
|
||||||
|
if (byCodes.contains(data[0].toLowerCase()) || byNameAndProvinces.contains(data[1].toLowerCase() + "," + data[2].toLowerCase()))
|
||||||
|
{
|
||||||
|
String code = data[0].trim();
|
||||||
|
String town = data[1].trim();
|
||||||
|
String province = data[2].trim();
|
||||||
|
float latitude = Float.parseFloat(data[3].trim().substring(0, data[3].length()-1));
|
||||||
|
float longitude = Float.parseFloat(data[4].trim().substring(0, data[4].length()-1));
|
||||||
|
towns.add(new TownInfo(code, town, province, latitude, longitude));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
ready = true;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Util.cleanClose(bufferedReader);
|
||||||
|
}
|
||||||
|
forecastProcessor = new ForecastProcessor(towns.toArray(new TownInfo[0]));
|
||||||
|
forecastProcessor.processForecasts();
|
||||||
|
ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ForecastDetails getForecast() {
|
||||||
|
return forecastProcessor.getMostRecentForecast();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isForecastReady() {
|
||||||
|
return ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deinit() {
|
||||||
|
propertyManager.store();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
package com.flaremicro.visualforecast.datamart;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import com.flaremicro.util.Util;
|
||||||
|
import com.flaremicro.visualforecast.icons.IconProvider;
|
||||||
|
|
||||||
|
public class DatamartTranslation {
|
||||||
|
|
||||||
|
private HashMap<Integer, Byte> iconTranslation = new HashMap<Integer, Byte>();
|
||||||
|
private HashMap<String, WeatherLines> stringTranslation = new HashMap<String, WeatherLines>();
|
||||||
|
|
||||||
|
public DatamartTranslation() {
|
||||||
|
iconTranslation.put(0, IconProvider.SUN.id);
|
||||||
|
iconTranslation.put(1, IconProvider.PARTLY_CLOUDY.id);
|
||||||
|
iconTranslation.put(2, IconProvider.PARTLY_CLOUDY.id);
|
||||||
|
iconTranslation.put(3, IconProvider.PARTLY_CLOUDY.id);
|
||||||
|
iconTranslation.put(4, IconProvider.PARTLY_CLOUDY.id);
|
||||||
|
iconTranslation.put(5, IconProvider.PARTLY_CLOUDY.id);
|
||||||
|
iconTranslation.put(6, IconProvider.SCATTERD_SHOWERS.id);
|
||||||
|
iconTranslation.put(7, IconProvider.RAIN_SNOW.id);
|
||||||
|
iconTranslation.put(8, IconProvider.SNOW.id);
|
||||||
|
iconTranslation.put(9, IconProvider.RAIN_STORM.id);
|
||||||
|
iconTranslation.put(10, IconProvider.CLOUD.id);
|
||||||
|
iconTranslation.put(11, IconProvider.INVALID.id);
|
||||||
|
iconTranslation.put(12, IconProvider.RAIN_LIGHT.id);
|
||||||
|
iconTranslation.put(13, IconProvider.RAIN_HEAVY.id);
|
||||||
|
iconTranslation.put(14, IconProvider.FREEZING_RAIN.id);
|
||||||
|
iconTranslation.put(15, IconProvider.SCATTERD_SHOWERS.id);
|
||||||
|
iconTranslation.put(16, IconProvider.SNOW.id);
|
||||||
|
iconTranslation.put(17, IconProvider.SNOW.id);
|
||||||
|
iconTranslation.put(18, IconProvider.BLIZZARD.id);
|
||||||
|
iconTranslation.put(19, IconProvider.RAIN_STORM.id);
|
||||||
|
iconTranslation.put(20, IconProvider.INVALID.id);
|
||||||
|
iconTranslation.put(21, IconProvider.INVALID.id);
|
||||||
|
iconTranslation.put(22, IconProvider.PARTLY_CLOUDY.id);
|
||||||
|
iconTranslation.put(23, IconProvider.FOG.id);
|
||||||
|
iconTranslation.put(24, IconProvider.FOG.id);
|
||||||
|
iconTranslation.put(25, IconProvider.INVALID.id);
|
||||||
|
iconTranslation.put(26, IconProvider.INVALID.id);
|
||||||
|
iconTranslation.put(27, IconProvider.HAIL.id);
|
||||||
|
iconTranslation.put(28, IconProvider.RAIN_LIGHTEST.id);
|
||||||
|
iconTranslation.put(29, IconProvider.INVALID.id);
|
||||||
|
iconTranslation.put(30, IconProvider.SUN.id); //MOON
|
||||||
|
iconTranslation.put(31, IconProvider.PARTLY_CLOUDY.id);
|
||||||
|
iconTranslation.put(32, IconProvider.PARTLY_CLOUDY.id);
|
||||||
|
iconTranslation.put(33, IconProvider.CLOUD.id);
|
||||||
|
iconTranslation.put(34, IconProvider.CLOUDY_CLOUDY.id);
|
||||||
|
iconTranslation.put(35, IconProvider.PARTLY_CLOUDY.id);
|
||||||
|
iconTranslation.put(36, IconProvider.SCATTERD_SHOWERS.id);
|
||||||
|
iconTranslation.put(37, IconProvider.RAIN_LIGHT.id);
|
||||||
|
iconTranslation.put(38, IconProvider.SNOW.id);
|
||||||
|
iconTranslation.put(39, IconProvider.LIGHTNING_STORM.id);
|
||||||
|
iconTranslation.put(40, IconProvider.SNOW.id);
|
||||||
|
iconTranslation.put(41, IconProvider.INVALID.id);
|
||||||
|
iconTranslation.put(42, IconProvider.INVALID.id);
|
||||||
|
iconTranslation.put(43, IconProvider.INVALID.id); //WIND
|
||||||
|
iconTranslation.put(44, IconProvider.INVALID.id); //SMOKE
|
||||||
|
|
||||||
|
BufferedReader reader = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
reader = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream("/translation.csv")));
|
||||||
|
String line;
|
||||||
|
while((line = reader.readLine()) != null)
|
||||||
|
{
|
||||||
|
String[] info = line.split(",");
|
||||||
|
if(info.length == 2)
|
||||||
|
{
|
||||||
|
stringTranslation.put(info[0].toLowerCase(), new WeatherLines(info[1], ""));
|
||||||
|
}
|
||||||
|
else if(info.length == 3)
|
||||||
|
{
|
||||||
|
stringTranslation.put(info[0].toLowerCase(), new WeatherLines(info[1], info[2]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Util.cleanClose(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte icon(int icon) {
|
||||||
|
if(!iconTranslation.containsKey(icon))
|
||||||
|
return IconProvider.INVALID.id;
|
||||||
|
return iconTranslation.get(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WeatherLines weatherName(String desc) {
|
||||||
|
WeatherLines lines = stringTranslation.get(desc.toLowerCase());
|
||||||
|
if(lines == null)
|
||||||
|
{
|
||||||
|
System.out.println("FAILED:"+desc.toLowerCase());
|
||||||
|
return new WeatherLines("TRANSLAT.", "FAILURE");
|
||||||
|
}
|
||||||
|
else return lines;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WeatherLines {
|
||||||
|
public final String line1;
|
||||||
|
public final String line2;
|
||||||
|
|
||||||
|
public WeatherLines(String line1, String line2) {
|
||||||
|
this.line1 = line1;
|
||||||
|
this.line2 = line2;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,213 @@
|
|||||||
|
package com.flaremicro.visualforecast.datamart;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import com.flaremicro.util.Util;
|
||||||
|
import com.flaremicro.visualforecast.forecast.DayForecast;
|
||||||
|
import com.flaremicro.visualforecast.forecast.ForecastDetails;
|
||||||
|
import com.flaremicro.visualforecast.forecast.TownForecast;
|
||||||
|
import com.flaremicro.visualforecast.forecast.ValueCheck;
|
||||||
|
|
||||||
|
public class ForecastProcessor implements Runnable {
|
||||||
|
private final TownInfo[] towns;
|
||||||
|
private ForecastDetails mostRecentForecast = null;
|
||||||
|
private boolean running = false;
|
||||||
|
private Thread self;
|
||||||
|
private DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||||
|
|
||||||
|
private DatamartTranslation dmt = new DatamartTranslation();
|
||||||
|
|
||||||
|
public ForecastProcessor(TownInfo[] towns) {
|
||||||
|
this.towns = towns;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
|
}
|
||||||
|
catch (ParserConfigurationException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stringToOffset(String dayString) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDayIndex(String dayString) {
|
||||||
|
dayString = dayString.trim();
|
||||||
|
if (dayString.equalsIgnoreCase("today") || dayString.equalsIgnoreCase("tonight"))
|
||||||
|
return 0;
|
||||||
|
dayString = dayString.toLowerCase().replace("night", "").trim();
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
|
calendar.set(Calendar.MINUTE, 0);
|
||||||
|
calendar.set(Calendar.SECOND, 0);
|
||||||
|
calendar.set(Calendar.MILLISECOND, 0);
|
||||||
|
for (int i = 1; i < 8; i++)
|
||||||
|
{
|
||||||
|
calendar.add(Calendar.HOUR, 24);
|
||||||
|
if (calendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.US).equalsIgnoreCase(dayString))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processForecasts() {
|
||||||
|
ForecastDetails forecastDetails = new ForecastDetails();
|
||||||
|
ArrayList<TownForecast> townForecasts = new ArrayList<TownForecast>();
|
||||||
|
for (TownInfo townInfo : towns)
|
||||||
|
{
|
||||||
|
DayForecast[] dayForecasts = new DayForecast[8];
|
||||||
|
InputStream is = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
URL url = new URL("https://dd.weather.gc.ca/citypage_weather/xml/BC/" + townInfo.code + "_e.xml");
|
||||||
|
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||||
|
is = url.openStream();
|
||||||
|
Document doc = db.parse(is);
|
||||||
|
NodeList nodeList = doc.getElementsByTagName("forecast");
|
||||||
|
for (int i = 0; i < nodeList.getLength(); i++)
|
||||||
|
{
|
||||||
|
if (nodeList.item(1).getNodeType() == Node.ELEMENT_NODE)
|
||||||
|
{
|
||||||
|
Element node = (Element) nodeList.item(i);
|
||||||
|
int dayIndex = getDayIndex(XMLUtils.getStringFromTagAttribute(node, "period", "textForecastName"));
|
||||||
|
Element abbForecast = XMLUtils.getFistElement(node, "abbreviatedForecast");
|
||||||
|
int iconIndex = XMLUtils.getIntFromTag(abbForecast, "iconCode", 0);
|
||||||
|
String textForecast = XMLUtils.getStringFromTag(abbForecast, "textSummary");
|
||||||
|
|
||||||
|
WeatherLines lines = dmt.weatherName(textForecast);
|
||||||
|
byte icon = dmt.icon(iconIndex);
|
||||||
|
|
||||||
|
byte lo = ValueCheck.NO_DATA_BYTE;
|
||||||
|
byte hi = ValueCheck.NO_DATA_BYTE;
|
||||||
|
|
||||||
|
Element element = XMLUtils.getFistElement(node, "temperatures");
|
||||||
|
NodeList temps = element.getElementsByTagName("temperature");
|
||||||
|
for (int j = 0; j < temps.getLength(); j++)
|
||||||
|
{
|
||||||
|
Node n = temps.item(j);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte val = Byte.parseByte(n.getTextContent().trim());
|
||||||
|
if(XMLUtils.getStringFromAttribute(n, "class").trim().equalsIgnoreCase("high"))
|
||||||
|
{
|
||||||
|
hi = val;
|
||||||
|
}
|
||||||
|
else if(XMLUtils.getStringFromAttribute(n, "class").trim().equalsIgnoreCase("low"))
|
||||||
|
{
|
||||||
|
lo = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NumberFormatException ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dayIndex >= 0 && dayIndex <= 7)
|
||||||
|
{
|
||||||
|
if (dayForecasts[dayIndex] != null)
|
||||||
|
{
|
||||||
|
if (lo != ValueCheck.NO_DATA_BYTE && dayForecasts[dayIndex].loTemp == ValueCheck.NO_DATA_BYTE)
|
||||||
|
{
|
||||||
|
dayForecasts[dayIndex].loTemp = lo;
|
||||||
|
}
|
||||||
|
if (hi != ValueCheck.NO_DATA_BYTE && dayForecasts[dayIndex].hiTemp == ValueCheck.NO_DATA_BYTE)
|
||||||
|
{
|
||||||
|
dayForecasts[dayIndex].hiTemp = hi;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dayForecasts[dayIndex] = new DayForecast(hi, lo, icon, lines.line1, lines.line2, ValueCheck.NO_DATA_FLOAT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (ParserConfigurationException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (SAXException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Util.cleanClose(is);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < dayForecasts.length; i++)
|
||||||
|
{
|
||||||
|
if (dayForecasts[i] == null)
|
||||||
|
{
|
||||||
|
dayForecasts[i] = new DayForecast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
townForecasts.add(new TownForecast(townInfo.townName + ", " + townInfo.province, dayForecasts));
|
||||||
|
}
|
||||||
|
forecastDetails.setTownForecast(townForecasts.toArray(new TownForecast[0]));
|
||||||
|
setMostRecentForecast(forecastDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void end() {
|
||||||
|
running = false;
|
||||||
|
self.interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ForecastDetails getMostRecentForecast() {
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
return mostRecentForecast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setMostRecentForecast(ForecastDetails forecast) {
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
mostRecentForecast = forecast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
self = Thread.currentThread();
|
||||||
|
while (running)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep(TimeUnit.MILLISECONDS.convert(1, TimeUnit.HOURS));
|
||||||
|
processForecasts();
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/com/flaremicro/visualforecast/datamart/TownInfo.java
Normal file
17
src/com/flaremicro/visualforecast/datamart/TownInfo.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package com.flaremicro.visualforecast.datamart;
|
||||||
|
|
||||||
|
public class TownInfo {
|
||||||
|
public final String code;
|
||||||
|
public final String townName;
|
||||||
|
public final String province;
|
||||||
|
public final float northLat;
|
||||||
|
public final float westLong;
|
||||||
|
|
||||||
|
public TownInfo(String code, String townName, String province, float northLat, float westLong) {
|
||||||
|
this.code = code;
|
||||||
|
this.townName = townName;
|
||||||
|
this.province = province;
|
||||||
|
this.northLat = northLat;
|
||||||
|
this.westLong = westLong;
|
||||||
|
}
|
||||||
|
}
|
||||||
56
src/com/flaremicro/visualforecast/datamart/XMLUtils.java
Normal file
56
src/com/flaremicro/visualforecast/datamart/XMLUtils.java
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package com.flaremicro.visualforecast.datamart;
|
||||||
|
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
public class XMLUtils {
|
||||||
|
public static String getStringFromTag(Element parent, String tag) {
|
||||||
|
NodeList l = parent.getElementsByTagName(tag);
|
||||||
|
if (l.getLength() > 0)
|
||||||
|
return l.item(0).getTextContent();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getStringFromTagAttribute(Element parent, String tag, String attribute) {
|
||||||
|
NodeList l = parent.getElementsByTagName(tag);
|
||||||
|
if (l.getLength() > 0)
|
||||||
|
{
|
||||||
|
Node attrib = l.item(0).getAttributes().getNamedItem(attribute);
|
||||||
|
if(attrib != null)
|
||||||
|
return attrib.getTextContent();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String getStringFromAttribute(Node n, String attribute) {
|
||||||
|
Node attrib = n.getAttributes().getNamedItem(attribute);
|
||||||
|
if(attrib != null)
|
||||||
|
return attrib.getTextContent();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Element getFistElement(Element parent, String tag) {
|
||||||
|
NodeList l = parent.getElementsByTagName(tag);
|
||||||
|
for (int i = 0; i < l.getLength(); i++)
|
||||||
|
{
|
||||||
|
if (l.item(i).getNodeType() == Node.ELEMENT_NODE)
|
||||||
|
return (Element) l.item(i);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer getIntFromTag(Element abbForecast, String tag, Integer fallback) {
|
||||||
|
String content = getStringFromTag(abbForecast, tag);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Integer.parseInt(content);
|
||||||
|
}
|
||||||
|
catch (NumberFormatException ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/provider.properties
Normal file
1
src/provider.properties
Normal file
@@ -0,0 +1 @@
|
|||||||
|
main-class=com.flaremicro.visualforecast.datamart.CanadaDatamartProvider
|
||||||
99
src/translation.csv
Normal file
99
src/translation.csv
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
Mainly sunny,Mainly,Sunny
|
||||||
|
Mainly cloudy,Mainly, Cloudy
|
||||||
|
Sunny,Sunny,
|
||||||
|
A few clouds,Few,Clouds
|
||||||
|
A mix of sun and cloud,Partly,Cloudy
|
||||||
|
Cloudy periods,Cloudy,Periods
|
||||||
|
Sunny with cloudy periods,Cloudy,Periods
|
||||||
|
Cloudy with sunny periods,Sunny,Periods
|
||||||
|
Increasing cloudiness,Increasing,Clouds
|
||||||
|
Clearing,Clearing,
|
||||||
|
Clear,Sun,
|
||||||
|
Chance of showers,Chance,Showers
|
||||||
|
A few showers,Few,Showers
|
||||||
|
Chance of drizzle or rain,Chance,Drizzle
|
||||||
|
A few flurries or rain showers,Flurries/,Showers
|
||||||
|
Chance of flurries or rain showers,Flurries/,Showers
|
||||||
|
Chance of rain showers or flurries,Flurries/,Showers
|
||||||
|
A few flurries,Flurries,
|
||||||
|
Chance of flurries,Chance,Flurries
|
||||||
|
A few wet flurries,Wet,Flurries
|
||||||
|
Chance of showers at times heavy or thundershowers,Scattered,T'Storms
|
||||||
|
Chance of showers at times heavy or thunderstorms,Scattered,T'Storms
|
||||||
|
Chance of thundershowers,Thunder,Storms
|
||||||
|
Chance of thunderstorms,Thunder,Storms
|
||||||
|
Chance of showers or thundershowers,Thunder,Storms
|
||||||
|
Chance of showers or thunderstorms,Thunder,Storms
|
||||||
|
A few flurries or thundershowers,Thunder,Storms
|
||||||
|
Cloudy,Cloudy,
|
||||||
|
Overcast,Overcast,
|
||||||
|
Showers,Showers,
|
||||||
|
Chance of showers,Chance,Showers
|
||||||
|
Periods of rain,Scattered,Rain
|
||||||
|
Mostly Cloudy,Mostly,Cloudy
|
||||||
|
Rain at times heavy,Heavy,Rain
|
||||||
|
A few showers or drizzle,Drizzle
|
||||||
|
Rain,Rain
|
||||||
|
Chance of freezing rain,Chance,Ice Rain
|
||||||
|
Freezing rain,Freezing,Rain
|
||||||
|
Chance of freezing rain or rain,Chance,Ice Rain,
|
||||||
|
Chance of rain or freezing rain,Chance,Ice Rain,
|
||||||
|
A few rain showers or flurries,Scattered,Flurries
|
||||||
|
Periods of rain or snow,Rain or,Snow
|
||||||
|
A few rain showers or wet flurries,Rain or,Flurries
|
||||||
|
Snow mixed with rain,Rain,Snow
|
||||||
|
Chance of snow mixed with freezing rain,Rain,Snow
|
||||||
|
Wet snow or rain,Wet,Snow
|
||||||
|
Flurries,Flurries,
|
||||||
|
Light snow,Light,Snow
|
||||||
|
Wet flurries,Wet,Flurries
|
||||||
|
Wet snow,Wet,Snow
|
||||||
|
Snow at times heavy,Heavy,Snow
|
||||||
|
Periods of snow,Scattered,Snow
|
||||||
|
Snow,Snow,
|
||||||
|
Chance of snow,Chance,Snow
|
||||||
|
Snow squalls,Snow,Squalls
|
||||||
|
Local snow squalls,Snow,Squalls
|
||||||
|
Blizzard,Blizzard,
|
||||||
|
Near blizzard,Near,Blizzard
|
||||||
|
Snow and blizzard,Blizzard,
|
||||||
|
Snow at times heavy and blowing snow,Blowing,Snow
|
||||||
|
A few showers or thundershowers,Thunder,Showers
|
||||||
|
A few showers or thunderstorms,Thunder,Storms
|
||||||
|
Showers or thundershowers,Thunder,Showers
|
||||||
|
Showers or thunderstorms,Thunder,Storms
|
||||||
|
Rain or thunderstorms,Thunder,Storms
|
||||||
|
Rain or thundershowers,Thunder,Showers
|
||||||
|
Chance of thunderstorms and possible hail,Hail,T'Storms
|
||||||
|
Thunderstorms and possible hail,Hail,T'Storms
|
||||||
|
A mix of sun and cloud,Partly,Cloudy
|
||||||
|
Haze,Haze,
|
||||||
|
Fog,Fog,
|
||||||
|
Fog Patches,Patchy,Fog
|
||||||
|
Fog dissipating,Fog
|
||||||
|
Fog developing,Fog
|
||||||
|
Ice fog,Ice,Fog
|
||||||
|
Ice fog developing,Ice,Fog
|
||||||
|
Ice fog dissipating,Ice,Fog
|
||||||
|
A few flurries mixed with ice pellets,Sleet,Flurries
|
||||||
|
Ice pellet,Sleet
|
||||||
|
Ice pellet mixed with freezing rain,Sleet,Rain
|
||||||
|
Ice pellet mixed with snow,Sleet,Snow
|
||||||
|
Ice pellet or snow,Sleet,Snow
|
||||||
|
Possibility of drizzle mixed with freezing drizzle,Ice,Drizzle
|
||||||
|
Drizzle,Drizzle
|
||||||
|
Freezing drizzle,Freezing,Drizzle
|
||||||
|
Possibility of drizzle,Drizzle
|
||||||
|
Drizzle or freezing drizzle,Freezing,Drizzle
|
||||||
|
Not available,MISSING,DATA
|
||||||
|
Chance of drizzle or rain,Chance,Rain
|
||||||
|
A few flurries or showers,Flurries/,Showers
|
||||||
|
Chance of snow or rain,Chance,Snow
|
||||||
|
A few flurries,Scattered,Flurries
|
||||||
|
Chance of light snow,Light,Snow
|
||||||
|
A few wet flurries,Wet,Flurries
|
||||||
|
Chance of showers at times heavy or thunderstorms,Thunder,Storms
|
||||||
|
Chance of thunderstorms,Thunder,Storms
|
||||||
|
Snow and blowing snow,Blowing,Snow
|
||||||
|
Windy,Windy
|
||||||
|
Smoke,Smoke
|
||||||
|
Can't render this file because it has a wrong number of fields in line 35.
|
Reference in New Issue
Block a user