You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ja...@apache.org on 2012/03/29 21:14:07 UTC

svn commit: r1307063 - in /lucene/dev/trunk/solr: ./ core/src/java/org/apache/solr/schema/ core/src/test-files/solr/conf/ core/src/test/org/apache/solr/cloud/ core/src/test/org/apache/solr/schema/ example/solr/conf/

Author: janhoy
Date: Thu Mar 29 19:14:07 2012
New Revision: 1307063

URL: http://svn.apache.org/viewvc?rev=1307063&view=rev
Log:
SOLR-3255: OpenExchangeRates.Org Exchange Rate Provider and improved ExchangeRateProvider interface

Added:
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/OpenExchangeRatesOrgProvider.java   (with props)
    lucene/dev/trunk/solr/core/src/test-files/solr/conf/open-exchange-rates.json
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/OpenExchangeRatesOrgProviderTest.java   (with props)
Modified:
    lucene/dev/trunk/solr/CHANGES.txt
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/CurrencyField.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/ExchangeRateProvider.java
    lucene/dev/trunk/solr/core/src/test-files/solr/conf/schema.xml
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/AbstractZkTestCase.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/MockExchangeRateProvider.java
    lucene/dev/trunk/solr/example/solr/conf/schema.xml

Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1307063&r1=1307062&r2=1307063&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Thu Mar 29 19:14:07 2012
@@ -581,6 +581,8 @@ New Features
 * SOLR-2202: Currency FieldType, whith support for currencies and exchange rates
   (Greg Fodor & Andrew Morrison via janhoy, rmuir, Uwe Schindler)
 
+* SOLR-3255: OpenExchangeRates.Org Exchange Rate Provider for CurrencyField (janhoy)
+
 * SOLR-3026: eDismax: Locking down which fields can be explicitly queried (user fields aka uf)
   (janhoy, hossmann, Tomás Fernández Löbbe)
 

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/CurrencyField.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/CurrencyField.java?rev=1307063&r1=1307062&r2=1307063&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/CurrencyField.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/CurrencyField.java Thu Mar 29 19:14:07 2012
@@ -47,11 +47,11 @@ import javax.xml.xpath.XPathExpressionEx
 import javax.xml.xpath.XPathFactory;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.ArrayList;
 import java.util.Currency;
 import java.util.HashMap;
-import java.util.List;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Field type for support of monetary values.
@@ -62,7 +62,7 @@ public class CurrencyField extends Field
   protected static final String PARAM_DEFAULT_CURRENCY      = "defaultCurrency";
   protected static final String PARAM_RATE_PROVIDER_CLASS   = "providerClass";
   protected static final Object PARAM_PRECISION_STEP        = "precisionStep";
-  protected static final String DEFAULT_RATE_PROVIDER_CLASS = "org.apache.solr.schema.FileExchangeRateProvider";
+  protected static final String DEFAULT_RATE_PROVIDER_CLASS = "solr.FileExchangeRateProvider";
   protected static final String DEFAULT_DEFAULT_CURRENCY    = "USD";
   protected static final String DEFAULT_PRECISION_STEP      = "0";
   protected static final String FIELD_SUFFIX_AMOUNT_RAW     = "_amount_raw";
