diff --git b/pom.xml a/pom.xml new file mode 100644 index 0000000..24edcbe --- /dev/null +++ a/pom.xml @@ -0,0 +1,110 @@ + + + 4.0.0 + + pl.labno.bernard.nbp.exchangerate + nbp-exchangerate-api + 1.0 + + + + junit + junit + 4.5 + test + + + net.sourceforge.yarfraw + yarfraw + 0.92 + + + commons-codec + commons-codec + 1.4 + + + commons-logging + commons-logging-api + 1.1 + + + javax.xml.bind + jaxb-api + 2.1 + + + com.sun.xml.bind + jaxb-impl + 2.1 + test + + + + + + generate-jaxb-artifacts + + + + org.codehaus.mojo + jaxb2-maven-plugin + + + + xjc + + + + + pl.labno.bernard.nbp.exchangerate.rest.generated + ${build.sourceDirectory} + false + false + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + testOutputDirectory + ${build.testOutputDirectory} + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.5 + 1.5 + + + + org.apache.maven.plugins + maven-source-plugin + 2.1.1 + + + + jar + + + + + + + + \ No newline at end of file diff --git b/src/main/java/pl/labno/bernard/nbp/exchangerate/Updater.java a/src/main/java/pl/labno/bernard/nbp/exchangerate/Updater.java new file mode 100644 index 0000000..c15b132 --- /dev/null +++ a/src/main/java/pl/labno/bernard/nbp/exchangerate/Updater.java @@ -0,0 +1,39 @@ +package pl.labno.bernard.nbp.exchangerate; + +import org.apache.commons.httpclient.HttpURL; +import pl.labno.bernard.nbp.exchangerate.rest.ExchangeRateTableUnmarshaller; +import pl.labno.bernard.nbp.exchangerate.rest.generated.ExchangeRateTable; +import yarfraw.core.datamodel.ChannelFeed; +import yarfraw.core.datamodel.ItemEntry; +import yarfraw.core.datamodel.YarfrawException; +import yarfraw.utils.reader.FeedReaderUtils; + +import javax.xml.bind.JAXBException; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.Executors; + +public class Updater { + + private String feedURL = "http://rss.nbp.pl/kursy/TabelaA.xml"; + + public String getFeedURL() { + return feedURL; + } + + public void setFeedURL(String feedURL) { + this.feedURL = feedURL; + } + + public ExchangeRateTable getRecentExchangeTable() throws IOException, YarfrawException, JAXBException { + final List feedList = FeedReaderUtils.readAll(Executors.newCachedThreadPool(), new HttpURL(feedURL)); + if(feedList.size() < 1) { + throw new IllegalArgumentException("Read 0 feeds."); + } + final List entries = feedList.get(0).getItems(); + if(entries.size() < 1) { + return null; + } + return ExchangeRateTableUnmarshaller.unmarshal(entries.get(0).getEnclosure().getUrl()); + } +} diff --git b/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/ExchangeRateTableUnmarshaller.java a/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/ExchangeRateTableUnmarshaller.java new file mode 100644 index 0000000..561c1c0 --- /dev/null +++ a/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/ExchangeRateTableUnmarshaller.java @@ -0,0 +1,40 @@ +package pl.labno.bernard.nbp.exchangerate.rest; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import pl.labno.bernard.nbp.exchangerate.rest.generated.ExchangeRateTable; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.net.URL; + +public class ExchangeRateTableUnmarshaller { + + private static final Log LOG = LogFactory.getLog(ExchangeRateTableUnmarshaller.class); + + public static ExchangeRateTable unmarshal(String url) throws JAXBException, IOException { + return unmarshal(new URL(url).openStream()); + } + + public static ExchangeRateTable unmarshal(InputStream stream) throws JAXBException, IOException { + return unmarshal(new InputStreamReader(stream)); + } + + public static ExchangeRateTable unmarshal(Reader reader) throws JAXBException, IOException { + String content = IOUtils.toString(reader); + try { + JAXBContext jaxbContext = JAXBContext.newInstance(ExchangeRateTable.class.getPackage().getName()); + return (ExchangeRateTable) jaxbContext.createUnmarshaller().unmarshal(new StringReader(content)); + } catch (JAXBException e) { + LOG.error("Cannot unmarshal input stream.\n" + content, e); + throw e; + } + } + +} diff --git b/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/RateConverter.java a/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/RateConverter.java new file mode 100644 index 0000000..699dc2d --- /dev/null +++ a/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/RateConverter.java @@ -0,0 +1,10 @@ +package pl.labno.bernard.nbp.exchangerate.rest; + +import java.math.BigDecimal; + +public class RateConverter { + + public static BigDecimal convert(String value) { + return new BigDecimal(value.replaceAll(",",".")); + } +} diff --git b/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/generated/Adapter1.java a/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/generated/Adapter1.java new file mode 100644 index 0000000..37fd62b --- /dev/null +++ a/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/generated/Adapter1.java @@ -0,0 +1,30 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2010.12.16 at 02:23:57 PM GMT +// + + +package pl.labno.bernard.nbp.exchangerate.rest.generated; + +import java.math.BigDecimal; +import javax.xml.bind.annotation.adapters.XmlAdapter; + +public class Adapter1 + extends XmlAdapter +{ + + + public BigDecimal unmarshal(String value) { + return (pl.labno.bernard.nbp.exchangerate.rest.RateConverter.convert(value)); + } + + public String marshal(BigDecimal value) { + if (value == null) { + return null; + } + return value.toString(); + } + +} diff --git b/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/generated/ExchangeRate.java a/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/generated/ExchangeRate.java new file mode 100644 index 0000000..7da6a1c --- /dev/null +++ a/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/generated/ExchangeRate.java @@ -0,0 +1,159 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2010.12.16 at 02:23:57 PM GMT +// + + +package pl.labno.bernard.nbp.exchangerate.rest.generated; + +import java.math.BigDecimal; +import java.math.BigInteger; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="nazwa_waluty" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="przelicznik" type="{http://www.w3.org/2001/XMLSchema}integer"/>
+ *         <element name="kod_waluty" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="kurs_sredni" type="{http://www.w3.org/2001/XMLSchema}float"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "currencyName", + "przelicznik", + "currencySymbol", + "value" +}) +public class ExchangeRate { + + @XmlElement(name = "nazwa_waluty", required = true) + protected String currencyName; + @XmlElement(required = true) + protected BigInteger przelicznik; + @XmlElement(name = "kod_waluty", required = true) + protected String currencySymbol; + @XmlElement(name = "kurs_sredni", required = true, type = String.class) + @XmlJavaTypeAdapter(Adapter1 .class) + @XmlSchemaType(name = "float") + protected BigDecimal value; + + /** + * Gets the value of the currencyName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCurrencyName() { + return currencyName; + } + + /** + * Sets the value of the currencyName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCurrencyName(String value) { + this.currencyName = value; + } + + /** + * Gets the value of the przelicznik property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getPrzelicznik() { + return przelicznik; + } + + /** + * Sets the value of the przelicznik property. + * + * @param value + * allowed object is + * {@link BigInteger } + * + */ + public void setPrzelicznik(BigInteger value) { + this.przelicznik = value; + } + + /** + * Gets the value of the currencySymbol property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCurrencySymbol() { + return currencySymbol; + } + + /** + * Sets the value of the currencySymbol property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCurrencySymbol(String value) { + this.currencySymbol = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public BigDecimal getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValue(BigDecimal value) { + this.value = value; + } + +} diff --git b/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/generated/ExchangeRateTable.java a/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/generated/ExchangeRateTable.java new file mode 100644 index 0000000..bb3a3d3 --- /dev/null +++ a/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/generated/ExchangeRateTable.java @@ -0,0 +1,149 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2010.12.16 at 02:23:57 PM GMT +// + + +package pl.labno.bernard.nbp.exchangerate.rest.generated; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import java.util.ArrayList; +import java.util.List; + + +/** + *

Java class for tabela_kursow element declaration. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <element name="tabela_kursow">
+ *   <complexType>
+ *     <complexContent>
+ *       <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *         <sequence>
+ *           <element name="numer_tabeli" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *           <element name="data_publikacji" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *           <element name="pozycja" maxOccurs="unbounded" minOccurs="0">
+ *             <complexType>
+ *               <complexContent>
+ *                 <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                   <sequence>
+ *                     <element name="nazwa_waluty" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *                     <element name="przelicznik" type="{http://www.w3.org/2001/XMLSchema}integer"/>
+ *                     <element name="kod_waluty" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *                     <element name="kurs_sredni" type="{http://www.w3.org/2001/XMLSchema}float"/>
+ *                   </sequence>
+ *                 </restriction>
+ *               </complexContent>
+ *             </complexType>
+ *           </element>
+ *         </sequence>
+ *       </restriction>
+ *     </complexContent>
+ *   </complexType>
+ * </element>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "number", + "publicationDate", + "items" +}) +@XmlRootElement(name = "tabela_kursow") +public class ExchangeRateTable { + + @XmlElement(name = "numer_tabeli", required = true) + protected String number; + @XmlElement(name = "data_publikacji", required = true) + protected String publicationDate; + @XmlElement(name = "pozycja") + protected List items; + + /** + * Gets the value of the number property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getNumber() { + return number; + } + + /** + * Sets the value of the number property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setNumber(String value) { + this.number = value; + } + + /** + * Gets the value of the publicationDate property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPublicationDate() { + return publicationDate; + } + + /** + * Sets the value of the publicationDate property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPublicationDate(String value) { + this.publicationDate = value; + } + + /** + * Gets the value of the items property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the items property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getItems().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link ExchangeRate } + * + * + */ + public List getItems() { + if (items == null) { + items = new ArrayList(); + } + return this.items; + } + +} diff --git b/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/generated/ObjectFactory.java a/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/generated/ObjectFactory.java new file mode 100644 index 0000000..02537c1 --- /dev/null +++ a/src/main/java/pl/labno/bernard/nbp/exchangerate/rest/generated/ObjectFactory.java @@ -0,0 +1,55 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2010.12.16 at 02:23:57 PM GMT +// + + +package pl.labno.bernard.nbp.exchangerate.rest.generated; + +import javax.xml.bind.annotation.XmlRegistry; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the pl.labno.bernard.nbp.exchangerate.rest.generated package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: pl.labno.bernard.nbp.exchangerate.rest.generated + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link ExchangeRateTable } + * + */ + public ExchangeRateTable createExchangeRateTable() { + return new ExchangeRateTable(); + } + + /** + * Create an instance of {@link ExchangeRate } + * + */ + public ExchangeRate createExchangeRate() { + return new ExchangeRate(); + } + +} diff --git b/src/main/xjb/bindings.xjb a/src/main/xjb/bindings.xjb new file mode 100644 index 0000000..a14f844 --- /dev/null +++ a/src/main/xjb/bindings.xjb @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git b/src/main/xsd/response.xsd a/src/main/xsd/response.xsd new file mode 100644 index 0000000..d186ecc --- /dev/null +++ a/src/main/xsd/response.xsd @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git b/src/test/java/pl/labno/bernard/nbp/exchangerate/UpdaterTest.java a/src/test/java/pl/labno/bernard/nbp/exchangerate/UpdaterTest.java new file mode 100644 index 0000000..fcd8d03 --- /dev/null +++ a/src/test/java/pl/labno/bernard/nbp/exchangerate/UpdaterTest.java @@ -0,0 +1,24 @@ +package pl.labno.bernard.nbp.exchangerate; + +import org.junit.Assert; +import org.junit.Test; +import pl.labno.bernard.nbp.exchangerate.rest.generated.ExchangeRate; +import pl.labno.bernard.nbp.exchangerate.rest.generated.ExchangeRateTable; +import yarfraw.core.datamodel.YarfrawException; + +import javax.xml.bind.JAXBException; +import java.io.IOException; + +public class UpdaterTest { + + @Test + public void testGetRecentExchangeTable() throws YarfrawException, IOException, JAXBException { + final ExchangeRateTable recentExchangeTable = new Updater().getRecentExchangeTable(); + Assert.assertNotNull(recentExchangeTable); + for (ExchangeRate exchangeRate : recentExchangeTable.getItems()) { + Assert.assertNotNull(exchangeRate.getCurrencyName()); + Assert.assertNotNull(exchangeRate.getCurrencySymbol()); + Assert.assertTrue(exchangeRate.getValue().doubleValue() != 0d); + } + } +}