Make d3 and nvd3 URLs configurable

Allow loading d3 and nvd3 from custom URLs.
This can be useful for hosting these files on the RAP server itself.

Change-Id: Id8b36927ef64762d563481b0149b2422a4199650
diff --git a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/Chart.java b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/Chart.java
index ea1c472..1e697bf 100644
--- a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/Chart.java
+++ b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/Chart.java
@@ -38,8 +38,9 @@
 @SuppressWarnings( "deprecation" ) // RAP 3.0 compatibility
 public abstract class Chart extends Canvas {
 
+  private static final String PROP_D3_JS_URL = "org.eclipse.rap.addons.chart.d3JsUrl";
+  private static final String DEF_D3_JS_URL = "https://d3js.org/d3.v3.min.js";
   private static final String REMOTE_TYPE = "rwt.chart.Chart";
-  private static final String D3_JS_URL = "https://d3js.org/d3.v3.min.js";
 
   private Resources resources;
   private CssLoader cssLoader;
@@ -67,7 +68,7 @@
     } );
     resources = getUniqueInstance( Resources.class, RWT.getApplicationContext() );
     cssLoader = getUniqueInstance( CssLoader.class, RWT.getUISession() );
-    requireJs( D3_JS_URL );
+    requireJs( System.getProperty( PROP_D3_JS_URL, DEF_D3_JS_URL ) );
     requireJs( registerResource( "chart/chart.js" ) );
   }
 
diff --git a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/NvChart.java b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/NvChart.java
index 3319ca7..fae98eb 100644
--- a/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/NvChart.java
+++ b/bundles/org.eclipse.rap.addons.chart/src/org/eclipse/rap/addons/chart/NvChart.java
@@ -15,15 +15,18 @@
 
 public abstract class NvChart extends Chart {
 
-  private static final String NVD3_CSS_URL
-    = "https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.min.css";
-  private static final String NVD3_JS_URL
+  private static final String PROP_NVD3_JS_URL = "org.eclipse.rap.addons.chart.nvd3JsUrl";
+  private static final String PROP_NVD3_CSS_URL = "org.eclipse.rap.addons.chart.nvd3CssUrl";
+  private static final String DEF_NVD3_JS_URL
     = "https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.min.js";
+  private static final String DEF_NVD3_CSS_URL
+    = "https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.min.css";
+
 
   protected NvChart( Composite parent, int style, String renderer ) {
     super( parent, style, renderer );
-    requireJs( NVD3_JS_URL );
-    requireCss( NVD3_CSS_URL );
+    requireJs( System.getProperty( PROP_NVD3_JS_URL, DEF_NVD3_JS_URL ) );
+    requireCss( System.getProperty( PROP_NVD3_CSS_URL, DEF_NVD3_CSS_URL ) );
     requireCss( registerResource( "resources/nv-chart.css" ) );
   }
 
diff --git a/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/Chart_Test.java b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/Chart_Test.java
index 32f15d3..c327431 100644
--- a/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/Chart_Test.java
+++ b/tests/org.eclipse.rap.addons.chart.test/src/org/eclipse/rap/addons/chart/Chart_Test.java
@@ -35,6 +35,7 @@
 import org.junit.Test;
 
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -69,9 +70,7 @@
   @Test
   public void testCreate_requiresD3JS() {
     JavaScriptLoader loader = mock( JavaScriptLoader.class );
-    Client client = mock( Client.class );
-    when( client.getService( JavaScriptLoader.class ) ).thenReturn( loader );
-    context.replaceClient( client );
+    fakeLoader( loader );
 
     new Chart( shell, SWT.BORDER, "foo" ) {};
 
@@ -79,6 +78,19 @@
   }
 
   @Test
+  public void testCreate_requiresD3JS_fromSystemProperty() {
+    JavaScriptLoader loader = mock( JavaScriptLoader.class );
+    fakeLoader( loader );
+
+    System.setProperty( "org.eclipse.rap.addons.chart.d3JsUrl", "custom://url" );
+    new Chart( shell, SWT.BORDER, "foo" ) {};
+    System.clearProperty( "org.eclipse.rap.addons.chart.d3JsUrl" );
+
+    verify( loader, never() ).require( "https://d3js.org/d3.v3.min.js" );
+    verify( loader ).require( "custom://url" );
+  }
+
+  @Test
   public void testCreate_registeresJavaScriptResource() {
     new Chart( shell, SWT.BORDER, "foo" ) {};
 
@@ -187,6 +199,12 @@
     verify( remoteObject ).listen( "Selection", false );
   }
 
+  private void fakeLoader( JavaScriptLoader loader ) {
+    Client client = mock( Client.class );
+    when( client.getService( JavaScriptLoader.class ) ).thenReturn( loader );
+    context.replaceClient( client );
+  }
+
   private Connection fakeConnection( RemoteObject remoteObject ) {
     Connection connection = mock( Connection.class );
     when( connection.createRemoteObject( anyString() ) ).thenReturn( remoteObject );