@@ -117,8 +117,7 @@ public class CurrencyField extends Field
     args.remove(PARAM_PRECISION_STEP);
 
     try {
-      // TODO: Are we using correct classloader?
-      Class<?> c = Class.forName(exchangeRateProviderClass);
+      Class<?> c = schema.getResourceLoader().findClass(exchangeRateProviderClass);
       Object clazz = c.newInstance();
       if (clazz instanceof ExchangeRateProvider) {
         provider = (ExchangeRateProvider) clazz;
@@ -512,14 +511,15 @@ class FileExchangeRateProvider implement
   }
 
   @Override
-  public String[] listAvailableCurrencies() {
-    List<String> pairs = new ArrayList<String>();
+  public Set<String> listAvailableCurrencies() {
+    Set<String> currencies = new HashSet<String>();
     for(String from : rates.keySet()) {
+      currencies.add(from);
       for(String to : rates.get(from).keySet()) {
-        pairs.add(from+","+to);
+        currencies.add(to);
       }
     }
-    return pairs.toArray(new String[1]);
+    return currencies;
   }
 
   @Override

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/ExchangeRateProvider.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/ExchangeRateProvider.java?rev=1307063&r1=1307062&r2=1307063&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/ExchangeRateProvider.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/ExchangeRateProvider.java Thu Mar 29 19:14:07 2012
@@ -17,6 +17,7 @@ package org.apache.solr.schema;
  */
 
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.solr.common.ResourceLoader;
 import org.apache.solr.common.SolrException;
@@ -35,11 +36,10 @@ public interface ExchangeRateProvider {
   public double getExchangeRate(String sourceCurrencyCode, String targetCurrencyCode) throws SolrException;
   
   /**
-   * List all configured currency code pairs
-   * @return a string array of <a href="http://en.wikipedia.org/wiki/ISO_4217">ISO 4217</a> currency codes on the format
-   * ["SRC,DST", "SRC,DST"...]
+   * List all configured currency codes which are valid as source/target for this Provider
+   * @return a Set of <a href="http://en.wikipedia.org/wiki/ISO_4217">ISO 4217</a> currency code strings
    */
-  public String[] listAvailableCurrencies();
+  public Set<String> listAvailableCurrencies();
 
   /**
    * Ask the currency provider to explicitly reload/refresh its configuration.

Added: lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/OpenExchangeRatesOrgProvider.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/OpenExchangeRatesOrgProvider.java?rev=1307063&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/OpenExchangeRatesOrgProvider.java (added)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/OpenExchangeRatesOrgProvider.java Thu Mar 29 19:14:07 2012
@@ -0,0 +1,257 @@
+package org.apache.solr.schema;
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.noggit.JSONParser;
+import org.apache.solr.common.ResourceLoader;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Exchange Rates Provider for {@link CurrencyField} implementing the freely available
+ * exchange rates from openexchangerates.org
+ * <p/>
+ * <b>Disclaimer:</b> This data is collected from various providers and provided free of charge
+ * for informational purposes only, with no guarantee whatsoever of accuracy, validity,
+ * availability or fitness for any purpose; use at your own risk. Other than that - have
+ * fun, and please share/watch/fork if you think data like this should be free!
+ */
+public class OpenExchangeRatesOrgProvider implements ExchangeRateProvider {
+  public static Logger log = LoggerFactory.getLogger(OpenExchangeRatesOrgProvider.class);
+  protected static final String PARAM_RATES_FILE_LOCATION   = "ratesFileLocation";
+  protected static final String PARAM_REFRESH_INTERVAL      = "refreshInterval";
+  protected static final String DEFAULT_RATES_FILE_LOCATION = "http://openexchangerates.org/latest.json";
+  protected static final String DEFAULT_REFRESH_INTERVAL    = "1440";
+  
+  protected String ratesFileLocation;
+  protected int refreshInterval;
+  protected ResourceLoader resourceLoader;
+  
+  protected OpenExchangeRates rates;
+
+  /**
+   * Returns the currently known exchange rate between two currencies. The rates are fetched from
+   * the freely available OpenExchangeRates.org JSON, hourly updated. All rates are symmetrical with
+   * base currency being USD by default.
+   *
+   * @param sourceCurrencyCode The source currency being converted from.
+   * @param targetCurrencyCode The target currency being converted to.
+   * @return The exchange rate.
+   * @throws an exception if the requested currency pair cannot be found 
+   */
+  public double getExchangeRate(String sourceCurrencyCode, String targetCurrencyCode) {
+    if (rates == null) {
+      throw new SolrException(SolrException.ErrorCode.SERVICE_UNAVAILABLE, "Rates not initialized.");
+    }
+      
+    if (sourceCurrencyCode == null || targetCurrencyCode == null) {
+      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Cannot get exchange rate; currency was null.");
+    }
+    
+    if (rates.getTimestamp() + refreshInterval*60*1000 > System.currentTimeMillis()) {
+      log.debug("Refresh interval has expired. Refreshing exchange rates.");
+      reload();
+    }
+    
+    Double source = (Double) rates.getRates().get(sourceCurrencyCode);
+    Double target = (Double) rates.getRates().get(targetCurrencyCode);
+
+    if (source == null || target == null) {
+      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, 
+          "No available conversion rate from " + sourceCurrencyCode + " to " + targetCurrencyCode + ". "
+          + "Available rates are "+listAvailableCurrencies());
+    }
+    
+    return target / source;  
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    OpenExchangeRatesOrgProvider that = (OpenExchangeRatesOrgProvider) o;
+
+    return !(rates != null ? !rates.equals(that.rates) : that.rates != null);
+  }
+
+  @Override
+  public int hashCode() {
+    return rates != null ? rates.hashCode() : 0;
+  }
+
+  public String toString() {
+    return "["+this.getClass().getName()+" : " + rates.getRates().size() + " rates.]";
+  }
+
+  @Override
+  public Set<String> listAvailableCurrencies() {
+    if (rates == null)
+      throw new SolrException(ErrorCode.SERVER_ERROR, "Rates not initialized");
+    return rates.getRates().keySet();
+  }
+
+  @Override
+  public boolean reload() throws SolrException {
+    InputStream ratesJsonStream = null;
+    try {
+      log.info("Reloading exchange rates from "+ratesFileLocation);
+      try {
+        ratesJsonStream = (new URL(ratesFileLocation)).openStream();
+      } catch (Exception e) {
+        ratesJsonStream = resourceLoader.openResource(ratesFileLocation);
+      }
+        
+      rates = new OpenExchangeRates(ratesJsonStream);
+      return true;
+    } catch (Exception e) {
+      throw new SolrException(ErrorCode.SERVER_ERROR, "Error reloading exchange rates", e);
+    } finally {
+      if (ratesJsonStream != null) try {
+        ratesJsonStream.close();
+      } catch (IOException e) {
+        throw new SolrException(ErrorCode.SERVER_ERROR, "Error closing stream", e);
+      }
+    }
+  }
+
+  @Override
+  public void init(Map<String,String> params) throws SolrException {
+    try {
+      ratesFileLocation = getParam(params.get(PARAM_RATES_FILE_LOCATION), DEFAULT_RATES_FILE_LOCATION);
+      refreshInterval = Integer.parseInt(getParam(params.get(PARAM_REFRESH_INTERVAL), DEFAULT_REFRESH_INTERVAL));
+      // Force a refresh interval of minimum one hour, since the API does not offer better resolution
+      if (refreshInterval < 60) {
+        refreshInterval = 60;
+        log.warn("Specified refreshInterval was too small. Setting to 60 minutes which is the update rate of openexchangerates.org");
+      }
+      log.info("Initialized with rates="+ratesFileLocation+", refreshInterval="+refreshInterval+".");
+    } catch (Exception e) {
+      throw new SolrException(ErrorCode.BAD_REQUEST, "Error initializing", e);
+    } finally {
+      // Removing config params custom to us
+      params.remove(PARAM_RATES_FILE_LOCATION);
+      params.remove(PARAM_REFRESH_INTERVAL);
+    }
+  }
+
+  @Override
+  public void inform(ResourceLoader loader) throws SolrException {
+    resourceLoader = loader;
+    reload();
+  }
+  
+  private String getParam(String param, String defaultParam) {
+    return param == null ? defaultParam : param;
+  }
+  
+  /**
+   * A simple class encapsulating the JSON data from openexchangerates.org
+   */
+  class OpenExchangeRates {
+    private Map<String, Double> rates;
+    private String baseCurrency;
+    private long timestamp;
+    private String disclaimer;
+    private String license;
+    private JSONParser parser;
+    
+    public OpenExchangeRates(InputStream ratesStream) throws IOException {
+      parser = new JSONParser(new InputStreamReader(ratesStream));
+      rates = new HashMap<String, Double>();
+      
+      int ev;
+      do {
+        ev = parser.nextEvent();
+        switch( ev ) {
+          case JSONParser.STRING:
+            if( parser.wasKey() ) {
+              String key = parser.getString();
+              if(key.equals("disclaimer")) {
+                parser.nextEvent();
+                disclaimer = parser.getString();
+              } else if(key.equals("license")) {
+                parser.nextEvent();
+                license = parser.getString();
+              } else if(key.equals("timestamp")) {
+                parser.nextEvent();
+                timestamp = parser.getLong();
+              } else if(key.equals("base")) {
+                parser.nextEvent();
+                baseCurrency = parser.getString();
+              } else if(key.equals("rates")) {
+                ev = parser.nextEvent();
+                assert(ev == JSONParser.OBJECT_START);
+                ev = parser.nextEvent();
+                while (ev != JSONParser.OBJECT_END) {
+                  String curr = parser.getString();
+                  ev = parser.nextEvent();
+                  Double rate = parser.getDouble();
+                  rates.put(curr, rate);
+                  ev = parser.nextEvent();                  
+                }
+              } else {
+                log.warn("Unknown key "+key);
+              }
+              break;
+            } else {
+              log.warn("Expected key, got "+JSONParser.getEventString(ev));
+              break;
+            }
+             
+          case JSONParser.OBJECT_END:
+          case JSONParser.OBJECT_START:
+            break;
+
+          default:
+            log.info("Noggit UNKNOWN_EVENT_ID:"+JSONParser.getEventString(ev));
+            break;
+        }
+      } while( ev != JSONParser.EOF);
+    }
+
+    public Map<String, Double> getRates() {
+      return rates;
+    }
+    
+    public long getTimestamp() {
+      return timestamp;
+    }
+
+    public String getDisclaimer() {
+      return disclaimer;
+    }
+
+    public String getBaseCurrency() {
+      return baseCurrency;
+    }
+
+    public String getLicense() {
+      return license;
+    }
+  }
+}

Added: lucene/dev/trunk/solr/core/src/test-files/solr/conf/open-exchange-rates.json
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test-files/solr/conf/open-exchange-rates.json?rev=1307063&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/test-files/solr/conf/open-exchange-rates.json (added)
+++ lucene/dev/trunk/solr/core/src/test-files/solr/conf/open-exchange-rates.json Thu Mar 29 19:14:07 2012
@@ -0,0 +1,167 @@
+{
+  "disclaimer": "This data is collected from various providers and provided free of charge for informational purposes only, with no guarantee whatsoever of accuracy, validity, availability or fitness for any purpose; use at your own risk. Other than that - have fun, and please share/watch/fork if you think data like this should be free!",
+  "license": "Data collected from various providers with public-facing APIs; copyright may apply; not for resale; no warranties given.",
+  "timestamp": 1332070464,
+  "base": "USD",
+  "rates": {
+    "AED": 3.6732,
+    "AFN": 48.299999,
+    "ALL": 105.919998,
+    "AMD": 388.890015,
+    "ANG": 1.79,
+    "AOA": 94.769997,
+    "ARS": 4.35,
+    "AUD": 0.943931,
+    "AWG": 1.7899,
+    "AZN": 0.7863,
+    "BAM": 1.48775,
+    "BBD": 2,
+    "BDT": 82,
+    "BGN": 1.4962,
+    "BHD": 0.37703,
+    "BIF": 1304.170044,
+    "BMD": 1,
+    "BND": 1.2575,
+    "BOB": 6.91,
+    "BRL": 1.8003,
+    "BSD": 1,
+    "BTN": 50.185001,
+    "BWP": 7.2307,
+    "BYR": 8150,
+    "BZD": 1.9135,
+    "CAD": 0.9921,
+    "CDF": 917.276917,
+    "CHF": 0.9164,
+    "CLF": 0.02146,
+    "CLP": 482.75,
+    "CNY": 6.3239,
+    "COP": 1760,
+    "CRC": 507.600006,
+    "CUP": 1,
+    "CVE": 84.190002,
+    "CZK": 18.606001,
+    "DJF": 179.490005,
+    "DKK": 5.64424,
+    "DOP": 39.025002,
+    "DZD": 74.544998,
+    "EGP": 6.0385,
+    "ETB": 17.720449,
+    "EUR": 0.758956,
+    "FJD": 1.7734,
+    "FKP": 0.6316,
+    "GBP": 0.631373,
+    "GEL": 1.6469,
+    "GHS": 1.7455,
+    "GIP": 0.63165,
+    "GMD": 31.5,
+    "GNF": 7100,
+    "GTQ": 7.6975,
+    "GYD": 203.699997,
+    "HKD": 7.76306,
+    "HNL": 19.055,
+    "HRK": 5.7333,
+    "HTG": 41,
+    "HUF": 219.850006,
+    "IDR": 9118,
+    "IEP": 0.5978,
+    "ILS": 3.7542,
+    "INR": 50.165001,
+    "IQD": 1165.5,
+    "IRR": 12308,
+    "ISK": 127.440002,
+    "JMD": 86.699997,
+    "JOD": 0.7095,
+    "JPY": 83.445,
+    "KES": 83.18,
+    "KGS": 46.699402,
+    "KHR": 4010.300049,
+    "KMF": 373.424255,
+    "KPW": 900,
+    "KRW": 1125.849976,
+    "KWD": 0.27925,
+    "KZT": 147.690002,
+    "LAK": 7993.799805,
+    "LBP": 1504,
+    "LKR": 125.224998,
+    "LRD": 73.459999,
+    "LSL": 7.5768,
+    "LTL": 2.6219,
+    "LVL": 0.5291,
+    "LYD": 1.2572,
+    "MAD": 8.4611,
+    "MDL": 11.89,
+    "MGA": 2155,
+    "MKD": 46.705002,
+    "MMK": 6.51,
+    "MNT": 1322.5,
+    "MOP": 7.9958,
+    "MRO": 293,
+    "MUR": 29.110001,
+    "MVR": 15.36,
+    "MWK": 165.206207,
+    "MXN": 12.6745,
+    "MYR": 3.0575,
+    "MZN": 27.200001,
+    "NAD": 7.58,
+    "NGN": 157.600006,
+    "NIO": 23.215,
+    "NOK": 5.73163,
+    "NPR": 80.620003,
+    "NZD": 1.212269,
+    "OMR": 0.38485,
+    "PAB": 1,
+    "PEN": 2.674,
+    "PGK": 2.0627,
+    "PHP": 43.02,
+    "PKR": 90.800003,
+    "PLN": 3.1285,
+    "PYG": 4245,
+    "QAR": 3.6415,
+    "RON": 3.3256,
+    "RSD": 84.100502,
+    "RUB": 29.2342,
+    "RWF": 606.717468,
+    "SAR": 3.7505,
+    "SBD": 7.075973,
+    "SCR": 14.0447,
+    "SDG": 2.6765,
+    "SEK": 6.74525,
+    "SGD": 1.258,
+    "SHP": 0.63165,
+    "SLL": 4364.5,
+    "SOS": 1629,
+    "SRD": 3.2875,
+    "STD": 18650,
+    "SVC": 8.7475,
+    "SYP": 57.450001,
+    "SZL": 7.5752,
+    "THB": 30.700001,
+    "TJS": 4.7588,
+    "TMT": 2.85,
+    "TND": 1.5178,
+    "TOP": 1.693601,
+    "TRY": 1.796,
+    "TTD": 6.40015,
+    "TWD": 29.532,
+    "TZS": 1595,
+    "UAH": 8.029,
+    "UGX": 2481.699951,
+    "USD": 1,
+    "UYU": 19.469999,
+    "UZS": 1835.75,
+    "VEF": 4.295,
+    "VND": 20820,
+    "VUV": 90.199997,
+    "WST": 2.247475,
+    "XAF": 497.898987,
+    "XCD": 2.7,
+    "XDR": 0.652794,
+    "XOF": 498.399994,
+    "XPF": 90.639999,
+    "YER": 216.005005,
+    "ZAR": 7.5688,
+    "ZMK": 5271.5,
+    "ZWD": 378.700012,
+    "ZWL": 322.355011
+  }
+}
\ No newline at end of file

Modified: lucene/dev/trunk/solr/core/src/test-files/solr/conf/schema.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test-files/solr/conf/schema.xml?rev=1307063&r1=1307062&r2=1307063&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test-files/solr/conf/schema.xml (original)
+++ lucene/dev/trunk/solr/core/src/test-files/solr/conf/schema.xml Thu Mar 29 19:14:07 2012
@@ -396,7 +396,10 @@
 
   <!-- Currency type -->
   <fieldType name="currency" class="solr.CurrencyField" currencyConfig="currency.xml"/>
-  <fieldType name="mock_currency" class="solr.CurrencyField" providerClass="org.apache.solr.schema.MockExchangeRateProvider" foo="bar" />
+  <fieldType name="mock_currency" class="solr.CurrencyField" providerClass="solr.MockExchangeRateProvider" foo="bar" />
+  <fieldType name="openexchangeratesorg_currency" class="solr.CurrencyField" 
+             providerClass="solr.OpenExchangeRatesOrgProvider"
+             ratesFileLocation="open-exchange-rates.json" />
 
   <!--  some per-field similarity examples -->
   

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/AbstractZkTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/AbstractZkTestCase.java?rev=1307063&r1=1307062&r2=1307063&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/AbstractZkTestCase.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/AbstractZkTestCase.java Thu Mar 29 19:14:07 2012
@@ -91,6 +91,7 @@ public abstract class AbstractZkTestCase
     putConfig(zkClient, "stopwords.txt");
     putConfig(zkClient, "protwords.txt");
     putConfig(zkClient, "currency.xml");
+    putConfig(zkClient, "open-exchange-rates.json");
     putConfig(zkClient, "mapping-ISOLatin1Accent.txt");
     putConfig(zkClient, "old_synonyms.txt");
     putConfig(zkClient, "synonyms.txt");

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTest.java?rev=1307063&r1=1307062&r2=1307063&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTest.java Thu Mar 29 19:14:07 2012
@@ -23,8 +23,8 @@ import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
 
-import java.util.Arrays;
 import java.util.Random;
+import java.util.Set;
 
 /**
  * Tests currency field type.
@@ -86,13 +86,27 @@ public class CurrencyFieldTest extends S
     
     // A few tests on the provider directly
     ExchangeRateProvider p = ((CurrencyField) tmp).getProvider();
-    String[] available = p.listAvailableCurrencies();
-    assert(available.length == 5);
+    Set<String> availableCurrencies = p.listAvailableCurrencies();
+    assert(availableCurrencies.size() == 4);
     assert(p.reload() == true);
     assert(p.getExchangeRate("USD", "EUR") == 2.5);
   }
 
   @Test
+  public void testMockExchangeRateProvider() throws Exception {
+    SolrCore core = h.getCore();
+    IndexSchema schema = core.getSchema();
+    SchemaField amount = schema.getField("mock_amount");
+
+    // A few tests on the provider directly
+    ExchangeRateProvider p = ((CurrencyField)amount.getType()).getProvider();
+    Set<String> availableCurrencies = p.listAvailableCurrencies();
+    assert(availableCurrencies.size() == 3);
+    assert(p.reload() == true);
+    assert(p.getExchangeRate("USD", "EUR") == 0.8);
+  }
+
+  @Test
   public void testCurrencyRangeSearch() throws Exception {
     for (int i = 1; i <= 10; i++) {
       assertU(adoc("id", "" + i, "amount", i + ",USD"));
@@ -197,7 +211,7 @@ public class CurrencyFieldTest extends S
   }
 
   @Test
-  public void testMockExchangeRateProvider() throws Exception {
+  public void testMockFieldType() throws Exception {
     assertU(adoc("id", "1", "mock_amount", "1.00,USD"));
     assertU(adoc("id", "2", "mock_amount", "1.00,EUR"));
     assertU(adoc("id", "3", "mock_amount", "1.00,NOK"));

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/MockExchangeRateProvider.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/MockExchangeRateProvider.java?rev=1307063&r1=1307062&r2=1307063&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/MockExchangeRateProvider.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/MockExchangeRateProvider.java Thu Mar 29 19:14:07 2012
@@ -17,7 +17,9 @@ package org.apache.solr.schema;
  */
 
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.solr.common.ResourceLoader;
 import org.apache.solr.common.SolrException;
@@ -53,8 +55,17 @@ public class MockExchangeRateProvider im
   }
 
   @Override
-  public String[] listAvailableCurrencies() {
-    return map.keySet().toArray(new String[1]);
+  public Set<String> listAvailableCurrencies() {
+    Set<String> currenciesPairs = map.keySet();
+    Set<String> returnSet;
+    
+    returnSet = new HashSet<String>();
+    for (String c : currenciesPairs) {
+      String[] pairs = c.split(",");
+      returnSet.add(pairs[0]);
+      returnSet.add(pairs[1]);
+    }
+    return returnSet;
   }
 
   @Override

Added: lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/OpenExchangeRatesOrgProviderTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/OpenExchangeRatesOrgProviderTest.java?rev=1307063&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/OpenExchangeRatesOrgProviderTest.java (added)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/OpenExchangeRatesOrgProviderTest.java Thu Mar 29 19:14:07 2012
@@ -0,0 +1,89 @@
+package org.apache.solr.schema;
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.ResourceLoader;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.core.SolrResourceLoader;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Tests currency field type.
+ */
+public class OpenExchangeRatesOrgProviderTest extends SolrTestCaseJ4 {
+  OpenExchangeRatesOrgProvider oerp;
+  ResourceLoader loader;
+  private final Map<String,String> emptyParams = new HashMap<String,String>();
+  private Map<String,String> mockParams;
+
+  @Before
+  public void setUp() throws Exception {
+    super.setUp();
+    mockParams = new HashMap<String,String>();;
+    mockParams.put(OpenExchangeRatesOrgProvider.PARAM_RATES_FILE_LOCATION, "open-exchange-rates.json");  
+    oerp = new OpenExchangeRatesOrgProvider();
+    loader = new SolrResourceLoader("solr");
+  }
+  
+  @Test
+  public void testInit() throws Exception {
+    oerp.init(emptyParams);
+    assertTrue("Wrong default url", oerp.ratesFileLocation.toString().equals("http://openexchangerates.org/latest.json"));
+    assertTrue("Wrong default interval", oerp.refreshInterval == 1440);
+
+    Map<String,String> params = new HashMap<String,String>();
+    params.put(OpenExchangeRatesOrgProvider.PARAM_RATES_FILE_LOCATION, "http://foo.bar/baz");
+    params.put(OpenExchangeRatesOrgProvider.PARAM_REFRESH_INTERVAL, "100");
+    oerp.init(params);
+    assertTrue("Wrong param set url", oerp.ratesFileLocation.equals("http://foo.bar/baz"));
+    assertTrue("Wrong param interval", oerp.refreshInterval == 100);
+  }
+
+  @Test
+  public void testList() {
+    oerp.init(mockParams);
+    oerp.inform(loader);
+    assertEquals(159,     oerp.listAvailableCurrencies().size());
+  }
+
+  @Test
+  public void testGetExchangeRate() {
+    oerp.init(mockParams);
+    oerp.inform(loader);
+    assertTrue(5.73163 == oerp.getExchangeRate("USD", "NOK"));    
+  }
+
+  @Test
+  public void testReload() {
+    oerp.init(mockParams);
+    oerp.inform(loader);
+    assertTrue(oerp.reload());
+    assertEquals("USD", oerp.rates.getBaseCurrency());
+    assertEquals(new Long(1332070464L), new Long(oerp.rates.getTimestamp()));
+  }
+
+  @Test(expected=SolrException.class)
+  public void testNoInit() {
+    oerp.getExchangeRate("ABC", "DEF");
+    assertTrue("Should have thrown exception if not initialized", false);
+  }
+}

Modified: lucene/dev/trunk/solr/example/solr/conf/schema.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/example/solr/conf/schema.xml?rev=1307063&r1=1307062&r2=1307063&view=diff
==============================================================================
--- lucene/dev/trunk/solr/example/solr/conf/schema.xml (original)
+++ lucene/dev/trunk/solr/example/solr/conf/schema.xml Thu Mar 29 19:14:07 2012
@@ -459,12 +459,15 @@
         Parameters:
           defaultCurrency: Specifies the default currency if none specified. Defaults to "USD"
           precisionStep:   Specifies the precisionStep for the TrieLong field used for the amount
-          providerClass:   Lets you plug in other exchange backend. Defaults to FileExchangeRateProvider
-                           The FileExchangeRateProvider takes one parameter:
+          providerClass:   Lets you plug in other exchange provider backend:
+                           solr.FileExchangeRateProvider is the default and takes one parameter:
                              currencyConfig: name of an xml file holding exhange rates
+                           solr.OpenExchangeRatesOrgProvider uses rates from openexchangerates.org:
+                             ratesFileLocation: URL or path to rates JSON file (default latest.json on the web)
+                             refreshInterval: Number of minutes between each rates fetch (default: 1440, min: 60)
    -->
     <fieldType name="currency" class="solr.CurrencyField" precisionStep="8" defaultCurrency="USD" currencyConfig="currency.xml" />
-
+             
    <!-- some examples for different languages (generally ordered by ISO code) -->
 
     <!-- Arabic -->