{"id":371,"date":"2011-07-01T16:45:06","date_gmt":"2011-07-01T15:45:06","guid":{"rendered":"http:\/\/www.xenonique.co.uk\/blog\/?p=371"},"modified":"2011-07-03T23:34:18","modified_gmt":"2011-07-03T22:34:18","slug":"scalafication-of-a-java-equity-quote-application-part-1","status":"publish","type":"post","link":"https:\/\/www.xenonique.co.uk\/blog\/2011\/07\/01\/scalafication-of-a-java-equity-quote-application-part-1\/","title":{"rendered":"Scalafication of a Java Equity Quote Application Part 1"},"content":{"rendered":"<p>Here follows in these series of three article is a description of Scala application that ported from Java. I would prefer to call this work a <span style=\"color: #0000ff;\"><strong>\u201cScalafication\u201d<\/strong>.<\/span><\/p>\n<p>Many people are thinking about Scala Adoption as it gets important interest from the wider community. Did you know that Professor <strong>Martin Odersky<\/strong> won the <strong>Java Top Ambassador<\/strong> award at the <strong>JAX Conference 2011<\/strong>? I think as you might do that Java the programming language is now very mature and that it is getting long in the tooth. However, Java is still very important for open source libraries, because the vast majority of the framework and library landscape, out there, has been very built with Java the programming language. Therefore interoperability is going to be important, and whenever they get around to my favourite [fictional] <strong>JSR 555<\/strong>, which will standardise the interoperability between Java and Beyond Java, the holy grail of meta-object protocol, virtual classes, static and dynamic languages and the JVM byte code executor will be a momentous occasion in the history of the Java platform. However, I digress and pat myself down due my excitement.<\/p>\n<p>(Please start your favour MP3 player now on the track: <em>Holst \u2013 The Planets \u2013 \u201cJupiter\u201d. <\/em>You are going need some inspiration.)<\/p>\n<h2>Overall Project Summary<\/h2>\n<p>The task for this Java project was to retrieve stock quotes from <strong>Yahoo Financial Quotes<\/strong> services, store these quotes in a repository, and all prospective users to interrogate the repository for a quotes. If the quote does exist in the repository then the application should go the Yahoo web service and pull down the quote. If it is newer store it in the cache and then return the result to the user.<\/p>\n<h2>Project Requirement<\/h2>\n<p>The Java application stored the latest quote on a data store (so that, say, a banking risk manager department could compare quotes to some trade that may have been made by the user through some other system). The application displayed the equity stock quote (the average of bid and ask prices) to the user.<\/p>\n<p>The Java application was a prototype. The client envisioned Spring MVC and Hibernate as the web framework solution, which of course meant a relational database. The prototype was a single-user, and build with Apache Maven.<\/p>\n<h2>User Stories<\/h2>\n<p>For the original Java prototype, there were two user stories:<\/p>\n<p>S1 \u201cA trader wants to see the stock quote for a given ticker symbol so that she can buy and sell the relevant financial instrument at a good market price\u201d.<\/p>\n<h3>S1-Acceptance Criteria<\/h3>\n<p>A1-1 \u201cType in a Yahoo ticker symbol and within one second see the current price.\u00a0 The current price should be approximately equal to that available from a Google search\u201d<\/p>\n<p>A1-2 \u201cType in an invalid ticker symbol and within one second see an error message\u201d<\/p>\n<p>S2 \u201cA risk analyst wants to view a repository of ticker symbols together with the latest price in each case as last viewed by the stock system\u2019s user so that I can compare these to prices traded by the user on other systems.\u201d<\/p>\n<h3>S2-Acceptance Criteria<\/h3>\n<p>A2-1 \u201cFrom an empty data store, use the stock system to view ORCL and then RHT noting their current value.\u00a0 Then query the data store to ensure those values have been recorded.\u201d<\/p>\n<p>A2-2 \u201cWait till the Oracle price has changed (a quarter of an hour during NY trading hours 2:30PM to 9:05PM UK time should be sufficient) and then re-query ORCL noting the new price.\u00a0 Then re-query the data store to ensure that the value had been updated for ORCL and the RHT value is unchanged\u201d.<\/p>\n<h2>Original Java Interfaces<\/h2>\n<p>In order to port the prototype easy I started the Java interface and the unit tests.<\/p>\n<p>Here is a design-by-contract interface for a quote repository<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npackage uk.co.xenonique.stockquoteapp;\r\n\r\nimport java.util.List;\r\n\r\n\/**\r\n * A contract for a stock quote repository\r\n * @author Peter\r\n *\/\r\npublic interface QuoteRepository {\r\n\r\n\tpublic boolean isEmpty();\r\n\tpublic int size();\r\n\tpublic void clear();\r\n\tpublic void store( StockQuote quote );\r\n\tpublic StockQuote get( String symbol );\r\n\tpublic boolean contains( String symbol );\r\n\tpublic List&lt;String&gt; getSymbols();\r\n}\r\n<\/pre>\n<p>Here, with QuoteRepository, the contract is to store and retrieve a stock quote by a symbol. You can check if the repository is empty or not, how many quotes it stores and clear it out. You can enquire also if stock quote is part of the repository by symbols, and finally you can a list collection of stock exchange symbols. By inspection, this interface, looks to be an associative collection, a map type.<\/p>\n<p>Here is an implementation that uses a repository key value storage. Notice that I chose the ConcurrentHashMap to store the key value. Strictly, speaking it could have been a HashMap too, since the prototype was a single-user. Where have you seen a single-user system in existance if ever?<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npackage uk.co.xenonique.stockquoteapp;\r\n\r\nimport java.util.*;\r\nimport java.util.concurrent.*;;\r\n\r\n\/**\r\n * A key value store representation of the stock quote repository\r\n * @author Peter\r\n *\/\r\npublic class QuoteRepositoryKeyValueStore implements QuoteRepository {\r\n\r\n\tprivate Map&lt;String, StockQuote&gt; store = new ConcurrentHashMap&lt;String, StockQuote&gt;();\r\n\t\r\n\t@Override\r\n\tpublic void clear() {\r\n\t\tstore.clear();\r\n\t}\r\n\r\n\t@Override\r\n\tpublic boolean contains(String symbol) {\r\n\t\treturn store.containsKey(symbol);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic StockQuote get(String symbol) {\r\n\t\treturn store.get(symbol);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic boolean isEmpty() {\r\n\t\treturn store.isEmpty();\r\n\t}\r\n\r\n\t@Override\r\n\tpublic int size() {\r\n\t\treturn store.size();\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void store(StockQuote quote) {\r\n\t\tstore.put(quote.getSymbol(), quote);\r\n\t}\r\n\t\r\n\t@Override\r\n\tpublic List&lt;String&gt; getSymbols() {\r\n\t\tList&lt;String&gt; symbols = new ArrayList&lt;String&gt;();\r\n\t\tsymbols.addAll( store.keySet() );\r\n\t\tCollections.sort(symbols);\r\n\t\treturn symbols;\r\n\t}\r\n\r\n}\r\n\r\n<\/pre>\n<p>Here is interface for a quote retriever<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npackage uk.co.xenonique.stockquoteapp;\r\n\r\npublic interface QuoteRetriever {\r\n\tpublic StockQuote getStockQuote( String symbol );\r\n}\r\n<\/pre>\n<p>This is a contract to retrieve a stock quote from a system and return it the user.<br \/>\nHere is an implementation of it that talks to the Yahoo web service.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n\/**\r\n * \r\n *\/\r\npackage uk.co.xenonique.stockquoteapp;\r\n\r\nimport java.io.BufferedReader;\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\nimport java.io.InputStreamReader;\r\nimport java.net.HttpURLConnection;\r\nimport java.net.MalformedURLException;\r\nimport java.net.URL;\r\nimport java.util.StringTokenizer;\r\n\r\n\/**\r\n * Yahoo web site stock retriever\r\n * @author Peter\r\n *\/\r\npublic class QuoteRetrieverYahooImpl implements QuoteRetriever {\r\n\r\n\tpublic final static String TOKEN_SYMBOL=&quot;@SYMBOL@&quot;;\r\n\/\/\tprivate final static String URL_FRAGMENT=&quot;https:\/\/finance.yahoo.com\/d\/quotes.csv?s=@SYMBOL@&amp;f=sb2b3jk&quot;;\r\n\tprivate final static String DEFAULT_URL_FRAGMENT=&quot;https:\/\/finance.yahoo.com\/d\/quotes.csv?s=&quot;+TOKEN_SYMBOL+&quot;&amp;f=sb2b3&quot;;\r\n\t\r\n\tprivate String urlFragment = DEFAULT_URL_FRAGMENT; \r\n\r\n\t@Override\r\n\tpublic StockQuote getStockQuote(String symbol) {\r\n\t\tString queryUrl = urlFragment.replace(TOKEN_SYMBOL, symbol);\r\n\t\ttry {\r\n\t\t\tURL url = new URL( queryUrl );\r\n\t\t\tHttpURLConnection connection = (HttpURLConnection)url.openConnection();\r\n\t\t\tconnection.setRequestMethod(&quot;GET&quot;);\r\n\t\t\tconnection.connect();\r\n\r\n\t\t\tInputStream is = connection.getInputStream();\r\n\t\t\tBufferedReader reader = new BufferedReader( new InputStreamReader(is) );\r\n\t\t\t\r\n\t\t\ttry {\r\n\t\t\t\tString line = reader.readLine();\r\n\t\t\t\tif (  line != null ) {\r\n\/\/\t\t\t\t\tSystem.out.println(&quot;*DEBUG* : line=&quot;+line);\r\n\t\t\t\t\tString stockSymbol;\r\n\t\t\t\t\tString askPrice;\r\n\t\t\t\t\tString bidPrice;\r\n\t\t\t\t\tStringTokenizer stk = new StringTokenizer(line, &quot;,&quot;);\r\n\t\t\t\t\tint countTokens = stk.countTokens();\r\n\t\t\t\t\tif ( countTokens &lt; 3 ) {\r\n\t\t\t\t\t\tthrow new DataRetrievalException(&quot;Data service at URL=[&quot;+queryUrl+&quot;] does not supply enough fields (3 != &quot;+countTokens+&quot;)&quot;);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tstockSymbol = stk.nextToken();\r\n\t\t\t\t\tif ( stockSymbol.length() &gt; 0 &amp;&amp;\r\n\t\t\t\t\t\t\tstockSymbol.charAt(0) == '&quot;' &amp;&amp; stockSymbol.charAt(stockSymbol.length()-1) == '&quot;') {\r\n\t\t\t\t\t\tstockSymbol = stockSymbol.substring(1, stockSymbol.length()-1 );\r\n\t\t\t\t\t}\r\n\t\t\t\t\taskPrice = stk.nextToken();\r\n\t\t\t\t\tif ( &quot;N\/A&quot;.equals(askPrice)) {\r\n\t\t\t\t\t\tthrow new UnknownStockSymbolException(&quot;Unknown stock quote symbol [&quot;+stockSymbol+&quot;] price not available&quot;);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbidPrice = stk.nextToken();\r\n\t\t\t\t\tif ( &quot;N\/A&quot;.equals(bidPrice)) {\r\n\t\t\t\t\t\tthrow new UnknownStockSymbolException(&quot;Unknown stock quote symbol [&quot;+stockSymbol+&quot;] price not available&quot;);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t\treturn new StockQuote(stockSymbol, askPrice, bidPrice);\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tthrow new DataRetrievalException(&quot;Data unavailable from quote service URL=[&quot;+queryUrl+&quot;]&quot;);\r\n\t\t\t\t}\r\n\t\t\t} \r\n\t\t\tfinally  {\r\n\t\t\t\tif ( reader != null) {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\treader.close();\r\n\t\t\t\t\t} catch (Exception e) {\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif ( is != null) {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tis.close();\r\n\t\t\t\t\t} catch (Exception e) {\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} \r\n\t\tcatch (MalformedURLException e) {\r\n\t\t\tthrow new ConnectionException(&quot;unable to connect to the remote quote service URL=[&quot;+queryUrl+&quot;]&quot;, e);\r\n\t\t}\r\n\t\tcatch (IOException e) {\r\n\t\t\tthrow new ConnectionException(&quot;I\/O failure reading service URL=[&quot;+queryUrl+&quot;]&quot;, e);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic String getUrlFragment() {\r\n\t\treturn urlFragment;\r\n\t}\r\n\r\n\tpublic void setUrlFragment(String urlFragment) {\r\n\t\tthis.urlFragment = urlFragment;\r\n\t}\r\n}\r\n<\/pre>\n<p>This is all very straight forward Java Networking that you all should know and love by now.<\/p>\n<p>Here is the equity stock quote data class<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npackage uk.co.xenonique.stockquoteapp;\r\n\r\nimport java.math.BigDecimal;\r\nimport java.math.RoundingMode;\r\n\r\npublic class StockQuote {\r\n\tprivate final String symbol;\r\n\tprivate final BigDecimal askPrice;\r\n\tprivate final BigDecimal bidPrice;\r\n\tprivate final BigDecimal meanPrice;\r\n\r\n\tprivate final static BigDecimal TWO= new BigDecimal(&quot;2.0&quot;);\r\n\t\r\n\tpublic StockQuote(String symbol, String askPrice, String bidPrice) {\r\n\t\tthis( symbol, new BigDecimal(askPrice), new BigDecimal(bidPrice));\r\n\t}\r\n\r\n\tpublic StockQuote(String symbol, BigDecimal askPrice, BigDecimal bidPrice) {\r\n\t\tthis.symbol = symbol;\r\n\t\tthis.askPrice = askPrice.setScale(2);\r\n\t\tthis.bidPrice = bidPrice.setScale(2);\r\n\t\tthis.meanPrice = calcMeanPrice(askPrice, bidPrice);\r\n\t}\r\n\r\n\t\/**\r\n\t * Copy constructor \r\n\t * @param ref the reference\r\n\t *\/\r\n\tpublic StockQuote(StockQuote ref) {\r\n\t\tthis.symbol = ref.symbol;\r\n\t\tthis.askPrice = ref.askPrice.setScale(2);\r\n\t\tthis.bidPrice = ref.bidPrice.setScale(2);\r\n\t\tthis.meanPrice = bidPrice.add( askPrice.subtract(bidPrice).divide( TWO ) );\r\n\t}\r\n\r\n\tprivate BigDecimal calcMeanPrice(BigDecimal askPrice, BigDecimal bidPrice) {\r\n\t\treturn bidPrice.add( askPrice.subtract(bidPrice).divide( TWO ) ).setScale(2, RoundingMode.DOWN );\r\n\t}\r\n\r\n\tpublic String getSymbol() {\r\n\t\treturn symbol;\r\n\t}\r\n\r\n\tpublic BigDecimal getAskPrice() {\r\n\t\treturn askPrice;\r\n\t}\r\n\r\n\tpublic BigDecimal getBidPrice() {\r\n\t\treturn bidPrice;\r\n\t}\r\n\t\r\n\tpublic BigDecimal getMeanPrice() {\r\n\t\treturn meanPrice;\r\n\t}\r\n\t\r\n\t@Override\r\n\tpublic int hashCode() {\r\n\t\tfinal int prime = 31;\r\n\t\tint result = 1;\r\n\t\tresult = prime * result\r\n\t\t\t\t+ ((askPrice == null) ? 0 : askPrice.hashCode());\r\n\t\tresult = prime * result\r\n\t\t\t\t+ ((bidPrice == null) ? 0 : bidPrice.hashCode());\r\n\t\tresult = prime * result + ((symbol == null) ? 0 : symbol.hashCode());\r\n\t\treturn result;\r\n\t}\r\n\r\n\t@Override\r\n\tpublic boolean equals(Object obj) {\r\n\t\tif (this == obj)\r\n\t\t\treturn true;\r\n\t\tif (obj == null)\r\n\t\t\treturn false;\r\n\t\tif (getClass() != obj.getClass())\r\n\t\t\treturn false;\r\n\t\tStockQuote other = (StockQuote) obj;\r\n\t\tif (askPrice == null) {\r\n\t\t\tif (other.askPrice != null)\r\n\t\t\t\treturn false;\r\n\t\t} else if (!askPrice.equals(other.askPrice))\r\n\t\t\treturn false;\r\n\t\tif (bidPrice == null) {\r\n\t\t\tif (other.bidPrice != null)\r\n\t\t\t\treturn false;\r\n\t\t} else if (!bidPrice.equals(other.bidPrice))\r\n\t\t\treturn false;\r\n\t\tif (symbol == null) {\r\n\t\t\tif (other.symbol != null)\r\n\t\t\t\treturn false;\r\n\t\t} else if (!symbol.equals(other.symbol))\r\n\t\t\treturn false;\r\n\t\treturn true;\r\n\t}\r\n\r\n\t@Override\r\n\tpublic String toString() {\r\n\t\treturn &quot;StockQuote [ symbol=&quot; + symbol +&quot;, askPrice=&quot; + askPrice + \r\n\t\t&quot;, bidPrice=&quot; + bidPrice + &quot;, meanPrice=&quot;+meanPrice+&quot;]&quot;;\r\n\t}\r\n}\r\n<\/pre>\n<p>I need you to notice that it is an immutable object class. It is a stock quote that aggregates the symbol, ask and bid prices together. It borrows from C++ with a copy constructor, it has the hashCode() and equals() and a toString().<\/p>\n<p>Finally, lets look at a unit test that ties it all together<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npackage uk.co.xenonique.stockquoteapp;\r\n\r\nimport org.junit.*;\r\nimport static org.junit.Assert.*;\r\n\r\npublic class QuoteRetrieverYahooTest \r\n{\r\n    @BeforeClass \r\n    public static void loadProxySettings()\r\n    {\r\n        StockQuoteApp.applyConnectionPropertiesFile();\r\n    }\r\n\r\n    @Test\r\n    public void shouldRetrieveStockQuote()\r\n    {\r\n        QuoteRetriever retriever = new QuoteRetrieverYahooImpl();\r\n        StockQuote quote = retriever.getStockQuote(&quot;ORCL&quot;);\r\n        assertNotNull(quote);\r\n        assertEquals(&quot;ORCL&quot;, quote.getSymbol());\r\n        assertNotNull( quote.getAskPrice());\r\n        assertNotNull( quote.getBidPrice());\r\n        assertNotNull( quote.getMeanPrice());\t\t\r\n    }\r\n\r\n    @Test(expected=UnknownStockSymbolException.class)\r\n    public void shouldRaiseErrorWithUnknownStockSymbol()\r\n    {\r\n        QuoteRetriever retriever = new QuoteRetrieverYahooImpl();\r\n        retriever.getStockQuote(&quot;UNKNOWN&quot;);\r\n    }\r\n\r\n    @Test(expected=ConnectionException.class)\r\n    public void shouldRaiseConnectionFailure()\r\n    {\r\n            QuoteRetrieverYahooImpl retriever = new QuoteRetrieverYahooImpl();\r\n        retriever.setUrlFragment(&quot;https:\/\/foo.finance.yahoo.com\/&quot;+QuoteRetrieverYahooImpl.TOKEN_SYMBOL);\r\n        retriever.getStockQuote(&quot;MFST&quot;);\r\n    }\r\n}\r\n<\/pre>\n<p>There is another unit test to verify the operation of the key value repository. <\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\npackage uk.co.xenonique.stockquoteapp;\r\n\r\nimport java.util.List;\r\n\r\nimport org.junit.*;\r\nimport static org.junit.Assert.*;\r\n\r\npublic class QuoteRepositoryKeyValueTest {\r\n\t\r\n\t@Test\r\n\tpublic void shouldInitialiseWell() {\r\n\t\tQuoteRepository store = new QuoteRepositoryKeyValueStore();\r\n\t\tassertTrue(store.isEmpty());\r\n\t\tassertEquals(0,store.size());\r\n\t}\r\n\r\n\t@Test\r\n\tpublic void shouldStoreAndRetrieve() {\r\n\t\tQuoteRepository store = new QuoteRepositoryKeyValueStore();\r\n\t\tStockQuote expected1 = new StockQuote(&quot;PILGRIM&quot;, &quot;123.45&quot;, &quot;123.12&quot; );\r\n\t\t\/\/ Exercise the copy constructor in order to verify the store is not just using object references!\r\n\t\tstore.store(new StockQuote(expected1));\r\n\t\tassertFalse(store.isEmpty());\r\n\t\tassertEquals(1,store.size());\r\n\t\t\r\n\t\tassertEquals( expected1, store.get(&quot;PILGRIM&quot;));\r\n\t\t\/\/ Put an updated stock quote in the repository with same symbol for good measure\r\n\t\tStockQuote expected2 = new StockQuote(&quot;PILGRIM&quot;, &quot;555.55&quot;, &quot;555.12&quot; );\r\n\t\tstore.store(expected2);\t\t\r\n\t\tassertFalse(store.isEmpty());\r\n\t\tassertEquals(1,store.size());\r\n\t\t\r\n\t\t\/\/ The quote inside the store is not equal to the old stock quote \r\n\t\tassertNotSame( expected1, store.get(&quot;PILGRIM&quot;));\r\n\t\t\/\/ The quote inside the store is equal to the new stock quote \r\n\t\tassertEquals( expected2, store.get(&quot;PILGRIM&quot;));\r\n\t}\r\n\t\r\n\t@Test\r\n\tpublic void shouldStoreAndRetrieveMultipleQuotes() {\r\n\t\tQuoteRepository store = new QuoteRepositoryKeyValueStore();\r\n\t\tassertTrue(store.isEmpty());\r\n\t\tassertEquals(0,store.size());\r\n\t\t\r\n\t\tStockQuote quotes[] = new StockQuote[] {\r\n\t\t\t\tnew StockQuote( &quot;LYG&quot;, &quot;4.020&quot;, &quot;4.015&quot; ),\r\n\t\t\t\tnew StockQuote( &quot;RBS.L&quot;, &quot;39.58&quot;, &quot;39.48&quot; ),\r\n\t\t\t\tnew StockQuote( &quot;HSBC.L&quot;, &quot;646.65&quot;, &quot;646.62&quot; ),\r\n\t\t\t\tnew StockQuote( &quot;ORCL&quot;, &quot;27.75&quot;, &quot;27.74&quot; ),\r\n\t\t};\r\n\t\t\r\n\t\tfor (StockQuote quote: quotes) {\r\n\t\t\tstore.store(quote);\r\n\t\t}\r\n\t\t\r\n\t\tassertEquals( quotes.length, store.size());\r\n\t\tassertFalse(store.isEmpty());\r\n\r\n\t\tfor (StockQuote quote: quotes) {\r\n\t\t\tassertTrue( store.contains(quote.getSymbol()));\r\n\t\t\tassertEquals( quote, store.get(quote.getSymbol()));\r\n\t\t}\r\n\t\t\r\n\t\tList&lt;String&gt; symbols = store.getSymbols();\r\n\t\tassertEquals( quotes.length, symbols.size());\r\n\t\tfor (StockQuote quote: quotes) {\r\n\t\t\tassertTrue( symbols.contains(quote.getSymbol()));\r\n\t\t}\r\n\t\t\r\n\t\tstore.clear();\t\t\r\n\t\tassertTrue(store.isEmpty());\r\n\t\tassertEquals(0,store.size());\t\t\r\n\t}\r\n}\r\n<\/pre>\n<p>These were the essential parts of the Stock Quote application written in Java. I have left some notable bits and bobs, such the exceptions, and also the main program. You can treat it as an exercise-for-the-reader to tie it all together. I will publish the Java main program later on. <\/p>\n<p>The static method call StockQuoteApp.applyConnectionPropertiesFile() is a method, that initialised the Java system properties with a configuration that allowed the application to work behind a company Internet proxy. The properties file looks like this:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n# File: ``Connection.properties''\r\n# ==========================================\r\n# Uncomment and set the proxy gateway for your environment\r\n#\r\n# Uncomment this line to use a Internet Proxy\r\nhttp.proxySet=true\r\n# Define the proxy hostmachine e.g. gateway.declan.server1\r\nhttp.proxyHost=webcacge.proxyhost.mydomain.com\r\n# Define the port number of the proxy e.g. 8080\r\nhttp.proxyPort=8080\r\n# Define the login name \r\nhttp.proxyUser=PILG1472\r\n# Define the password\r\nhttp.proxyPassword=PILGPASS\r\n# Define the non proxy hosts\r\nhttp.nonProxyHosts=otcdev57,otcdev1287,otcdev1244\r\n# End\r\n<\/pre>\n<p>Next time. I will describe how I <strong>Scalafied<\/strong> these classes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Here follows in these series of three article is a description of Scala application that ported from Java. I would prefer to call this work a \u201cScalafication\u201d. Many people are thinking about Scala Adoption as it gets important interest from the wider community. Did you know that Professor Martin Odersky won the Java Top Ambassador [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[50,44,40,6,98,99],"tags":[],"_links":{"self":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts\/371"}],"collection":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=371"}],"version-history":[{"count":7,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts\/371\/revisions"}],"predecessor-version":[{"id":379,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts\/371\/revisions\/379"}],"wp:attachment":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=371"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=371"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=371"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}