├── .classpath ├── .gitignore ├── .project ├── .settings ├── org.eclipse.core.resources.prefs ├── org.eclipse.jdt.core.prefs └── org.eclipse.m2e.core.prefs ├── .travis.yml ├── README.md ├── build.bat ├── build.sh ├── deploy.bat ├── deploy.sh ├── pom.xml ├── release-rerun.bat ├── release.bat ├── rollback.bat └── src ├── main ├── java │ └── com │ │ └── github │ │ └── fedy2 │ │ └── weather │ │ ├── QueryBuilder.java │ │ ├── YahooWeatherService.java │ │ ├── binding │ │ ├── Constants.java │ │ ├── RSSParser.java │ │ └── adapter │ │ │ ├── BarometricPressureStateAdapter.java │ │ │ ├── DateAdapter.java │ │ │ ├── DegreeUnitAdapter.java │ │ │ ├── DistanceUnitAdapter.java │ │ │ ├── FloatAdapter.java │ │ │ ├── IntegerAdapter.java │ │ │ ├── PressureUnitAdapter.java │ │ │ ├── RFC822DateAdapter.java │ │ │ ├── SpeedUnitAdapter.java │ │ │ ├── TimeAdapter.java │ │ │ └── WeekDayAdapter.java │ │ └── data │ │ ├── Astronomy.java │ │ ├── Atmosphere.java │ │ ├── Channel.java │ │ ├── Condition.java │ │ ├── Forecast.java │ │ ├── Image.java │ │ ├── Item.java │ │ ├── Location.java │ │ ├── Rss.java │ │ ├── Units.java │ │ ├── Wind.java │ │ ├── Wrapper.java │ │ └── unit │ │ ├── BarometricPressureState.java │ │ ├── DegreeUnit.java │ │ ├── DistanceUnit.java │ │ ├── PressureUnit.java │ │ ├── SpeedUnit.java │ │ ├── Time.java │ │ ├── TimeConvention.java │ │ └── WeekDay.java └── resources │ └── .gitignore └── test ├── java └── com │ └── github │ └── fedy2 │ └── weather │ └── test │ ├── Example.java │ └── TestJaxB.java └── resources └── xml ├── sample-time-parsing.xml └── sample.xml /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | yahoo-weather-java-api 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/test/java=UTF-8 5 | encoding//src/test/resources=UTF-8 6 | encoding/=UTF-8 7 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 3 | org.eclipse.jdt.core.compiler.compliance=1.6 4 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 5 | org.eclipse.jdt.core.compiler.source=1.6 6 | -------------------------------------------------------------------------------- /.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | - openjdk8 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | yahoo-weather-java-api [![Build Status](https://travis-ci.org/fedy2/yahoo-weather-java-api.svg)](https://travis-ci.org/fedy2/yahoo-weather-java-api) 2 | ====================== 3 | 4 | **Current version is not working because the yql service by Yahoo has been dismissed (https://developer.yahoo.com/yql/)** 5 | 6 | A Java library for the yahoo weather service. 7 | 8 | The library is a lightweight wrapper for the Yahoo Weather API (http://developer.yahoo.com/weather/). 9 | 10 | The only required dependency is the slf4j-api library. 11 | 12 | Usage example: 13 | 14 | YahooWeatherService service = new YahooWeatherService(); 15 | Channel channel = service.getForecast("2502265", DegreeUnit.CELSIUS); 16 | System.out.println(channel.getDescription()); 17 | 18 | Dependency declaration: 19 | 20 | 21 | com.github.fedy2 22 | yahoo-weather-java-api 23 | 2.0.2 24 | 25 | 26 | Changelog: 27 | 28 | * 2.0.2 Fixes time parsing when minutes are not padded. 29 | * 2.0.1 Fixes RFC822 date parsing. Fixed lastBuildDate field parsing. 30 | * 2.0.0 Changed whole implementation to use YQL for querying 31 | * 1.2.0 YahooWeatherService constructor now accepts a Proxy to be used during service connections 32 | * 1.1.0 Updated data model: Atmosphere and Wind numeric values have been replaced by corresponding Classes (int to Integer and float to Float) in order to support "missing" values in Weather system response. 33 | * 1.0.1 fixed issues on Date parsing and local settings 34 | * 1.0.0 first release 35 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET WD=%CD% 4 | SET SD=%~dp0 5 | SET PARAMS=%* 6 | 7 | cd "%SD%" 8 | 9 | call mvn clean install %PARAMS% 10 | 11 | cd "%WD%" 12 | 13 | PAUSE 14 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SD=$(cd $(dirname $0); pwd -P) 4 | WD="`pwd`" 5 | SCRIPT=$(basename $0) 6 | SCRIPT_NAME=${SCRIPT%.*} 7 | SCRIPT_EXTENSION=${SCRIPT##*.} 8 | SELF=$SD/$SCRIPT 9 | 10 | cd $SD/ 11 | 12 | mvn clean install 13 | 14 | cd $WD/ -------------------------------------------------------------------------------- /deploy.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET WD=%CD% 4 | SET SD=%~dp0 5 | SET PARAMS=%* 6 | 7 | cd "%SD%" 8 | 9 | call mvn clean deploy -Prelease %PARAMS% 10 | 11 | cd "%WD%" 12 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SD=$(cd $(dirname $0); pwd -P) 4 | WD="`pwd`" 5 | SCRIPT=$(basename $0) 6 | SCRIPT_NAME=${SCRIPT%.*} 7 | SCRIPT_EXTENSION=${SCRIPT##*.} 8 | SELF=$SD/$SCRIPT 9 | 10 | cd $SD/ 11 | 12 | mvn clean install deploy -Prelease 13 | 14 | cd $WD/ -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | com.github.fedy2 7 | yahoo-weather-java-api 8 | 2.0.3-SNAPSHOT 9 | jar 10 | Yahoo Weather Java API 11 | A Java library for the yahoo weather RSS feed service 12 | https://github.com/fedy2/yahoo-weather-java-api 13 | 14 | 15 | 16 | The Apache Software License, Version 2.0 17 | http://www.apache.org/licenses/LICENSE-2.0.txt 18 | repo 19 | 20 | 21 | 22 | 23 | 3.1.1 24 | 25 | 26 | 27 | UTF-8 28 | 29 | 30 | 1.7.21 31 | 32 | 2.19.1 33 | 34 | 35 | 36 | scm:git:https://github.com/fedy2/yahoo-weather-java-api.git 37 | scm:git:https://github.com/fedy2/yahoo-weather-java-api.git 38 | https://github.com/fedy2/yahoo-weather-java-api 39 | HEAD 40 | 41 | 42 | 43 | 44 | defaveri 45 | Federico De Faveri 46 | defaveri@gmail.com 47 | federico.defaveri.org 48 | 49 | developer 50 | 51 | 52 | 53 | 54 | 55 | 56 | org.slf4j 57 | slf4j-api 58 | ${slf4j.version} 59 | 60 | 61 | org.slf4j 62 | slf4j-simple 63 | ${slf4j.version} 64 | runtime 65 | 66 | 67 | 68 | 69 | 70 | 71 | org.apache.maven.plugins 72 | maven-compiler-plugin 73 | 74 | 75 | 76 | 77 | 78 | 79 | org.apache.maven.plugins 80 | maven-compiler-plugin 81 | 3.5.1 82 | 83 | 1.6 84 | 1.6 85 | UTF-8 86 | true 87 | true 88 | 89 | 90 | 91 | org.apache.maven.plugins 92 | maven-install-plugin 93 | 2.5.2 94 | 95 | 96 | org.apache.maven.plugins 97 | maven-deploy-plugin 98 | 2.8.2 99 | 100 | 101 | maven-dependency-plugin 102 | 2.10 103 | 104 | 105 | org.apache.maven.plugins 106 | maven-resources-plugin 107 | 2.7 108 | 109 | \ 110 | true 111 | 112 | 113 | 114 | org.apache.maven.plugins 115 | maven-source-plugin 116 | 3.0.0 117 | 118 | 119 | org.codehaus.mojo 120 | versions-maven-plugin 121 | 2.2 122 | 123 | 124 | org.apache.maven.plugins 125 | maven-eclipse-plugin 126 | 2.10 127 | 128 | 129 | 130 | 131 | true 132 | 133 | 134 | 135 | 136 | org.codehaus.mojo 137 | build-helper-maven-plugin 138 | 1.10 139 | 140 | 141 | org.apache.maven.plugins 142 | maven-clean-plugin 143 | 3.0.0 144 | 145 | 146 | org.apache.maven.plugins 147 | maven-jar-plugin 148 | 2.6 149 | 150 | 151 | 152 | org.apache.maven.plugins 153 | maven-surefire-plugin 154 | ${surefire.version} 155 | 156 | false 157 | 158 | **/Test*.java 159 | 160 | 161 | 162 | 163 | 164 | org.apache.maven.plugins 165 | maven-surefire-report-plugin 166 | ${surefire.version} 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | release 175 | 176 | 177 | ossrh 178 | https://oss.sonatype.org/content/repositories/snapshots 179 | 180 | 181 | ossrh 182 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 183 | 184 | 185 | 186 | 187 | 188 | org.apache.maven.plugins 189 | maven-release-plugin 190 | 2.5.3 191 | 192 | true 193 | false 194 | release 195 | deploy 196 | 197 | 198 | 199 | org.sonatype.plugins 200 | nexus-staging-maven-plugin 201 | 1.6.6 202 | true 203 | 204 | ossrh 205 | https://oss.sonatype.org/ 206 | true 207 | 208 | 209 | 210 | org.apache.maven.plugins 211 | maven-source-plugin 212 | 2.4 213 | 214 | 215 | attach-sources 216 | 217 | jar-no-fork 218 | 219 | 220 | 221 | 222 | 223 | org.apache.maven.plugins 224 | maven-javadoc-plugin 225 | 2.10.3 226 | 227 | 228 | attach-javadocs 229 | 230 | jar 231 | 232 | 233 | 234 | 235 | 236 | org.apache.maven.plugins 237 | maven-gpg-plugin 238 | 1.5 239 | 240 | 241 | sign-artifacts 242 | verify 243 | 244 | sign 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | -------------------------------------------------------------------------------- /release-rerun.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET WD=%CD% 4 | SET SD=%~dp0 5 | SET PARAMS=%* 6 | 7 | cd "%SD%" 8 | 9 | call mvn release:prepare -Prelease -Dusername=${github.username} -Dpassword=${github.password} %PARAMS% 10 | call mvn release:perform -Prelease %PARAMS% 11 | 12 | cd "%WD%" 13 | 14 | PAUSE 15 | -------------------------------------------------------------------------------- /release.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET WD=%CD% 4 | SET SD=%~dp0 5 | SET PARAMS=%* 6 | 7 | cd "%SD%" 8 | 9 | call mvn release:clean release:prepare -Prelease -Dusername=${github.username} -Dpassword=${github.password} %PARAMS% 10 | call mvn release:perform -Prelease %PARAMS% 11 | 12 | cd "%WD%" 13 | 14 | PAUSE 15 | -------------------------------------------------------------------------------- /rollback.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET WD=%CD% 4 | SET SD=%~dp0 5 | SET PARAMS=%* 6 | 7 | cd "%SD%" 8 | 9 | call mvn release:rollback -Prelease %PARAMS% 10 | 11 | cd "%WD%" 12 | 13 | PAUSE 14 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/QueryBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | import java.util.Map.Entry; 9 | 10 | import com.github.fedy2.weather.data.unit.DegreeUnit; 11 | 12 | /** 13 | * An helper for query building. 14 | * @author "Federico De Faveri defaveri@gmail.com" 15 | */ 16 | public class QueryBuilder { 17 | 18 | private static final String WOEID_PARAMETER_NAME = "woeid"; 19 | private static final String DEGREES_PARAMETER_CELSIUS = "u=\"c\""; 20 | private static final String DEGREES_PARAMETER_FAHRENHEIT = "u=\"f\""; 21 | private static final String FIRST_PARAMETER_NAME = "truncate"; 22 | private static final String LAST_PARAMETER_NAME = "tail"; 23 | 24 | private String unitCondition; 25 | private String woeidCondition; 26 | private Map limits; 27 | 28 | public QueryBuilder() { 29 | limits = new HashMap(); 30 | } 31 | 32 | public QueryBuilder woeid(String woeid) { 33 | woeidCondition = WOEID_PARAMETER_NAME + "=" + "\"" + woeid +"\""; 34 | return this; 35 | } 36 | 37 | public QueryBuilder location(String location) { 38 | woeidCondition = WOEID_PARAMETER_NAME + " in (select woeid from geo.places where text=\""+location+"\")"; 39 | return this; 40 | } 41 | 42 | public QueryBuilder unit(DegreeUnit unit) { 43 | switch (unit) { 44 | case CELSIUS: unitCondition = DEGREES_PARAMETER_CELSIUS; break; 45 | case FAHRENHEIT: unitCondition = DEGREES_PARAMETER_FAHRENHEIT; break; 46 | } 47 | return this; 48 | } 49 | 50 | public QueryBuilder first(int limit) { 51 | limits.put(FIRST_PARAMETER_NAME, String.valueOf(limit)); 52 | return this; 53 | } 54 | 55 | public QueryBuilder last(int limit) { 56 | limits.put(LAST_PARAMETER_NAME, String.valueOf(limit)); 57 | return this; 58 | } 59 | 60 | public String build() { 61 | StringBuilder query = new StringBuilder("SELECT * FROM weather.forecast WHERE "); 62 | query.append(woeidCondition).append(" "); 63 | if (unitCondition!=null) query.append("AND ").append(unitCondition).append(" "); 64 | 65 | for (Entry limit:limits.entrySet()) query.append("| ").append(limit.getKey()).append("(count=").append(limit.getValue()).append(") "); 66 | 67 | return query.toString(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/YahooWeatherService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather; 5 | 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.InputStreamReader; 9 | import java.io.Reader; 10 | import java.io.StringWriter; 11 | import java.io.UnsupportedEncodingException; 12 | import java.io.Writer; 13 | import java.net.Proxy; 14 | import java.net.URL; 15 | import java.net.URLConnection; 16 | import java.net.URLEncoder; 17 | import java.util.List; 18 | 19 | import javax.xml.bind.JAXBException; 20 | 21 | import org.slf4j.Logger; 22 | import org.slf4j.LoggerFactory; 23 | 24 | import com.github.fedy2.weather.binding.RSSParser; 25 | import com.github.fedy2.weather.data.Channel; 26 | import com.github.fedy2.weather.data.Rss; 27 | import com.github.fedy2.weather.data.unit.DegreeUnit; 28 | 29 | /** 30 | * Main access point for the Yahoo weather service. 31 | * @author "Federico De Faveri defaveri@gmail.com" 32 | */ 33 | public class YahooWeatherService { 34 | 35 | private static final String WEATHER_SERVICE_BASE_URL = "https://query.yahooapis.com/v1/public/yql"; 36 | 37 | private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; 38 | 39 | public interface LimitDeclaration { 40 | 41 | /** 42 | * Limits results to first count {@link Channel}s. 43 | * @param count the limit of the number of results. 44 | * @return the results. 45 | * @throws JAXBException if an error occurs parsing the response. 46 | * @throws IOException if an error occurs communicating with the service. 47 | */ 48 | List first(int count) throws JAXBException, IOException; 49 | 50 | /** 51 | * Limits results to last count {@link Channel}s. 52 | * @param count the limit of the number of results. 53 | * @return the results. 54 | * @throws JAXBException if an error occurs parsing the response. 55 | * @throws IOException if an error occurs communicating with the service. 56 | */ 57 | List last(int count) throws JAXBException, IOException; 58 | 59 | /** 60 | * Returns all the results with no limits. 61 | * @return the results. 62 | * @throws JAXBException if an error occurs parsing the response. 63 | * @throws IOException if an error occurs communicating with the service. 64 | */ 65 | List all() throws JAXBException, IOException; 66 | } 67 | 68 | private Logger logger = LoggerFactory.getLogger(YahooWeatherService.class); 69 | private RSSParser parser; 70 | private Proxy proxy; 71 | 72 | public YahooWeatherService() throws JAXBException 73 | { 74 | this.parser = new RSSParser(); 75 | this.proxy = Proxy.NO_PROXY; 76 | } 77 | 78 | public YahooWeatherService(Proxy proxy) throws JAXBException 79 | { 80 | this.parser = new RSSParser(); 81 | this.proxy = proxy; 82 | } 83 | 84 | /** 85 | * Gets the Weather RSS feed. 86 | * @param woeid the location WOEID. 87 | * @param unit the degrees units. 88 | * @return the retrieved Channel. 89 | * @throws JAXBException if an error occurs parsing the response. 90 | * @throws IOException if an error occurs communicating with the service. 91 | */ 92 | public Channel getForecast(String woeid, DegreeUnit unit) throws JAXBException, IOException 93 | { 94 | QueryBuilder query = new QueryBuilder(); 95 | query.woeid(woeid).unit(unit); 96 | List channels = execute(query.build()); 97 | if (channels.isEmpty()) throw new IllegalStateException("No results from the service."); 98 | return channels.get(0); 99 | } 100 | 101 | /** 102 | * Gets the Weather RSS feed for the specified location. 103 | * @param location the location to search. 104 | * @param unit the degrees units. 105 | * @return the limit declaration. 106 | */ 107 | public LimitDeclaration getForecastForLocation(String location, DegreeUnit unit) 108 | { 109 | final QueryBuilder query = new QueryBuilder(); 110 | query.location(location).unit(unit); 111 | 112 | return new LimitDeclaration() { 113 | 114 | @Override 115 | public List last(int count) throws JAXBException, IOException { 116 | query.last(count); 117 | return execute(query.build()); 118 | } 119 | 120 | @Override 121 | public List first(int count) throws JAXBException, IOException { 122 | query.first(count); 123 | return execute(query.build()); 124 | } 125 | 126 | @Override 127 | public List all() throws JAXBException, IOException { 128 | return execute(query.build()); 129 | } 130 | }; 131 | } 132 | 133 | /** 134 | * Composes the URL with the specified query. 135 | * @param query the query to submit. 136 | * @return the composed URL. 137 | */ 138 | private String composeUrl(String query) 139 | { 140 | logger.trace("query: {}", query); 141 | StringBuilder url = new StringBuilder(WEATHER_SERVICE_BASE_URL); 142 | try { 143 | url.append("?q=").append(URLEncoder.encode(query, "UTF-8")); 144 | } catch (UnsupportedEncodingException e) { 145 | throw new RuntimeException("Url encoding failed", e); 146 | } 147 | return url.toString(); 148 | } 149 | 150 | private List execute(String query) throws IOException, JAXBException { 151 | String url = composeUrl(query); 152 | String xml = retrieveRSS(url); 153 | Rss rss = parser.parse(xml); 154 | return rss.getChannels(); 155 | } 156 | 157 | /** 158 | * Open the connection to the service and retrieves the data. 159 | * @param serviceUrl the service URL. 160 | * @return the service response. 161 | * @throws IOException if an error occurs during the connection. 162 | */ 163 | private String retrieveRSS(String serviceUrl) throws IOException 164 | { 165 | URL url = new URL(serviceUrl); 166 | URLConnection connection = url.openConnection(proxy); 167 | InputStream is = connection.getInputStream(); 168 | InputStreamReader reader = new InputStreamReader(is); 169 | StringWriter writer = new StringWriter(); 170 | copy(reader, writer); 171 | reader.close(); 172 | is.close(); 173 | 174 | return writer.toString(); 175 | } 176 | 177 | /** 178 | * Copy the input reader into the output writer. 179 | * @param input the input reader. 180 | * @param output the output writer. 181 | * @return the number of char copied. 182 | * @throws IOException if an error occurs during the copy. 183 | */ 184 | private static long copy(Reader input, Writer output) throws IOException { 185 | char[] buffer = new char[DEFAULT_BUFFER_SIZE]; 186 | long count = 0; 187 | int n = 0; 188 | while (-1 != (n = input.read(buffer))) { 189 | output.write(buffer, 0, n); 190 | count += n; 191 | } 192 | return count; 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/binding/Constants.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.binding; 5 | 6 | /** 7 | * @author "Federico De Faveri defaveri@gmail.com" 8 | * 9 | */ 10 | public class Constants { 11 | public static final String YWEATHER_NAMESPACE = "yweather"; 12 | public static final String YWEATHER_NAMESPACE_URI = "http://xml.weather.yahoo.com/ns/rss/1.0"; 13 | public static final String GEO_NAMESPACE_URI = "http://www.w3.org/2003/01/geo/wgs84_pos#"; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/binding/RSSParser.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.binding; 5 | 6 | import java.io.StringReader; 7 | 8 | import javax.xml.bind.JAXBContext; 9 | import javax.xml.bind.JAXBException; 10 | import javax.xml.bind.Unmarshaller; 11 | 12 | import com.github.fedy2.weather.data.Rss; 13 | 14 | /** 15 | * @author "Federico De Faveri defaveri@gmail.com" 16 | * 17 | */ 18 | public class RSSParser { 19 | 20 | private Unmarshaller unmarshaller; 21 | 22 | public RSSParser() throws JAXBException 23 | { 24 | JAXBContext context = JAXBContext.newInstance(Rss.class); 25 | unmarshaller = context.createUnmarshaller(); 26 | } 27 | 28 | public Rss parse(String xml) throws JAXBException 29 | { 30 | return (Rss)unmarshaller.unmarshal(new StringReader(xml)); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/binding/adapter/BarometricPressureStateAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.binding.adapter; 5 | 6 | import javax.xml.bind.annotation.adapters.XmlAdapter; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import com.github.fedy2.weather.data.unit.BarometricPressureState; 12 | 13 | /** 14 | * State of the barometric pressure adapter: steady (0), rising (1), or falling (2). 15 | * (integer: 0, 1, 2) 16 | * @author "Federico De Faveri defaveri@gmail.com" 17 | */ 18 | public class BarometricPressureStateAdapter extends XmlAdapter { 19 | 20 | private static final int FALLING = 2; 21 | private static final int RISING = 1; 22 | private static final int STEADY = 0; 23 | private Logger logger = LoggerFactory.getLogger(BarometricPressureStateAdapter.class); 24 | 25 | /** 26 | * {@inheritDoc} 27 | */ 28 | @Override 29 | public BarometricPressureState unmarshal(Integer v) throws Exception { 30 | switch (v) { 31 | case STEADY: return BarometricPressureState.STEADY; 32 | case RISING: return BarometricPressureState.RISING; 33 | case FALLING: return BarometricPressureState.FALLING; 34 | } 35 | logger.warn("Unknown barometric pressure state \""+v+"\""); 36 | return null; 37 | } 38 | 39 | /** 40 | * {@inheritDoc} 41 | */ 42 | @Override 43 | public Integer marshal(BarometricPressureState v) throws Exception { 44 | switch (v) { 45 | case STEADY: return STEADY; 46 | case RISING: return RISING; 47 | case FALLING: return FALLING; 48 | default: return -1; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/binding/adapter/DateAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.binding.adapter; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import javax.xml.bind.annotation.adapters.XmlAdapter; 10 | import java.text.SimpleDateFormat; 11 | import java.util.Date; 12 | import java.util.Locale; 13 | 14 | /** 15 | * @author "Federico De Faveri defaveri@gmail.com" 16 | */ 17 | public class DateAdapter extends XmlAdapter { 18 | 19 | private Logger logger = LoggerFactory.getLogger(DateAdapter.class); 20 | 21 | private SimpleDateFormat dateFormat = new SimpleDateFormat("d MMM yyyy", Locale.US); 22 | 23 | /** 24 | * {@inheritDoc} 25 | */ 26 | @Override 27 | public String marshal(Date v) throws Exception { 28 | return dateFormat.format(v); 29 | } 30 | 31 | /** 32 | * {@inheritDoc} 33 | */ 34 | @Override 35 | public Date unmarshal(String v) throws Exception { 36 | 37 | try { 38 | return dateFormat.parse(v); 39 | } catch (Exception e) { 40 | logger.warn("Unknown date format \"{}\"", v); 41 | return null; 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/binding/adapter/DegreeUnitAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.binding.adapter; 5 | 6 | import javax.xml.bind.annotation.adapters.XmlAdapter; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import com.github.fedy2.weather.data.unit.DegreeUnit; 12 | 13 | /** 14 | * Degree unit adapter: f for Fahrenheit or c for Celsius (character) 15 | * @author "Federico De Faveri defaveri@gmail.com" 16 | */ 17 | public class DegreeUnitAdapter extends XmlAdapter { 18 | 19 | private static final String CELSIUS = "c"; 20 | private static final String FAHRENHEIT = "f"; 21 | 22 | private Logger logger = LoggerFactory.getLogger(DegreeUnitAdapter.class); 23 | 24 | /** 25 | * {@inheritDoc} 26 | */ 27 | @Override 28 | public DegreeUnit unmarshal(String v) throws Exception { 29 | if (FAHRENHEIT.equalsIgnoreCase(v)) return DegreeUnit.FAHRENHEIT; 30 | if (CELSIUS.equalsIgnoreCase(v)) return DegreeUnit.CELSIUS; 31 | logger.warn("Unknown degree unit \"{}\"", v); 32 | return null; 33 | } 34 | 35 | /** 36 | * {@inheritDoc} 37 | */ 38 | @Override 39 | public String marshal(DegreeUnit v) throws Exception { 40 | switch (v) { 41 | case CELSIUS: return CELSIUS; 42 | case FAHRENHEIT: return FAHRENHEIT; 43 | default: return ""; 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/binding/adapter/DistanceUnitAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.binding.adapter; 5 | 6 | import javax.xml.bind.annotation.adapters.XmlAdapter; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import com.github.fedy2.weather.data.unit.DistanceUnit; 12 | 13 | /** 14 | * Units for distance adapter, mi for miles or km for kilometers. 15 | * @author "Federico De Faveri defaveri@gmail.com" 16 | */ 17 | public class DistanceUnitAdapter extends XmlAdapter { 18 | 19 | private static final String MI = "mi"; 20 | private static final String KM = "km"; 21 | private Logger logger = LoggerFactory.getLogger(DistanceUnitAdapter.class); 22 | 23 | /** 24 | * {@inheritDoc} 25 | */ 26 | @Override 27 | public DistanceUnit unmarshal(String v) throws Exception { 28 | if (MI.equalsIgnoreCase(v)) return DistanceUnit.MI; 29 | if (KM.equalsIgnoreCase(v)) return DistanceUnit.KM; 30 | logger.warn("Unknown distance unit \"{}\"", v); 31 | return null; 32 | } 33 | 34 | /** 35 | * {@inheritDoc} 36 | */ 37 | @Override 38 | public String marshal(DistanceUnit v) throws Exception { 39 | switch (v) { 40 | case KM: return KM; 41 | case MI: return MI; 42 | default: return ""; 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/binding/adapter/FloatAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.binding.adapter; 5 | 6 | import javax.xml.bind.annotation.adapters.XmlAdapter; 7 | 8 | /** 9 | * @author "Federico De Faveri defaveri@gmail.com" 10 | */ 11 | public class FloatAdapter extends XmlAdapter { 12 | 13 | /** 14 | * {@inheritDoc} 15 | */ 16 | @Override 17 | public String marshal(Float v) throws Exception { 18 | return String.valueOf(v); 19 | } 20 | 21 | /** 22 | * {@inheritDoc} 23 | */ 24 | @Override 25 | public Float unmarshal(String v) throws Exception { 26 | if (v == null || v.isEmpty()) return null; 27 | return Float.parseFloat(v); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/binding/adapter/IntegerAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.binding.adapter; 5 | 6 | import javax.xml.bind.annotation.adapters.XmlAdapter; 7 | 8 | /** 9 | * @author "Federico De Faveri defaveri@gmail.com" 10 | */ 11 | public class IntegerAdapter extends XmlAdapter { 12 | 13 | /** 14 | * {@inheritDoc} 15 | */ 16 | @Override 17 | public String marshal(Integer v) throws Exception { 18 | return String.valueOf(v); 19 | } 20 | 21 | /** 22 | * {@inheritDoc} 23 | */ 24 | @Override 25 | public Integer unmarshal(String v) throws Exception { 26 | if (v == null || v.isEmpty()) return null; 27 | return Integer.parseInt(v); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/binding/adapter/PressureUnitAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.binding.adapter; 5 | 6 | import javax.xml.bind.annotation.adapters.XmlAdapter; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import com.github.fedy2.weather.data.unit.PressureUnit; 12 | 13 | /** 14 | * Units of barometric pressure adapter, in for pounds per square inch or mb for millibars. 15 | * @author "Federico De Faveri defaveri@gmail.com" 16 | * 17 | */ 18 | public class PressureUnitAdapter extends XmlAdapter { 19 | 20 | private static final String MB = "mb"; 21 | private static final String IN = "in"; 22 | 23 | private Logger logger = LoggerFactory.getLogger(PressureUnitAdapter.class); 24 | 25 | /** 26 | * {@inheritDoc} 27 | */ 28 | @Override 29 | public PressureUnit unmarshal(String v) throws Exception { 30 | if (IN.equalsIgnoreCase(v)) return PressureUnit.IN; 31 | if (MB.equalsIgnoreCase(v)) return PressureUnit.MB; 32 | logger.warn("Unknown pressure unit \"{}\"", v); 33 | return null; 34 | } 35 | 36 | /** 37 | * {@inheritDoc} 38 | */ 39 | @Override 40 | public String marshal(PressureUnit v) throws Exception { 41 | switch (v) { 42 | case IN: return IN; 43 | case MB: return MB; 44 | default: return ""; 45 | } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/binding/adapter/RFC822DateAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.binding.adapter; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import javax.xml.bind.annotation.adapters.XmlAdapter; 10 | import java.text.SimpleDateFormat; 11 | import java.util.Date; 12 | import java.util.Locale; 13 | 14 | /** 15 | * @author "Federico De Faveri defaveri@gmail.com" 16 | */ 17 | public class RFC822DateAdapter extends XmlAdapter { 18 | 19 | private static final SimpleDateFormat rfc822DateFormats[] = new SimpleDateFormat[]{ 20 | new SimpleDateFormat("EEE, d MMM yy HH:mm:ss z", Locale.US), 21 | new SimpleDateFormat("EEE, d MMM yy HH:mm z", Locale.US), 22 | new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.US), 23 | new SimpleDateFormat("EEE, d MMM yyyy HH:mm z", Locale.US), 24 | new SimpleDateFormat("d MMM yy HH:mm z", Locale.US), 25 | new SimpleDateFormat("d MMM yy HH:mm:ss z", Locale.US), 26 | new SimpleDateFormat("d MMM yyyy HH:mm z", Locale.US), 27 | new SimpleDateFormat("d MMM yyyy HH:mm:ss z", Locale.US), 28 | //exception to RFC 822 format used by Yahoo "Thu, 22 Dec 2011 01:50 pm CET" 29 | new SimpleDateFormat("EEE, d MMM yyyy hh:mm a z", Locale.US)}; 30 | 31 | private Logger logger = LoggerFactory.getLogger(RFC822DateAdapter.class); 32 | 33 | private SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, d MMM yy HH:mm:ss z", Locale.US); 34 | 35 | /** 36 | * {@inheritDoc} 37 | */ 38 | @Override 39 | public String marshal(Date v) throws Exception { 40 | return dateFormat.format(v); 41 | } 42 | 43 | /** 44 | * {@inheritDoc} 45 | */ 46 | @Override 47 | public Date unmarshal(String v) throws Exception { 48 | 49 | for (SimpleDateFormat format : rfc822DateFormats) { 50 | try { 51 | return format.parse(v); 52 | } catch (Exception e) { 53 | }//skipping exception 54 | } 55 | logger.warn("Unknown date format \"{}\"", v); 56 | return null; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/binding/adapter/SpeedUnitAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.binding.adapter; 5 | 6 | import javax.xml.bind.annotation.adapters.XmlAdapter; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import com.github.fedy2.weather.data.unit.SpeedUnit; 12 | 13 | /** 14 | * @author "Federico De Faveri defaveri@gmail.com" 15 | * 16 | */ 17 | public class SpeedUnitAdapter extends XmlAdapter { 18 | 19 | /** 20 | * Official documentation says kph but the service returns km/h. 21 | */ 22 | private static final String KMH = "km/h"; 23 | private static final String MPH = "mph"; 24 | private Logger logger = LoggerFactory.getLogger(SpeedUnitAdapter.class); 25 | 26 | /** 27 | * {@inheritDoc} 28 | */ 29 | @Override 30 | public SpeedUnit unmarshal(String v) throws Exception { 31 | if (MPH.equalsIgnoreCase(v)) return SpeedUnit.MPH; 32 | if (KMH.equalsIgnoreCase(v)) return SpeedUnit.KMH; 33 | logger.warn("Unknown speed unit \"{}\"", v); 34 | return null; 35 | } 36 | 37 | /** 38 | * {@inheritDoc} 39 | */ 40 | @Override 41 | public String marshal(SpeedUnit v) throws Exception { 42 | switch (v) { 43 | case KMH: return KMH; 44 | case MPH: return MPH; 45 | default: return ""; 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/binding/adapter/TimeAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.binding.adapter; 5 | 6 | import java.util.regex.Matcher; 7 | import java.util.regex.Pattern; 8 | 9 | import javax.xml.bind.annotation.adapters.XmlAdapter; 10 | 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import com.github.fedy2.weather.data.unit.Time; 15 | import com.github.fedy2.weather.data.unit.TimeConvention; 16 | 17 | /** 18 | * The time is a string in a local time format of "h:mm am/pm", for example "7:02 am" (string) 19 | * @author "Federico De Faveri defaveri@gmail.com" 20 | * 21 | */ 22 | public class TimeAdapter extends XmlAdapter { 23 | 24 | private static final String TIME_PATTERN = "(\\d?\\d):(\\d?\\d)\\s(am|pm)"; 25 | private static final Pattern PATTERN = Pattern.compile(TIME_PATTERN); 26 | 27 | private Logger logger = LoggerFactory.getLogger(TimeAdapter.class); 28 | 29 | /** 30 | * {@inheritDoc} 31 | */ 32 | @Override 33 | public Time unmarshal(String v) throws Exception { 34 | if (v != null) { 35 | 36 | Matcher matcher = PATTERN.matcher(v); 37 | if (matcher.groupCount()==3) { 38 | matcher.find(); 39 | try { 40 | String hoursToken = matcher.group(1); 41 | int hours = Integer.parseInt(hoursToken); 42 | 43 | String minutesToken = matcher.group(2); 44 | int minutes = Integer.parseInt(minutesToken); 45 | 46 | String conventionToken = matcher.group(3); 47 | TimeConvention convention = TimeConvention.valueOf(conventionToken.toUpperCase()); 48 | 49 | return new Time(hours, minutes, convention); 50 | } catch(NumberFormatException nfe) 51 | { 52 | logger.warn("Error converting time value "+v, nfe); 53 | } 54 | } 55 | } 56 | logger.warn("Unparsable time value \"{}\"", v); 57 | return null; 58 | } 59 | 60 | /** 61 | * {@inheritDoc} 62 | */ 63 | @Override 64 | public String marshal(Time v) throws Exception { 65 | StringBuilder sb = new StringBuilder(); 66 | sb.append(v.getHours()); 67 | sb.append(':'); 68 | sb.append(v.getMinutes()); 69 | sb.append(' '); 70 | sb.append(v.getConvention().toString().toLowerCase()); 71 | return sb.toString(); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/binding/adapter/WeekDayAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.binding.adapter; 5 | 6 | import javax.xml.bind.annotation.adapters.XmlAdapter; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import com.github.fedy2.weather.data.unit.WeekDay; 12 | 13 | /** 14 | * @author "Federico De Faveri defaveri@gmail.com" 15 | * 16 | */ 17 | public class WeekDayAdapter extends XmlAdapter { 18 | 19 | private Logger logger = LoggerFactory.getLogger(WeekDayAdapter.class); 20 | 21 | @Override 22 | public WeekDay unmarshal(String v) throws Exception { 23 | try { 24 | return WeekDay.valueOf(v.toUpperCase()); 25 | } catch (Exception e) 26 | { 27 | logger.warn("Unknow week day \"{}\"", v); 28 | } 29 | return null; 30 | } 31 | 32 | @Override 33 | public String marshal(WeekDay v) throws Exception { 34 | return v!=null?v.toString():null; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/Astronomy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data; 5 | 6 | import javax.xml.bind.annotation.XmlAttribute; 7 | import javax.xml.bind.annotation.XmlRootElement; 8 | import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 9 | 10 | import com.github.fedy2.weather.binding.adapter.TimeAdapter; 11 | import com.github.fedy2.weather.data.unit.Time; 12 | 13 | /** 14 | * Information about astronomical conditions. 15 | * @author "Federico De Faveri defaveri@gmail.com" 16 | */ 17 | @XmlRootElement 18 | public class Astronomy { 19 | 20 | /** 21 | * Today's sunrise time. 22 | */ 23 | @XmlAttribute 24 | @XmlJavaTypeAdapter(TimeAdapter.class) 25 | private Time sunrise; 26 | 27 | /** 28 | * Today's sunset time. 29 | */ 30 | @XmlAttribute 31 | @XmlJavaTypeAdapter(TimeAdapter.class) 32 | private Time sunset; 33 | 34 | public Astronomy() 35 | {} 36 | 37 | /** 38 | * @param sunrise 39 | * @param sunset 40 | */ 41 | public Astronomy(Time sunrise, Time sunset) { 42 | this.sunrise = sunrise; 43 | this.sunset = sunset; 44 | } 45 | 46 | /** 47 | * Returns the today's sunrise time. 48 | * @return the sunrise 49 | */ 50 | public Time getSunrise() { 51 | return sunrise; 52 | } 53 | 54 | /** 55 | * Returns today's sunset time. 56 | * @return the sunset 57 | */ 58 | public Time getSunset() { 59 | return sunset; 60 | } 61 | 62 | /** 63 | * {@inheritDoc} 64 | */ 65 | @Override 66 | public String toString() { 67 | StringBuilder builder = new StringBuilder(); 68 | builder.append("Astronomy [sunrise="); 69 | builder.append(sunrise); 70 | builder.append(", sunset="); 71 | builder.append(sunset); 72 | builder.append("]"); 73 | return builder.toString(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/Atmosphere.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data; 5 | 6 | import javax.xml.bind.annotation.XmlAttribute; 7 | import javax.xml.bind.annotation.XmlRootElement; 8 | import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 9 | 10 | import com.github.fedy2.weather.binding.adapter.BarometricPressureStateAdapter; 11 | import com.github.fedy2.weather.binding.adapter.FloatAdapter; 12 | import com.github.fedy2.weather.binding.adapter.IntegerAdapter; 13 | import com.github.fedy2.weather.data.unit.BarometricPressureState; 14 | 15 | /** 16 | * Information about atmospheric pressure, humidity, and visibility. 17 | * @author "Federico De Faveri defaveri@gmail.com" 18 | */ 19 | @XmlRootElement 20 | public class Atmosphere { 21 | 22 | /** 23 | * Humidity, in percent. 24 | */ 25 | @XmlAttribute(required=false) 26 | @XmlJavaTypeAdapter(IntegerAdapter.class) 27 | private Integer humidity; 28 | 29 | /** 30 | * Visibility, in the units specified by the distance attribute of the units field in the {@link Channel} class. 31 | * Note that the visibility is specified as the actual value * 100. 32 | * For example, a visibility of 16.5 miles will be specified as 1650. A visibility of 14 kilometers will appear as 1400. 33 | */ 34 | @XmlAttribute(required=false) 35 | @XmlJavaTypeAdapter(FloatAdapter.class) 36 | private Float visibility; 37 | 38 | /** 39 | * Barometric pressure, in the units specified by the pressure attribute of the units field in the {@link Channel} class. 40 | */ 41 | @XmlAttribute(required=false) 42 | @XmlJavaTypeAdapter(FloatAdapter.class) 43 | private Float pressure; 44 | 45 | /** 46 | * state of the barometric pressure 47 | */ 48 | @XmlAttribute 49 | @XmlJavaTypeAdapter(BarometricPressureStateAdapter.class) 50 | private BarometricPressureState rising; 51 | 52 | public Atmosphere() 53 | {} 54 | 55 | /** 56 | * @param humidity 57 | * @param visibility 58 | * @param pressure 59 | * @param rising 60 | */ 61 | public Atmosphere(Integer humidity, Float visibility, Float pressure, 62 | BarometricPressureState rising) { 63 | this.humidity = humidity; 64 | this.visibility = visibility; 65 | this.pressure = pressure; 66 | this.rising = rising; 67 | } 68 | 69 | /** 70 | * Returns the humidity, in percent. 71 | * @return the humidity 72 | */ 73 | public Integer getHumidity() { 74 | return humidity; 75 | } 76 | 77 | /** 78 | * Returns the visibility, in the units specified by the distance attribute of the units field in the {@link Channel} class. 79 | * Note that the visibility is specified as the actual value * 100. 80 | * For example, a visibility of 16.5 miles will be specified as 1650. A visibility of 14 kilometers will appear as 1400. 81 | * @return the visibility 82 | */ 83 | public Float getVisibility() { 84 | return visibility; 85 | } 86 | 87 | /** 88 | * Returns the barometric pressure, in the units specified by the pressure attribute of the units field in the {@link Channel} class. 89 | * @return the pressure 90 | */ 91 | public Float getPressure() { 92 | return pressure; 93 | } 94 | 95 | /** 96 | * Returns the state of the barometric pressure. 97 | * @return the rising 98 | */ 99 | public BarometricPressureState getRising() { 100 | return rising; 101 | } 102 | 103 | /** 104 | * {@inheritDoc} 105 | */ 106 | @Override 107 | public String toString() { 108 | StringBuilder builder = new StringBuilder(); 109 | builder.append("Atmosphere [humidity="); 110 | builder.append(humidity); 111 | builder.append(", visibility="); 112 | builder.append(visibility); 113 | builder.append(", pressure="); 114 | builder.append(pressure); 115 | builder.append(", rising="); 116 | builder.append(rising); 117 | builder.append("]"); 118 | return builder.toString(); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/Channel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data; 5 | 6 | import java.util.Date; 7 | 8 | import javax.xml.bind.annotation.XmlAccessType; 9 | import javax.xml.bind.annotation.XmlAccessorType; 10 | import javax.xml.bind.annotation.XmlElement; 11 | import javax.xml.bind.annotation.XmlRootElement; 12 | import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 13 | 14 | import com.github.fedy2.weather.binding.Constants; 15 | import com.github.fedy2.weather.binding.adapter.RFC822DateAdapter; 16 | 17 | /** 18 | * @author "Federico De Faveri defaveri@gmail.com" 19 | * 20 | */ 21 | @XmlAccessorType(XmlAccessType.FIELD) 22 | @XmlRootElement 23 | public class Channel { 24 | 25 | /** 26 | * The title of the feed, which includes the location city. For example "Yahoo! Weather - Sunnyvale, CA" 27 | */ 28 | @XmlElement 29 | private String title; 30 | 31 | /** 32 | * The URL for the Weather page of the forecast for this location. For example http://us.rd.yahoo.com/dailynews/rss/weather/ Sunnyvale__CA/ *http://weather.yahoo.com/ forecast/USCA1116_f.html 33 | */ 34 | @XmlElement 35 | private String link; 36 | 37 | /** 38 | * The language of the weather forecast, for example, en-us for US English. 39 | */ 40 | @XmlElement 41 | private String language; 42 | 43 | /** 44 | * The overall description of the feed including the location, for example "Yahoo! Weather for Sunnyvale, CA" 45 | */ 46 | @XmlElement 47 | private String description; 48 | 49 | /** 50 | * The last time the feed was updated. The format is in the date format defined by RFC822 Section 5, for example Mon, 256 Sep 17:25:18 -0700. 51 | */ 52 | @XmlElement 53 | @XmlJavaTypeAdapter(RFC822DateAdapter.class) 54 | private Date lastBuildDate; 55 | 56 | /** 57 | * Time to Live; how long in minutes this feed should be cached. 58 | */ 59 | @XmlElement 60 | private long ttl; 61 | 62 | /** 63 | * The location of this forecast. 64 | */ 65 | @XmlElement(namespace=Constants.YWEATHER_NAMESPACE_URI) 66 | private Location location; 67 | 68 | /** 69 | * Units for various aspects of the forecast. 70 | */ 71 | @XmlElement(namespace=Constants.YWEATHER_NAMESPACE_URI) 72 | private Units units; 73 | 74 | /** 75 | * Forecast information about wind. 76 | */ 77 | @XmlElement(namespace=Constants.YWEATHER_NAMESPACE_URI) 78 | private Wind wind; 79 | 80 | /** 81 | * Forecast information about current atmospheric pressure, humidity, and visibility. 82 | */ 83 | @XmlElement(namespace=Constants.YWEATHER_NAMESPACE_URI) 84 | private Atmosphere atmosphere; 85 | 86 | /** 87 | * Forecast information about current astronomical conditions. 88 | */ 89 | @XmlElement(namespace=Constants.YWEATHER_NAMESPACE_URI) 90 | private Astronomy astronomy; 91 | 92 | /** 93 | * The image used to identify this feed. 94 | */ 95 | @XmlElement 96 | private Image image; 97 | 98 | /** 99 | * 100 | * The local weather conditions and forecast for a specific location. 101 | */ 102 | @XmlElement 103 | private Item item; 104 | 105 | public Channel() 106 | {} 107 | 108 | /** 109 | * Returns the title of the feed, which includes the location city. For example "Yahoo! Weather - Sunnyvale, CA" 110 | * @return the title 111 | */ 112 | public String getTitle() { 113 | return title; 114 | } 115 | 116 | /** 117 | * Returns the URL for the Weather page of the forecast for this location. For example http://us.rd.yahoo.com/dailynews/rss/weather/ Sunnyvale__CA/ *http://weather.yahoo.com/ forecast/USCA1116_f.html 118 | * @return the link 119 | */ 120 | public String getLink() { 121 | return link; 122 | } 123 | 124 | /** 125 | * Returns the language of the weather forecast, for example, en-us for US English. 126 | * @return the language 127 | */ 128 | public String getLanguage() { 129 | return language; 130 | } 131 | 132 | /** 133 | * Returns the overall description of the feed including the location, for example "Yahoo! Weather for Sunnyvale, CA". 134 | * @return the description 135 | */ 136 | public String getDescription() { 137 | return description; 138 | } 139 | 140 | /** 141 | * Returns the last time the feed was updated. The format is in the date format defined by RFC822 Section 5, for example Mon, 256 Sep 17:25:18 -0700. 142 | * @return the lastBuildDate 143 | */ 144 | public Date getLastBuildDate() { 145 | return lastBuildDate; 146 | } 147 | 148 | /** 149 | * Returns the time to Live; how long in minutes this feed should be cached. 150 | * @return the ttl 151 | */ 152 | public long getTtl() { 153 | return ttl; 154 | } 155 | 156 | /** 157 | * Returns the location of this forecast. 158 | * @return the location 159 | */ 160 | public Location getLocation() { 161 | return location; 162 | } 163 | 164 | /** 165 | * Returns the units for various aspects of the forecast. 166 | * @return the units 167 | */ 168 | public Units getUnits() { 169 | return units; 170 | } 171 | 172 | /** 173 | * Returns the forecast information about wind. 174 | * @return the wind 175 | */ 176 | public Wind getWind() { 177 | return wind; 178 | } 179 | 180 | /** 181 | * Returns the forecast information about current atmospheric pressure, humidity, and visibility. 182 | * @return the atmosphere 183 | */ 184 | public Atmosphere getAtmosphere() { 185 | return atmosphere; 186 | } 187 | 188 | /** 189 | * Returns the forecast information about current astronomical conditions. 190 | * @return the astronomy 191 | */ 192 | public Astronomy getAstronomy() { 193 | return astronomy; 194 | } 195 | 196 | /** 197 | * Returns the image used to identify this feed. 198 | * @return the image 199 | */ 200 | public Image getImage() { 201 | return image; 202 | } 203 | 204 | /** 205 | * Returns the local weather conditions and forecast for a specific location. 206 | * @return the item 207 | */ 208 | public Item getItem() { 209 | return item; 210 | } 211 | 212 | /** 213 | * {@inheritDoc} 214 | */ 215 | @Override 216 | public String toString() { 217 | StringBuilder builder = new StringBuilder(); 218 | builder.append("Channel [title="); 219 | builder.append(title); 220 | builder.append(", link="); 221 | builder.append(link); 222 | builder.append(", language="); 223 | builder.append(language); 224 | builder.append(", description="); 225 | builder.append(description); 226 | builder.append(", lastBuildDate="); 227 | builder.append(lastBuildDate); 228 | builder.append(", ttl="); 229 | builder.append(ttl); 230 | builder.append(", location="); 231 | builder.append(location); 232 | builder.append(", units="); 233 | builder.append(units); 234 | builder.append(", wind="); 235 | builder.append(wind); 236 | builder.append(", atmosphere="); 237 | builder.append(atmosphere); 238 | builder.append(", astronomy="); 239 | builder.append(astronomy); 240 | builder.append(", image="); 241 | builder.append(image); 242 | builder.append(", item="); 243 | builder.append(item); 244 | builder.append("]"); 245 | return builder.toString(); 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/Condition.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data; 5 | 6 | import java.util.Date; 7 | 8 | import javax.xml.bind.annotation.XmlAttribute; 9 | import javax.xml.bind.annotation.XmlRootElement; 10 | import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 11 | 12 | import com.github.fedy2.weather.binding.adapter.RFC822DateAdapter; 13 | 14 | /** 15 | * Weather conditions. 16 | * @author "Federico De Faveri defaveri@gmail.com" 17 | */ 18 | @XmlRootElement 19 | public class Condition { 20 | 21 | /** 22 | * A textual description of conditions, for example, "Partly Cloudy" 23 | */ 24 | @XmlAttribute 25 | private String text; 26 | 27 | /** 28 | * The condition code for this forecast. 29 | */ 30 | @XmlAttribute 31 | private int code; 32 | 33 | /** 34 | * The current temperature, in the units specified by the units field of {@link Channel} class. 35 | */ 36 | @XmlAttribute 37 | private int temp; 38 | 39 | /** 40 | * The current date and time for which this forecast applies. 41 | */ 42 | @XmlAttribute 43 | @XmlJavaTypeAdapter(RFC822DateAdapter.class) 44 | private Date date; 45 | 46 | public Condition() 47 | {} 48 | 49 | /** 50 | * @param text 51 | * @param code 52 | * @param temp 53 | * @param date 54 | */ 55 | public Condition(String text, int code, int temp, Date date) { 56 | this.text = text; 57 | this.code = code; 58 | this.temp = temp; 59 | this.date = date; 60 | } 61 | 62 | /** 63 | * Returns a textual description of conditions, for example, "Partly Cloudy" 64 | * @return the text 65 | */ 66 | public String getText() { 67 | return text; 68 | } 69 | 70 | /** 71 | * Returns the condition code for this forecast. 72 | * @return the code 73 | */ 74 | public int getCode() { 75 | return code; 76 | } 77 | 78 | /** 79 | * Returns the current temperature, in the units specified by the units field of {@link Channel} class. 80 | * @return the temp 81 | */ 82 | public int getTemp() { 83 | return temp; 84 | } 85 | 86 | /** 87 | * Returns the current date and time for which this forecast applies. 88 | * @return the date 89 | */ 90 | public Date getDate() { 91 | return date; 92 | } 93 | 94 | /** 95 | * {@inheritDoc} 96 | */ 97 | @Override 98 | public String toString() { 99 | StringBuilder builder = new StringBuilder(); 100 | builder.append("Condition [text="); 101 | builder.append(text); 102 | builder.append(", code="); 103 | builder.append(code); 104 | builder.append(", temp="); 105 | builder.append(temp); 106 | builder.append(", date="); 107 | builder.append(date); 108 | builder.append("]"); 109 | return builder.toString(); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/Forecast.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data; 5 | 6 | import java.util.Date; 7 | 8 | import javax.xml.bind.annotation.XmlAttribute; 9 | import javax.xml.bind.annotation.XmlRootElement; 10 | import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 11 | 12 | import com.github.fedy2.weather.binding.adapter.DateAdapter; 13 | import com.github.fedy2.weather.binding.adapter.WeekDayAdapter; 14 | import com.github.fedy2.weather.data.unit.WeekDay; 15 | 16 | /** 17 | * The weather forecast for a specific day. 18 | * @author "Federico De Faveri defaveri@gmail.com" 19 | */ 20 | @XmlRootElement 21 | public class Forecast { 22 | 23 | /** 24 | * Day of the week to which this forecast applies. 25 | */ 26 | @XmlAttribute 27 | @XmlJavaTypeAdapter(WeekDayAdapter.class) 28 | private WeekDay day; 29 | 30 | /** 31 | * The date to which this forecast applies. 32 | */ 33 | @XmlAttribute 34 | @XmlJavaTypeAdapter(DateAdapter.class) 35 | private Date date; 36 | 37 | /** 38 | * The forecasted low temperature for this day, in the units specified by the unit field in the {@link Channel} class. 39 | */ 40 | @XmlAttribute 41 | private int low; 42 | 43 | /** 44 | * The forecasted high temperature for this day, in the units specified by the unit field in the {@link Channel} class. 45 | */ 46 | @XmlAttribute 47 | private int high; 48 | 49 | /** 50 | * A textual description of conditions, for example, "Partly Cloudy" 51 | */ 52 | @XmlAttribute 53 | private String text; 54 | 55 | /** 56 | * The condition code for this forecast. 57 | */ 58 | @XmlAttribute 59 | private int code; 60 | 61 | public Forecast(){} 62 | 63 | /** 64 | * @param day 65 | * @param date 66 | * @param low 67 | * @param high 68 | * @param text 69 | * @param code 70 | */ 71 | public Forecast(WeekDay day, Date date, int low, int high, 72 | String text, int code) { 73 | this.day = day; 74 | this.date = date; 75 | this.low = low; 76 | this.high = high; 77 | this.text = text; 78 | this.code = code; 79 | } 80 | 81 | /** 82 | * Returns the day of the week to which this forecast applies. 83 | * @return the day 84 | */ 85 | public WeekDay getDay() { 86 | return day; 87 | } 88 | 89 | /** 90 | * Returns the date to which this forecast applies. 91 | * @return the date 92 | */ 93 | public Date getDate() { 94 | return date; 95 | } 96 | 97 | /** 98 | * Returns the forecasted low temperature for this day, in the units specified by the unit field in the {@link Channel} class. 99 | * @return the low 100 | */ 101 | public int getLow() { 102 | return low; 103 | } 104 | 105 | /** 106 | * Returns the forecasted high temperature for this day, in the units specified by the unit field in the {@link Channel} class. 107 | * @return the high 108 | */ 109 | public int getHigh() { 110 | return high; 111 | } 112 | 113 | /** 114 | * Returns a textual description of conditions, for example, "Partly Cloudy" 115 | * @return the text 116 | */ 117 | public String getText() { 118 | return text; 119 | } 120 | 121 | /** 122 | * Returns the condition code for this forecast. 123 | * The code are listed here: http://developer.yahoo.com/weather/#codes 124 | * @return the code 125 | */ 126 | public int getCode() { 127 | return code; 128 | } 129 | 130 | /** 131 | * {@inheritDoc} 132 | */ 133 | @Override 134 | public String toString() { 135 | StringBuilder builder = new StringBuilder(); 136 | builder.append("Forecast [day="); 137 | builder.append(day); 138 | builder.append(", date="); 139 | builder.append(date); 140 | builder.append(", low="); 141 | builder.append(low); 142 | builder.append(", high="); 143 | builder.append(high); 144 | builder.append(", text="); 145 | builder.append(text); 146 | builder.append(", code="); 147 | builder.append(code); 148 | builder.append("]"); 149 | return builder.toString(); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/Image.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data; 5 | 6 | import javax.xml.bind.annotation.XmlElement; 7 | import javax.xml.bind.annotation.XmlRootElement; 8 | 9 | /** 10 | * @author "Federico De Faveri defaveri@gmail.com" 11 | * 12 | */ 13 | @XmlRootElement 14 | public class Image { 15 | 16 | /** 17 | * The title of the image, for example "Yahoo! Weather". 18 | */ 19 | @XmlElement 20 | private String title; 21 | 22 | /** 23 | * The URL of Yahoo! Weather. 24 | */ 25 | @XmlElement 26 | private String link; 27 | 28 | /** 29 | * The URL of the image. 30 | */ 31 | @XmlElement 32 | private String url; 33 | 34 | /** 35 | * The width of the image, in pixels. 36 | */ 37 | @XmlElement 38 | private int width; 39 | 40 | /** 41 | * The height of the image, in pixels. 42 | */ 43 | @XmlElement 44 | private int height; 45 | 46 | public Image() 47 | {} 48 | 49 | /** 50 | * @param title 51 | * @param link 52 | * @param url 53 | * @param width 54 | * @param height 55 | */ 56 | public Image(String title, String link, String url, int width, 57 | int height) { 58 | this.title = title; 59 | this.link = link; 60 | this.url = url; 61 | this.width = width; 62 | this.height = height; 63 | } 64 | 65 | /** 66 | * Return the title of the image, for example "Yahoo! Weather". 67 | * @return the title 68 | */ 69 | public String getTitle() { 70 | return title; 71 | } 72 | 73 | /** 74 | * Returns the URL of Yahoo! Weather. 75 | * @return the link 76 | */ 77 | public String getLink() { 78 | return link; 79 | } 80 | 81 | /** 82 | * Returns the URL of the image. 83 | * @return the url 84 | */ 85 | public String getUrl() { 86 | return url; 87 | } 88 | 89 | /** 90 | * Returns the width of the image, in pixels. 91 | * @return the width 92 | */ 93 | public int getWidth() { 94 | return width; 95 | } 96 | 97 | /** 98 | * Returns the height of the image, in pixels. 99 | * @return the height 100 | */ 101 | public int getHeight() { 102 | return height; 103 | } 104 | 105 | /** 106 | * {@inheritDoc} 107 | */ 108 | @Override 109 | public String toString() { 110 | StringBuilder builder = new StringBuilder(); 111 | builder.append("Image [title="); 112 | builder.append(title); 113 | builder.append(", link="); 114 | builder.append(link); 115 | builder.append(", url="); 116 | builder.append(url); 117 | builder.append(", width="); 118 | builder.append(width); 119 | builder.append(", height="); 120 | builder.append(height); 121 | builder.append("]"); 122 | return builder.toString(); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/Item.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data; 5 | 6 | import java.util.Date; 7 | import java.util.List; 8 | 9 | import javax.xml.bind.annotation.XmlElement; 10 | import javax.xml.bind.annotation.XmlRootElement; 11 | import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 12 | 13 | import com.github.fedy2.weather.binding.Constants; 14 | import com.github.fedy2.weather.binding.adapter.RFC822DateAdapter; 15 | 16 | /** 17 | * @author "Federico De Faveri defaveri@gmail.com" 18 | * 19 | */ 20 | @XmlRootElement 21 | public class Item { 22 | 23 | /** 24 | * The forecast title and time, for example "Conditions for New York, NY at 1:51 pm EST". 25 | */ 26 | @XmlElement 27 | private String title; 28 | 29 | /** 30 | * The Yahoo! Weather URL for this forecast. 31 | */ 32 | @XmlElement 33 | private String link; 34 | 35 | /** 36 | * A simple summary of the current conditions and tomorrow's forecast, in HTML format, including a link to Yahoo! Weather for the full forecast. 37 | */ 38 | @XmlElement 39 | private String description; 40 | 41 | /** 42 | * Unique identifier for the forecast, made up of the location ID, the date, and the time. 43 | */ 44 | @XmlElement 45 | private String guid; 46 | 47 | /** 48 | * The date and time this forecast was posted. 49 | */ 50 | @XmlElement 51 | @XmlJavaTypeAdapter(RFC822DateAdapter.class) 52 | private Date pubDate; 53 | 54 | /** 55 | * The latitude of the location. 56 | */ 57 | @XmlElement(namespace=Constants.GEO_NAMESPACE_URI, name="lat") 58 | private float geoLat; 59 | 60 | /** 61 | * The longitude of the location. 62 | */ 63 | @XmlElement(namespace=Constants.GEO_NAMESPACE_URI, name="long") 64 | private float geoLong; 65 | 66 | /** 67 | * The current weather conditions. 68 | */ 69 | @XmlElement(namespace=Constants.YWEATHER_NAMESPACE_URI) 70 | private Condition condition; 71 | 72 | /** 73 | * The weather forecast for specific days. 74 | */ 75 | @XmlElement(namespace=Constants.YWEATHER_NAMESPACE_URI, name="forecast") 76 | private List forecasts; 77 | 78 | public Item() 79 | {} 80 | 81 | /** 82 | * Returns the forecast title and time, for example "Conditions for New York, NY at 1:51 pm EST". 83 | * @return the title 84 | */ 85 | public String getTitle() { 86 | return title; 87 | } 88 | 89 | /** 90 | * Returns the Yahoo! Weather URL for this forecast. 91 | * @return the link 92 | */ 93 | public String getLink() { 94 | return link; 95 | } 96 | 97 | /** 98 | * Returns a simple summary of the current conditions and tomorrow's forecast, in HTML format, including a link to Yahoo! Weather for the full forecast. 99 | * @return the description 100 | */ 101 | public String getDescription() { 102 | return description; 103 | } 104 | 105 | /** 106 | * Returns an unique identifier for the forecast, made up of the location ID, the date, and the time. 107 | * @return the guid 108 | */ 109 | public String getGuid() { 110 | return guid; 111 | } 112 | 113 | /** 114 | * Returns the date and time this forecast was posted. 115 | * @return the pubDate 116 | */ 117 | public Date getPubDate() { 118 | return pubDate; 119 | } 120 | 121 | /** 122 | * Returns the latitude of the location. 123 | * @return the geoLat 124 | */ 125 | public float getGeoLat() { 126 | return geoLat; 127 | } 128 | 129 | /** 130 | * Returns the longitude of the location. 131 | * @return the geoLong 132 | */ 133 | public float getGeoLong() { 134 | return geoLong; 135 | } 136 | 137 | /** 138 | * Returns the current weather conditions. 139 | * @return the condition 140 | */ 141 | public Condition getCondition() { 142 | return condition; 143 | } 144 | 145 | /** 146 | * Returns the weather forecast for specific days. 147 | * @return the forecasts 148 | */ 149 | public List getForecasts() { 150 | return forecasts; 151 | } 152 | 153 | /** 154 | * {@inheritDoc} 155 | */ 156 | @Override 157 | public String toString() { 158 | StringBuilder builder = new StringBuilder(); 159 | builder.append("Item [title="); 160 | builder.append(title); 161 | builder.append(", link="); 162 | builder.append(link); 163 | builder.append(", description="); 164 | builder.append(description); 165 | builder.append(", guid="); 166 | builder.append(guid); 167 | builder.append(", pubDate="); 168 | builder.append(pubDate); 169 | builder.append(", geoLat="); 170 | builder.append(geoLat); 171 | builder.append(", geoLong="); 172 | builder.append(geoLong); 173 | builder.append(", condition="); 174 | builder.append(condition); 175 | builder.append(", forecasts="); 176 | builder.append(forecasts); 177 | builder.append("]"); 178 | return builder.toString(); 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/Location.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data; 5 | 6 | import javax.xml.bind.annotation.*; 7 | 8 | /** 9 | * Weather location. 10 | * @author "Federico De Faveri defaveri@gmail.com" 11 | */ 12 | @XmlRootElement 13 | public class Location { 14 | 15 | /** 16 | * City name. 17 | */ 18 | @XmlAttribute 19 | private String city; 20 | 21 | /** 22 | * State, territory, or region, if given 23 | */ 24 | @XmlAttribute 25 | private String region; 26 | 27 | /** 28 | * Two-character country code. 29 | */ 30 | @XmlAttribute 31 | private String country; 32 | 33 | public Location(){} 34 | 35 | /** 36 | * @param city the city name. 37 | * @param region the state, territory, or region. 38 | * @param country the two-character country code. 39 | */ 40 | public Location(String city, String region, String country) { 41 | this.city = city; 42 | this.region = region; 43 | this.country = country; 44 | } 45 | 46 | /** 47 | * Returns the city name. 48 | * @return the city name. 49 | */ 50 | public String getCity() { 51 | return city; 52 | } 53 | 54 | /** 55 | * Returns the state, territory, or region, if given 56 | * @return the region 57 | */ 58 | public String getRegion() { 59 | return region; 60 | } 61 | 62 | /** 63 | * Returns the two-character country code. 64 | * @return the country 65 | */ 66 | public String getCountry() { 67 | return country; 68 | } 69 | 70 | /** 71 | * {@inheritDoc} 72 | */ 73 | @Override 74 | public String toString() { 75 | StringBuilder builder = new StringBuilder(); 76 | builder.append("Location [city="); 77 | builder.append(city); 78 | builder.append(", region="); 79 | builder.append(region); 80 | builder.append(", country="); 81 | builder.append(country); 82 | builder.append("]"); 83 | return builder.toString(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/Rss.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data; 5 | 6 | import java.util.List; 7 | 8 | import javax.xml.bind.annotation.XmlAccessType; 9 | import javax.xml.bind.annotation.XmlAccessorType; 10 | import javax.xml.bind.annotation.XmlElement; 11 | import javax.xml.bind.annotation.XmlRootElement; 12 | import javax.xml.bind.annotation.XmlSeeAlso; 13 | 14 | /** 15 | * @author "Federico De Faveri defaveri@gmail.com" 16 | * 17 | */ 18 | @XmlAccessorType(XmlAccessType.FIELD) 19 | @XmlRootElement(name="query") 20 | @XmlSeeAlso({Channel.class}) 21 | public class Rss { 22 | 23 | @XmlElement 24 | private Wrapper results; 25 | 26 | public Rss() 27 | {} 28 | 29 | /** 30 | * Returns the channel. 31 | * @return the channel 32 | */ 33 | public List getChannels() { 34 | return results.getItems(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/Units.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data; 5 | 6 | import javax.xml.bind.annotation.XmlAttribute; 7 | import javax.xml.bind.annotation.XmlRootElement; 8 | import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 9 | 10 | import com.github.fedy2.weather.binding.adapter.DegreeUnitAdapter; 11 | import com.github.fedy2.weather.binding.adapter.DistanceUnitAdapter; 12 | import com.github.fedy2.weather.binding.adapter.PressureUnitAdapter; 13 | import com.github.fedy2.weather.binding.adapter.SpeedUnitAdapter; 14 | import com.github.fedy2.weather.data.unit.DegreeUnit; 15 | import com.github.fedy2.weather.data.unit.DistanceUnit; 16 | import com.github.fedy2.weather.data.unit.PressureUnit; 17 | import com.github.fedy2.weather.data.unit.SpeedUnit; 18 | 19 | /** 20 | * Units for various aspects of the forecast. 21 | * @author "Federico De Faveri defaveri@gmail.com" 22 | */ 23 | @XmlRootElement 24 | public class Units { 25 | 26 | /** 27 | * Temperature unit. 28 | */ 29 | @XmlAttribute 30 | @XmlJavaTypeAdapter(DegreeUnitAdapter.class) 31 | private DegreeUnit temperature; 32 | 33 | /** 34 | * Distance unit. 35 | */ 36 | @XmlAttribute 37 | @XmlJavaTypeAdapter(DistanceUnitAdapter.class) 38 | private DistanceUnit distance; 39 | 40 | /** 41 | * Units of barometric pressure. 42 | */ 43 | @XmlAttribute 44 | @XmlJavaTypeAdapter(PressureUnitAdapter.class) 45 | private PressureUnit pressure; 46 | 47 | /** 48 | * Units of speed. 49 | */ 50 | @XmlAttribute 51 | @XmlJavaTypeAdapter(SpeedUnitAdapter.class) 52 | private SpeedUnit speed; 53 | 54 | public Units(){} 55 | 56 | /** 57 | * @param temperature 58 | * @param distance 59 | * @param pressure 60 | * @param speed 61 | */ 62 | public Units(DegreeUnit temperature, DistanceUnit distance, 63 | PressureUnit pressure, SpeedUnit speed) { 64 | this.temperature = temperature; 65 | this.distance = distance; 66 | this.pressure = pressure; 67 | this.speed = speed; 68 | } 69 | 70 | /** 71 | * Returns the temperature unit. 72 | * @return the temperature 73 | */ 74 | public DegreeUnit getTemperature() { 75 | return temperature; 76 | } 77 | 78 | /** 79 | * Returns the distance unit. 80 | * @return the distance 81 | */ 82 | public DistanceUnit getDistance() { 83 | return distance; 84 | } 85 | 86 | /** 87 | * Returns the units of barometric pressure. 88 | * @return the pressure 89 | */ 90 | public PressureUnit getPressure() { 91 | return pressure; 92 | } 93 | 94 | /** 95 | * Returns the units of speed. 96 | * @return the speed 97 | */ 98 | public SpeedUnit getSpeed() { 99 | return speed; 100 | } 101 | 102 | /** 103 | * {@inheritDoc} 104 | */ 105 | @Override 106 | public String toString() { 107 | StringBuilder builder = new StringBuilder(); 108 | builder.append("Units [temperature="); 109 | builder.append(temperature); 110 | builder.append(", distance="); 111 | builder.append(distance); 112 | builder.append(", pressure="); 113 | builder.append(pressure); 114 | builder.append(", speed="); 115 | builder.append(speed); 116 | builder.append("]"); 117 | return builder.toString(); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/Wind.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data; 5 | 6 | import javax.xml.bind.annotation.XmlAttribute; 7 | import javax.xml.bind.annotation.XmlRootElement; 8 | import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 9 | 10 | import com.github.fedy2.weather.binding.adapter.FloatAdapter; 11 | import com.github.fedy2.weather.binding.adapter.IntegerAdapter; 12 | 13 | /** 14 | * Information about wind. 15 | * @author "Federico De Faveri defaveri@gmail.com" 16 | */ 17 | @XmlRootElement 18 | public class Wind { 19 | 20 | /** 21 | * Wind chill in degrees. 22 | */ 23 | @XmlAttribute(required=false) 24 | @XmlJavaTypeAdapter(IntegerAdapter.class) 25 | private Integer chill; 26 | 27 | /** 28 | * Wind direction, in degrees. 29 | */ 30 | @XmlAttribute(required=false) 31 | @XmlJavaTypeAdapter(IntegerAdapter.class) 32 | private Integer direction; 33 | 34 | /** 35 | * Wind speed, in the units specified in the speed attribute of the wind speed, 36 | * in the units specified in the speed attribute of the units field of {@link Channel} class. 37 | */ 38 | @XmlAttribute(required=false) 39 | @XmlJavaTypeAdapter(FloatAdapter.class) 40 | private Float speed; 41 | 42 | public Wind() 43 | {} 44 | 45 | /** 46 | * @param chill 47 | * @param direction 48 | * @param speed 49 | */ 50 | public Wind(Integer chill, Integer direction, Float speed) { 51 | this.chill = chill; 52 | this.direction = direction; 53 | this.speed = speed; 54 | } 55 | 56 | /** 57 | * Returns the wind chill in degrees. 58 | * @return the chill 59 | */ 60 | public Integer getChill() { 61 | return chill; 62 | } 63 | 64 | /** 65 | * Returns the wind direction, in degrees. 66 | * @return the direction 67 | */ 68 | public Integer getDirection() { 69 | return direction; 70 | } 71 | 72 | /** 73 | * Returns the wind speed, in the units specified in the speed attribute of the wind speed, 74 | * in the units specified in the speed attribute of the units field of {@link Channel} class. 75 | * @return the speed 76 | */ 77 | public Float getSpeed() { 78 | return speed; 79 | } 80 | 81 | /** 82 | * {@inheritDoc} 83 | */ 84 | @Override 85 | public String toString() { 86 | StringBuilder builder = new StringBuilder(); 87 | builder.append("Wind [chill="); 88 | builder.append(chill); 89 | builder.append(", direction="); 90 | builder.append(direction); 91 | builder.append(", speed="); 92 | builder.append(speed); 93 | builder.append("]"); 94 | return builder.toString(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/Wrapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import javax.xml.bind.annotation.XmlAnyElement; 10 | import javax.xml.bind.annotation.XmlRootElement; 11 | 12 | /** 13 | * List wrapper. 14 | * @author "Federico De Faveri defaveri@gmail.com" 15 | */ 16 | @XmlRootElement 17 | public class Wrapper { 18 | 19 | private List items; 20 | 21 | public Wrapper() { 22 | items = new ArrayList(); 23 | } 24 | 25 | public Wrapper(List items) { 26 | this.items = items; 27 | } 28 | 29 | @XmlAnyElement(lax=true) 30 | public List getItems() { 31 | return items; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/unit/BarometricPressureState.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data.unit; 5 | 6 | /** 7 | * Barometric pressure states. 8 | * @author "Federico De Faveri defaveri@gmail.com" 9 | */ 10 | public enum BarometricPressureState { 11 | /** 12 | * Steady. 13 | */ 14 | STEADY, 15 | 16 | /** 17 | * Rising. 18 | */ 19 | RISING, 20 | 21 | /** 22 | * Falling. 23 | */ 24 | FALLING; 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/unit/DegreeUnit.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data.unit; 5 | 6 | /** 7 | * Units for distance. 8 | * @author "Federico De Faveri defaveri@gmail.com" 9 | */ 10 | public enum DegreeUnit { 11 | 12 | /** 13 | * Fahrenheit. 14 | */ 15 | FAHRENHEIT, 16 | 17 | /** 18 | * Celsius. 19 | */ 20 | CELSIUS; 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/unit/DistanceUnit.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data.unit; 5 | 6 | /** 7 | * Distance unit. 8 | * @author "Federico De Faveri defaveri@gmail.com" 9 | */ 10 | public enum DistanceUnit { 11 | 12 | /** 13 | * Miles. 14 | */ 15 | MI, 16 | 17 | /** 18 | * Kilometers. 19 | */ 20 | KM; 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/unit/PressureUnit.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data.unit; 5 | 6 | /** 7 | * Units of barometric pressure. 8 | * @author "Federico De Faveri defaveri@gmail.com" 9 | */ 10 | public enum PressureUnit { 11 | 12 | /** 13 | * Pounds per square inch. 14 | */ 15 | IN, 16 | 17 | /** 18 | * Millibars. 19 | */ 20 | MB; 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/unit/SpeedUnit.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data.unit; 5 | 6 | /** 7 | * Units of speed. 8 | * @author "Federico De Faveri defaveri@gmail.com" 9 | */ 10 | public enum SpeedUnit { 11 | 12 | /** 13 | * Miles per hour. 14 | */ 15 | MPH, 16 | 17 | /** 18 | * Kilometers per hour. 19 | */ 20 | KMH; 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/unit/Time.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data.unit; 5 | 6 | /** 7 | * @author "Federico De Faveri defaveri@gmail.com" 8 | * 9 | */ 10 | public class Time { 11 | 12 | private int hours; 13 | private int minutes; 14 | private TimeConvention convention; 15 | 16 | /** 17 | * @param hours 18 | * @param minutes 19 | * @param convention 20 | */ 21 | public Time(int hours, int minutes, TimeConvention convention) { 22 | this.hours = hours; 23 | this.minutes = minutes; 24 | this.convention = convention; 25 | } 26 | 27 | /** 28 | * Returns the hours. 29 | * @return the hours 30 | */ 31 | public int getHours() { 32 | return hours; 33 | } 34 | 35 | /** 36 | * Returns the minutes. 37 | * @return the minutes 38 | */ 39 | public int getMinutes() { 40 | return minutes; 41 | } 42 | 43 | /** 44 | * Returns the time convention. 45 | * @return the convention 46 | */ 47 | public TimeConvention getConvention() { 48 | return convention; 49 | } 50 | 51 | /** 52 | * {@inheritDoc} 53 | */ 54 | @Override 55 | public String toString() { 56 | StringBuilder builder = new StringBuilder(); 57 | builder.append("Time [hours="); 58 | builder.append(hours); 59 | builder.append(", minutes="); 60 | builder.append(minutes); 61 | builder.append(", convention="); 62 | builder.append(convention); 63 | builder.append("]"); 64 | return builder.toString(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/unit/TimeConvention.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.data.unit; 5 | 6 | /** 7 | * Time convention. 8 | * @author "Federico De Faveri defaveri@gmail.com" 9 | * 10 | */ 11 | public enum TimeConvention { 12 | /** 13 | * ante meridiem (a.m., English: "before midday") 14 | */ 15 | AM, 16 | 17 | /** 18 | * post meridiem (p.m., English: "after midday") 19 | */ 20 | PM; 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/fedy2/weather/data/unit/WeekDay.java: -------------------------------------------------------------------------------- 1 | package com.github.fedy2.weather.data.unit; 2 | 3 | /** 4 | * @author "Federico De Faveri defaveri@gmail.com" 5 | */ 6 | public enum WeekDay { 7 | MON, 8 | TUE, 9 | WED, 10 | THU, 11 | FRI, 12 | SAT, 13 | SUN; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/resources/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fedy2/yahoo-weather-java-api/c1b90799b7ea01996ff2ab5e22c6835c8a0e80d2/src/main/resources/.gitignore -------------------------------------------------------------------------------- /src/test/java/com/github/fedy2/weather/test/Example.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.test; 5 | 6 | import java.io.IOException; 7 | import java.util.List; 8 | 9 | import javax.xml.bind.JAXBException; 10 | 11 | import com.github.fedy2.weather.YahooWeatherService; 12 | import com.github.fedy2.weather.data.Channel; 13 | import com.github.fedy2.weather.data.unit.DegreeUnit; 14 | 15 | /** 16 | * @author "Federico De Faveri defaveri@gmail.com" 17 | * 18 | */ 19 | public class Example { 20 | 21 | /** 22 | * @param args 23 | * @throws JAXBException 24 | * @throws IOException 25 | */ 26 | public static void main(String[] args) throws JAXBException, IOException { 27 | YahooWeatherService service = new YahooWeatherService(); 28 | Channel result = service.getForecast("670807", DegreeUnit.CELSIUS); 29 | System.out.println(result.getDescription()); 30 | System.out.println(result.getTitle()); 31 | 32 | List channels = service.getForecastForLocation("Oristano", DegreeUnit.CELSIUS).first(3); 33 | for (Channel channel:channels) System.out.println(channel.getTitle()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/com/github/fedy2/weather/test/TestJaxB.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.github.fedy2.weather.test; 5 | 6 | import java.io.FileNotFoundException; 7 | import java.io.FileReader; 8 | 9 | import javax.xml.bind.JAXBContext; 10 | import javax.xml.bind.JAXBException; 11 | import javax.xml.bind.Unmarshaller; 12 | 13 | import com.github.fedy2.weather.data.Channel; 14 | import com.github.fedy2.weather.data.Rss; 15 | 16 | /** 17 | * @author "Federico De Faveri defaveri@gmail.com" 18 | * 19 | */ 20 | public class TestJaxB { 21 | 22 | /** 23 | * @param args 24 | * @throws JAXBException 25 | * @throws FileNotFoundException 26 | */ 27 | public static void main(String[] args) throws JAXBException, FileNotFoundException { 28 | JAXBContext context = JAXBContext.newInstance(Rss.class); 29 | Unmarshaller unmarshaller = context.createUnmarshaller(); 30 | Rss rss = (Rss)unmarshaller.unmarshal(new FileReader("src/test/resources/xml/sample.xml")); 31 | 32 | System.out.println(rss.getChannels()); 33 | 34 | rss = (Rss)unmarshaller.unmarshal(new FileReader("src/test/resources/xml/sample-time-parsing.xml")); 35 | for (Channel channel : rss.getChannels()) { 36 | System.out.println("Sunrise: " + channel.getAstronomy().getSunrise()); 37 | System.out.println("Sunset: " + channel.getAstronomy().getSunset()); 38 | } 39 | 40 | 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/test/resources/xml/sample-time-parsing.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | Yahoo! Weather - Vienna, Vienna, AT 10 | http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-551801/ 11 | Yahoo! Weather for Vienna, Vienna, AT 12 | en-us 13 | Wed, 13 Jul 2016 03:07 PM CEST 14 | 60 15 | 18 | 21 | 24 | 27 | 28 | Yahoo! Weather 29 | 142 30 | 18 31 | http://weather.yahoo.com 32 | http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif 33 | 34 | 35 | Conditions for Vienna, Vienna, AT at 01:00 PM CEST 36 | 48.202541 37 | 16.368799 38 | http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-551801/ 39 | Wed, 13 Jul 2016 01:00 PM CEST 40 | 44 | 48 | 52 | 56 | 60 | 64 | 68 | 72 | 76 | 80 | 84 | <![CDATA[<img src="http://l.yimg.com/a/i/us/we/52/28.gif"/> 85 | <BR /> 86 | <b>Current Conditions:</b> 87 | <BR />Mostly Cloudy 88 | <BR /> 89 | <BR /> 90 | <b>Forecast:</b> 91 | <BR /> Wed - Thunderstorms. High: 72Low: 62 92 | <BR /> Thu - Scattered Thunderstorms. High: 65Low: 56 93 | <BR /> Fri - Partly Cloudy. High: 67Low: 54 94 | <BR /> Sat - Mostly Cloudy. High: 69Low: 56 95 | <BR /> Sun - Partly Cloudy. High: 72Low: 57 96 | <BR /> 97 | <BR /> 98 | <a href="http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-551801/">Full Forecast at Yahoo! Weather</a> 99 | <BR /> 100 | <BR /> 101 | (provided by <a href="http://www.weather.com" >The Weather Channel</a>) 102 | <BR /> 103 | ]]> 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /src/test/resources/xml/sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Yahoo! Weather - Sunnyvale, CA 5 | http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_f.html 6 | Yahoo! Weather for Sunnyvale, CA 7 | en-us 8 | Sat, 09 Aug 2014 6:54 am PDT 9 | 60 10 | 11 | 12 | 13 | 14 | 15 | 16 | Yahoo! Weather 17 | 142 18 | 18 19 | http://weather.yahoo.com 20 | http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif 21 | 22 | 23 | Conditions for Sunnyvale, CA at 6:54 am PDT 24 | 37.37 25 | -122.04 26 | http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_f.html 27 | Sat, 09 Aug 2014 6:54 am PDT 28 | 29 |
31 | Current Conditions:
32 | Fair, 59 F
33 |
Forecast:
34 | Sat - AM Clouds/PM Sun. High: 78 Low: 58
35 | Sun - AM Clouds/PM Sun. High: 77 Low: 58
36 | Mon - AM Clouds/PM Sun. High: 79 Low: 58
37 | Tue - AM Clouds/PM Sun. High: 77 Low: 59
38 | Wed - AM Clouds/PM Sun. High: 80 Low: 60
39 |
40 | Full Forecast at Yahoo! Weather

41 | (provided by The Weather Channel)
42 | ]]>
43 | 44 | 45 | 46 | 47 | 48 | USCA1116_2014_08_13_7_00_PDT 49 |
50 |
51 | 52 | --------------------------------------------------------------------------------