diff --git a/.gitignore b/.gitignore
index 51f9d064..945799ca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,6 @@
/sdmx-facade/sdmx-facade-util/target/
/sdmx-facade/sdmx-facade-file/target/
/sdmx-facade/sdmx-facade-samples/target/
-/sdmx-facade/sdmx-facade-web/target/
\ No newline at end of file
+/sdmx-facade/sdmx-facade-web-ri/target/
+/sdmx-facade/sdmx-facade-util-web/target/
+/sdmx-facade/sdmx-facade-util-xml/target/
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 21f8717e..3b00836e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,26 @@
language: java
jdk:
- oraclejdk8
+ - openjdk11
+
+env:
+ global:
+ - DEPLOY_JDK=oraclejdk8
+ - DEPLOY_REPO=nbbrd/jdemetra-dotstat
+ - DEPLOY_BIN=demetra-dotstat-desktop/target/*.nbm
+
+deploy:
+ # Github releases from tags
+ - provider: releases
+ api_key: "${GITHUB_KEY}"
+ skip_cleanup: true
+ draft: true
+ file_glob: true
+ file: "${DEPLOY_BIN}"
+ on:
+ tags: true
+ repo: "${DEPLOY_REPO}"
+ condition: $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_JDK_VERSION == $DEPLOY_JDK
cache:
directories:
diff --git a/README.md b/README.md
index 1685f9b4..0e5d2208 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
# SDMX extension for JDemetra+
-This plugin provides time series from [SDMX](https://sdmx.org/) to [JDemetra+](https://github.com/jdemetra/jdemetra-app) by using [SDMX Web Services](https://github.com/sdmx-twg/sdmx-rest/wiki).
-
[![Download](https://img.shields.io/github/release/nbbrd/jdemetra-dotstat.svg)](https://github.com/nbbrd/jdemetra-dotstat/releases/latest)
-## Quickstart
+This plugin provides time series from [SDMX](https://sdmx.org/) to [JDemetra+](https://github.com/jdemetra/jdemetra-app) by querying [web services](https://github.com/nbbrd/jdemetra-dotstat/wiki/Supported-web-services) or parsing [files](https://github.com/nbbrd/jdemetra-dotstat/wiki/Supported-file-formats).
+
+![Browsing web service](https://github.com/nbbrd/jdemetra-dotstat/wiki/assets/browse_web_service.gif)
See [documentation](https://github.com/nbbrd/jdemetra-dotstat/wiki).
diff --git a/demetra-dotstat-core/pom.xml b/demetra-dotstat-core/pom.xml
index 1ba5a079..4297ceb6 100644
--- a/demetra-dotstat-core/pom.xml
+++ b/demetra-dotstat-core/pom.xml
@@ -4,7 +4,7 @@
be.nbb.demetra
demetra-dotstat-core
- 2.2.2
+ 2.2.3
jar
Demetra - DotStat - Core
@@ -27,8 +27,11 @@
UTF-8
1.8
1.8
+ 3.8.0
+
2.2.0
+ 1.18.4
@@ -40,6 +43,11 @@
pom
import
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
@@ -73,17 +81,23 @@
be.nbb.sdmx
- sdmx-facade-web
+ sdmx-facade-file
${project.version}
+
+ eu.europa.ec.joinup.sat
+ demetra-jdbc
+
+
be.nbb.sdmx
- sdmx-facade-file
+ sdmx-facade-connectors
${project.version}
- eu.europa.ec.joinup.sat
- demetra-jdbc
+ be.nbb.sdmx
+ sdmx-facade-web-ri
+ ${project.version}
@@ -109,6 +123,41 @@
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+
+
+
+
+
+
+
+ 11
+
+
+
+ javax.xml.bind
+ jaxb-api
+ 2.4.0-b180830.0359
+ provided
+
+
+ org.glassfish.jaxb
+ jaxb-runtime
+ 2.4.0-b180830.0438
+ provided
+
+
+
+
+
netbeans-releases
@@ -118,5 +167,12 @@
oss-jfrog-artifactory-releases
https://oss.jfrog.org/artifactory/oss-release-local
+
+ projectlombok.org
+ https://projectlombok.org/edge-releases
+
+ true
+
+
diff --git a/demetra-dotstat-core/src/main/java/be/nbb/demetra/sdmx/file/SdmxFileProvider.java b/demetra-dotstat-core/src/main/java/be/nbb/demetra/sdmx/file/SdmxFileProvider.java
index 3afb3771..afdc1aa7 100644
--- a/demetra-dotstat-core/src/main/java/be/nbb/demetra/sdmx/file/SdmxFileProvider.java
+++ b/demetra-dotstat-core/src/main/java/be/nbb/demetra/sdmx/file/SdmxFileProvider.java
@@ -49,6 +49,10 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import be.nbb.sdmx.facade.SdmxManager;
+import ec.tss.TsAsyncMode;
+import ec.tss.tsproviders.cursor.TsCursorAsFiller;
+import ec.tss.tsproviders.utils.TsFillerAsProvider;
+import java.io.EOFException;
/**
*
@@ -78,6 +82,9 @@ public final class SdmxFileProvider implements IFileLoader, HasSdmxProperties {
@lombok.experimental.Delegate(excludes = {HasTsCursor.class, HasDataDisplayName.class})
private final CubeSupport cubeSupport;
+ @lombok.experimental.Delegate
+ private final HasDataDisplayName dataDisplayName;
+
@lombok.experimental.Delegate
private final ITsProvider tsSupport;
@@ -92,7 +99,8 @@ public SdmxFileProvider() {
this.beanSupport = HasDataSourceBean.of(NAME, sdmxParam, sdmxParam.getVersion());
this.filePathSupport = HasFilePaths.of(cache::invalidateAll);
this.cubeSupport = CubeSupport.of(new SdmxCubeResource(cache, properties, filePathSupport, sdmxParam));
- this.tsSupport = CubeSupport.asTsProvider(NAME, logger, cubeSupport, monikerSupport, cache::invalidateAll);
+ this.dataDisplayName = new SdmxFileDataDisplayName(beanSupport, cubeSupport);
+ this.tsSupport = TsFillerAsProvider.of(NAME, TsAsyncMode.Once, TsCursorAsFiller.of(logger, cubeSupport, monikerSupport, dataDisplayName), cache::invalidateAll);
}
@Override
@@ -110,24 +118,8 @@ public boolean accept(File pathname) {
return pathname.getName().toLowerCase().endsWith(".xml");
}
- @Override
- public String getDisplayName(DataSource dataSource) throws IllegalArgumentException {
- return getSourceLabel(decodeBean(dataSource));
- }
-
- @Override
- public String getDisplayName(DataSet dataSet) throws IllegalArgumentException {
- return cubeSupport.getDisplayName(dataSet);
- }
-
- @Override
- public String getDisplayName(IOException exception) throws IllegalArgumentException {
- return cubeSupport.getDisplayName(exception);
- }
-
- @Override
- public String getDisplayNodeName(DataSet dataSet) throws IllegalArgumentException {
- return cubeSupport.getDisplayNodeName(dataSet);
+ private static String getSourceLabel(SdmxFileBean bean) {
+ return bean.getFile().getPath();
}
@lombok.AllArgsConstructor
@@ -182,7 +174,33 @@ private static IO.Supplier toConnection(HasSdmxProperties proper
}
}
- private static String getSourceLabel(SdmxFileBean bean) {
- return bean.getFile().getPath();
+ @lombok.AllArgsConstructor
+ private static final class SdmxFileDataDisplayName implements HasDataDisplayName {
+
+ private final HasDataSourceBean beanSupport;
+ private final CubeSupport cubeSupport;
+
+ @Override
+ public String getDisplayName(DataSource dataSource) throws IllegalArgumentException {
+ return getSourceLabel(beanSupport.decodeBean(dataSource));
+ }
+
+ @Override
+ public String getDisplayName(DataSet dataSet) throws IllegalArgumentException {
+ return cubeSupport.getDisplayName(dataSet);
+ }
+
+ @Override
+ public String getDisplayName(IOException exception) throws IllegalArgumentException {
+ if (exception instanceof EOFException) {
+ return "Unexpected end-of-file: " + exception.getMessage();
+ }
+ return cubeSupport.getDisplayName(exception);
+ }
+
+ @Override
+ public String getDisplayNodeName(DataSet dataSet) throws IllegalArgumentException {
+ return cubeSupport.getDisplayNodeName(dataSet);
+ }
}
}
diff --git a/demetra-dotstat-core/src/main/java/internal/sdmx/SdmxQueryUtil.java b/demetra-dotstat-core/src/main/java/internal/sdmx/SdmxQueryUtil.java
index 544319e8..9ffa0a68 100644
--- a/demetra-dotstat-core/src/main/java/internal/sdmx/SdmxQueryUtil.java
+++ b/demetra-dotstat-core/src/main/java/internal/sdmx/SdmxQueryUtil.java
@@ -20,7 +20,7 @@
import be.nbb.sdmx.facade.DataflowRef;
import be.nbb.sdmx.facade.Dimension;
import be.nbb.sdmx.facade.Key;
-import be.nbb.sdmx.facade.DataQuery;
+import be.nbb.sdmx.facade.DataFilter;
import be.nbb.sdmx.facade.SdmxConnection;
import com.google.common.collect.ImmutableList;
import ec.tss.tsproviders.cursor.TsCursor;
@@ -85,7 +85,7 @@ public List getChildren(SdmxConnection conn, DataflowRef flowRef, Key re
//
private TsCursor request(SdmxConnection conn, DataflowRef flowRef, Key key, String labelAttribute, boolean seriesKeysOnly) throws IOException {
- return new SdmxDataAdapter(key, conn.getCursor(flowRef, DataQuery.of(key, seriesKeysOnly)), labelAttribute);
+ return new SdmxDataAdapter(key, conn.getDataCursor(flowRef, key, seriesKeysOnly ? DataFilter.SERIES_KEYS_ONLY : DataFilter.ALL), labelAttribute);
}
private TsCursor computeKeys(SdmxConnection conn, DataflowRef flowRef, Key key) throws IOException {
diff --git a/demetra-dotstat-core/src/test/java/be/nbb/demetra/dotstat/DotStatAccessorTest.java b/demetra-dotstat-core/src/test/java/be/nbb/demetra/dotstat/DotStatAccessorTest.java
index e1567f89..82400204 100644
--- a/demetra-dotstat-core/src/test/java/be/nbb/demetra/dotstat/DotStatAccessorTest.java
+++ b/demetra-dotstat-core/src/test/java/be/nbb/demetra/dotstat/DotStatAccessorTest.java
@@ -20,7 +20,7 @@
import be.nbb.sdmx.facade.DataStructure;
import be.nbb.sdmx.facade.Dimension;
import be.nbb.sdmx.facade.Key;
-import be.nbb.sdmx.facade.DataQuery;
+import be.nbb.sdmx.facade.DataFilter;
import be.nbb.sdmx.facade.Series;
import be.nbb.sdmx.facade.repo.SdmxRepositoryManager;
import com.google.common.base.Joiner;
@@ -108,7 +108,7 @@ public void testGetKey() throws Exception {
@Test
public void testGetKeyFromTs() throws Exception {
assertThat(manager.getConnection("NBB")
- .getStream(NBB_FLOW_REF, DataQuery.of(Key.ALL, true))
+ .getDataStream(NBB_FLOW_REF, Key.ALL, DataFilter.SERIES_KEYS_ONLY)
.map(Series::getKey)).contains(Key.parse("LOCSTL04.AUS.M"));
}
diff --git a/demetra-dotstat-core/src/test/java/be/nbb/demetra/sdmx/file/SdmxFileProviderTest.java b/demetra-dotstat-core/src/test/java/be/nbb/demetra/sdmx/file/SdmxFileProviderTest.java
index 09b781df..976e7b8c 100644
--- a/demetra-dotstat-core/src/test/java/be/nbb/demetra/sdmx/file/SdmxFileProviderTest.java
+++ b/demetra-dotstat-core/src/test/java/be/nbb/demetra/sdmx/file/SdmxFileProviderTest.java
@@ -146,12 +146,12 @@ public void testContent() throws IOException {
assertThat(newColInfo(p, NO_XML, STRUCT20)).satisfies(info -> {
assertThat(p.get(info)).isFalse();
- assertThat(info.invalidDataCause).contains("XMLStreamException");
+ assertThat(info.invalidDataCause).contains("end-of-file");
});
assertThat(newColInfo(p, GENERIC20, NO_XML)).satisfies(info -> {
assertThat(p.get(info)).isFalse();
- assertThat(info.invalidDataCause).contains("XMLStreamException");
+ assertThat(info.invalidDataCause).contains("end-of-file");
});
}
}
diff --git a/demetra-dotstat-core/src/test/java/test/samples/FacadeResource.java b/demetra-dotstat-core/src/test/java/test/samples/FacadeResource.java
index 3fcde583..4a7769f9 100644
--- a/demetra-dotstat-core/src/test/java/test/samples/FacadeResource.java
+++ b/demetra-dotstat-core/src/test/java/test/samples/FacadeResource.java
@@ -26,6 +26,7 @@
import be.nbb.sdmx.facade.samples.SdmxSource;
import be.nbb.sdmx.facade.repo.SdmxRepository;
import be.nbb.sdmx.facade.Series;
+import be.nbb.sdmx.facade.parser.DataFactory;
import be.nbb.sdmx.facade.util.SeriesSupport;
import be.nbb.sdmx.facade.xml.stream.SdmxXmlStreams;
import java.io.IOException;
@@ -104,7 +105,7 @@ private List flow20(ByteSource xml, LanguagePriorityList l) throws IOE
}
List data20(ByteSource xml, DataStructure dsd) throws IOException {
- try (DataCursor c = SdmxXmlStreams.genericData20(dsd).parseReader(xml::openReader)) {
+ try (DataCursor c = SdmxXmlStreams.genericData20(dsd, DataFactory.sdmx20()).parseReader(xml::openReader)) {
return SeriesSupport.copyOf(c);
}
}
@@ -118,7 +119,7 @@ private List flow21(ByteSource xml, LanguagePriorityList l) throws IOE
}
List data21(ByteSource xml, DataStructure dsd) throws IOException {
- try (DataCursor c = SdmxXmlStreams.genericData21(dsd).parseReader(xml::openReader)) {
+ try (DataCursor c = SdmxXmlStreams.genericData21(dsd, DataFactory.sdmx21()).parseReader(xml::openReader)) {
return SeriesSupport.copyOf(c);
}
}
diff --git a/demetra-dotstat-desktop/pom.xml b/demetra-dotstat-desktop/pom.xml
index 2826f654..e62b1d36 100644
--- a/demetra-dotstat-desktop/pom.xml
+++ b/demetra-dotstat-desktop/pom.xml
@@ -4,7 +4,7 @@
be.nbb.demetra
demetra-dotstat-desktop
- 2.2.2
+ 2.2.3
nbm
Demetra - DotStat - Desktop
@@ -27,10 +27,13 @@
UTF-8
1.8
1.8
- 2.6
- 3.14
+ 3.8.0
+ 3.1.1
+ 4.1
+
2.2.0
+ 1.0.0-SNAPSHOT
@@ -134,6 +137,11 @@
sdmx-facade-api
${project.version}
+
+ be.nbb.rd
+ java-net-proxy
+ ${java-net-proxy.version}
+
@@ -145,9 +153,22 @@
oss-jfrog-artifactory-releases
https://oss.jfrog.org/artifactory/oss-release-local
+
+ oss-jfrog-artifactory-snapshots
+ https://oss.jfrog.org/artifactory/oss-snapshot-local
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+
org.apache.maven.plugins
@@ -155,7 +176,9 @@
${maven-jar-plugin.version}
- true
+
+ ${project.build.outputDirectory}/META-INF/MANIFEST.MF
+
@@ -172,4 +195,21 @@
+
+
+
+
+
+ 11
+
+
+
+ javax.annotation
+ javax.annotation-api
+ 1.3.2
+ provided
+
+
+
+
diff --git a/demetra-dotstat-desktop/src/main/java/be/nbb/demetra/sdmx/file/SdmxFileProviderBuddy.java b/demetra-dotstat-desktop/src/main/java/be/nbb/demetra/sdmx/file/SdmxFileProviderBuddy.java
index dc130aa4..df47f413 100644
--- a/demetra-dotstat-desktop/src/main/java/be/nbb/demetra/sdmx/file/SdmxFileProviderBuddy.java
+++ b/demetra-dotstat-desktop/src/main/java/be/nbb/demetra/sdmx/file/SdmxFileProviderBuddy.java
@@ -32,7 +32,6 @@
import ec.nbdemetra.ui.tsproviders.IDataSourceProviderBuddy;
import ec.tss.tsproviders.DataSet;
import ec.tss.tsproviders.IFileLoader;
-import ec.tss.tsproviders.TsProviders;
import ec.tstoolkit.utilities.GuavaCaches;
import internal.file.SdmxFileUtil;
import internal.sdmx.SdmxAutoCompletion;
@@ -52,6 +51,7 @@
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import be.nbb.sdmx.facade.SdmxManager;
+import org.openide.util.Lookup;
/**
*
@@ -133,7 +133,7 @@ private static SdmxFileManager createManager() {
}
private static Optional lookupProvider() {
- return TsProviders.lookup(SdmxFileProvider.class, SdmxFileProvider.NAME).toJavaUtil();
+ return Optional.ofNullable(Lookup.getDefault().lookup(SdmxFileProvider.class));
}
private static Configurator createConfigurator() {
diff --git a/demetra-dotstat-desktop/src/main/java/be/nbb/demetra/sdmx/web/SdmxWebProviderBuddy.java b/demetra-dotstat-desktop/src/main/java/be/nbb/demetra/sdmx/web/SdmxWebProviderBuddy.java
index f18c69f3..a33b5aa2 100644
--- a/demetra-dotstat-desktop/src/main/java/be/nbb/demetra/sdmx/web/SdmxWebProviderBuddy.java
+++ b/demetra-dotstat-desktop/src/main/java/be/nbb/demetra/sdmx/web/SdmxWebProviderBuddy.java
@@ -33,7 +33,6 @@
import ec.nbdemetra.ui.properties.PropertySheetDialogBuilder;
import ec.nbdemetra.ui.tsproviders.IDataSourceProviderBuddy;
import ec.tss.tsproviders.DataSet;
-import ec.tss.tsproviders.TsProviders;
import ec.tstoolkit.utilities.GuavaCaches;
import internal.sdmx.SdmxAutoCompletion;
import java.awt.Image;
@@ -50,9 +49,15 @@
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import be.nbb.sdmx.facade.SdmxManager;
+import be.nbb.sdmx.facade.util.HasCache;
+import be.nbb.sdmx.facade.web.spi.SdmxWebDriver;
import java.net.ProxySelector;
+import java.util.ArrayList;
+import java.util.ServiceLoader;
import javax.annotation.Nullable;
import javax.net.ssl.SSLSocketFactory;
+import nbbrd.net.SystemProxySelector;
+import org.openide.util.Lookup;
/**
*
@@ -142,7 +147,7 @@ public void setSSLSocketFactory(@Nullable SSLSocketFactory sslSocketFactory) {
//
private static Optional lookupProvider() {
- return TsProviders.lookup(SdmxWebProvider.class, SdmxWebProvider.NAME).toJavaUtil();
+ return Optional.ofNullable(Lookup.getDefault().lookup(SdmxWebProvider.class));
}
private static Configurator createConfigurator() {
@@ -150,8 +155,18 @@ private static Configurator createConfigurator() {
}
private static SdmxWebManager createManager() {
- SdmxWebManager result = SdmxWebManager.ofServiceLoader();
- result.setCache(GuavaCaches.softValuesCacheAsMap());
+ ConcurrentMap cache = GuavaCaches.softValuesCacheAsMap();
+ List drivers = new ArrayList<>();
+ ServiceLoader
+ .load(SdmxWebDriver.class)
+ .forEach(o -> {
+ if (o instanceof HasCache) {
+ ((HasCache) o).setCache(cache);
+ }
+ drivers.add(o);
+ });
+ SdmxWebManager result = SdmxWebManager.of(drivers);
+ result.setProxySelector(SystemProxySelector.ofServiceLoader());
return result;
}
diff --git a/demetra-dotstat-desktop/src/main/java/internal/sdmx/SdmxAutoCompletion.java b/demetra-dotstat-desktop/src/main/java/internal/sdmx/SdmxAutoCompletion.java
index eab9ac96..2da85d7b 100644
--- a/demetra-dotstat-desktop/src/main/java/internal/sdmx/SdmxAutoCompletion.java
+++ b/demetra-dotstat-desktop/src/main/java/internal/sdmx/SdmxAutoCompletion.java
@@ -83,7 +83,11 @@ public AutoCompletionSource onSources(SdmxWebManager manager) {
}
public ListCellRenderer getSourceRenderer() {
- return CustomListCellRenderer.of(SdmxWebSource::getDescription, SdmxWebSource::getName);
+ return CustomListCellRenderer.of(SdmxAutoCompletion::getNameAndDescription, o -> null);
+ }
+
+ private String getNameAndDescription(SdmxWebSource o) {
+ return o.getName() + ": " + o.getDescription();
}
public AutoCompletionSource onFlows(SdmxManager manager, Supplier source, ConcurrentMap cache) {
@@ -129,7 +133,13 @@ public String getDefaultDimensionsAsString(SdmxManager manager, Supplier
private List filterAndSortSources(List allValues, String term) {
Predicate filter = ExtAutoCompletionSource.basicFilter(term);
- return allValues.stream()
+ // need to filter out duplicates
+ return allValues
+ .stream()
+ .collect(Collectors.groupingBy(SdmxWebSource::getName))
+ .values()
+ .stream()
+ .flatMap(o -> o.stream().limit(1))
.filter(o -> filter.test(o.getDescription()) || filter.test(o.getName()))
.sorted(Comparator.comparing(SdmxWebSource::getDescription))
.collect(Collectors.toList());
diff --git a/pom.xml b/pom.xml
index 664da3b3..0dd93d67 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
be.nbb.demetra
demetra-dotstat-aggregator
- 2.2.2
+ 2.2.3
pom
Demetra - DotStat
diff --git a/sdmx-facade/pom.xml b/sdmx-facade/pom.xml
index ae308b16..99d01937 100644
--- a/sdmx-facade/pom.xml
+++ b/sdmx-facade/pom.xml
@@ -4,17 +4,20 @@
be.nbb.sdmx
sdmx-facade-parent
- 2.2.2
+ 2.2.3
pom
sdmx-facade
sdmx-facade-api
+ sdmx-facade-samples
sdmx-facade-util
+ sdmx-facade-util-xml
+ sdmx-facade-util-web
sdmx-facade-file
- sdmx-facade-samples
- sdmx-facade-web
+ sdmx-facade-web-ri
+ sdmx-facade-connectors
@@ -22,14 +25,18 @@
UTF-8
1.8
1.8
- 0.7.9
+ 3.8.0
+ 0.8.2
-
- 3.0.2
- 1.16.18
+
4.12
- 3.8.0
- 0.0.1
+ 3.0.2
+ 3.11.1
+ RELEASE82
+ 1.18.4
+
+
+ 0.0.2
@@ -60,6 +67,11 @@
java-io-util
${java-io-util.version}
+
+ org.netbeans.api
+ org-openide-util-lookup
+ ${netbeans.version}
+
${project.groupId}
@@ -73,7 +85,12 @@
${project.groupId}
- sdmx-facade-web
+ sdmx-facade-connectors
+ ${project.version}
+
+
+ ${project.groupId}
+ sdmx-facade-util-web
${project.version}
@@ -86,29 +103,47 @@
sdmx-facade-samples
${project.version}
+
+ ${project.groupId}
+ sdmx-facade-util-xml
+ ${project.version}
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco-maven-plugin.version}
+
+
+
+ prepare-agent
+
+
+
+ report
+ prepare-package
+
+ report
+
+
+
+
+
+
org.jacoco
jacoco-maven-plugin
- ${jacoco-maven-plugin.version}
-
-
-
- prepare-agent
-
-
-
- report
- prepare-package
-
- report
-
-
-
@@ -122,5 +157,16 @@
oss-jfrog-artifactory-snapshots
https://oss.jfrog.org/artifactory/oss-snapshot-local
+
+ netbeans
+ http://bits.netbeans.org/maven2/
+
+
+ projectlombok.org
+ https://projectlombok.org/edge-releases
+
+ true
+
+
diff --git a/sdmx-facade/sdmx-facade-api/pom.xml b/sdmx-facade/sdmx-facade-api/pom.xml
index 79843443..614a584d 100644
--- a/sdmx-facade/sdmx-facade-api/pom.xml
+++ b/sdmx-facade/sdmx-facade-api/pom.xml
@@ -5,7 +5,7 @@
be.nbb.sdmx
sdmx-facade-parent
- 2.2.2
+ 2.2.3
sdmx-facade-api
diff --git a/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/DataQuery.java b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/DataFilter.java
similarity index 67%
rename from sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/DataQuery.java
rename to sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/DataFilter.java
index 456f170c..9c07a4f3 100644
--- a/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/DataQuery.java
+++ b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/DataFilter.java
@@ -16,28 +16,26 @@
*/
package be.nbb.sdmx.facade;
-import javax.annotation.Nonnull;
-
/**
*
* @author Philippe Charles
*/
@lombok.Value
@lombok.Builder(builderClassName = "Builder")
-public class DataQuery {
+public class DataFilter {
- @lombok.NonNull
- Key key;
+ public static final DataFilter ALL = builder().build();
+ public static final DataFilter SERIES_KEYS_ONLY = builder().detail(Detail.SERIES_KEYS_ONLY).build();
@lombok.NonNull
@lombok.Builder.Default
- DataQueryDetail detail = DataQueryDetail.FULL;
+ Detail detail = Detail.FULL;
+
+ public boolean isSeriesKeyOnly() {
+ return detail.equals(Detail.SERIES_KEYS_ONLY);
+ }
- @Nonnull
- public static DataQuery of(@Nonnull Key key, boolean seriesKeysOnly) {
- return DataQuery.builder()
- .key(key)
- .detail(seriesKeysOnly ? DataQueryDetail.SERIES_KEYS_ONLY : DataQueryDetail.FULL)
- .build();
+ public enum Detail {
+ FULL, SERIES_KEYS_ONLY
}
}
diff --git a/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/DataStructure.java b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/DataStructure.java
index 6e97ea4c..e90f55d2 100644
--- a/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/DataStructure.java
+++ b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/DataStructure.java
@@ -28,7 +28,7 @@
* @author Philippe Charles
*/
@lombok.Value
-@lombok.Builder(builderClassName = "Builder")
+@lombok.Builder(builderClassName = "Builder", toBuilder = true)
public class DataStructure implements HasLabel {
/**
diff --git a/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/SdmxConnection.java b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/SdmxConnection.java
index 913e31da..0f6e8b6d 100644
--- a/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/SdmxConnection.java
+++ b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/SdmxConnection.java
@@ -18,7 +18,8 @@
import java.io.Closeable;
import java.io.IOException;
-import java.util.Set;
+import java.util.Collection;
+import java.util.List;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.NotThreadSafe;
@@ -31,7 +32,7 @@
public interface SdmxConnection extends Closeable {
@Nonnull
- Set getFlows() throws IOException;
+ Collection getFlows() throws IOException;
@Nonnull
Dataflow getFlow(@Nonnull DataflowRef flowRef) throws IOException;
@@ -40,10 +41,13 @@ public interface SdmxConnection extends Closeable {
DataStructure getStructure(@Nonnull DataflowRef flowRef) throws IOException;
@Nonnull
- DataCursor getCursor(@Nonnull DataflowRef flowRef, @Nonnull DataQuery query) throws IOException;
+ List getData(@Nonnull DataflowRef flowRef, @Nonnull Key key, @Nonnull DataFilter filter) throws IOException;
@Nonnull
- Stream getStream(@Nonnull DataflowRef flowRef, @Nonnull DataQuery query) throws IOException;
+ Stream getDataStream(@Nonnull DataflowRef flowRef, @Nonnull Key key, @Nonnull DataFilter filter) throws IOException;
+
+ @Nonnull
+ DataCursor getDataCursor(@Nonnull DataflowRef flowRef, @Nonnull Key key, @Nonnull DataFilter filter) throws IOException;
boolean isSeriesKeysOnlySupported() throws IOException;
}
diff --git a/sdmx-facade/sdmx-facade-web/src/main/java/be/nbb/sdmx/facade/web/SdmxWebConnection.java b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/web/SdmxWebConnection.java
similarity index 94%
rename from sdmx-facade/sdmx-facade-web/src/main/java/be/nbb/sdmx/facade/web/SdmxWebConnection.java
rename to sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/web/SdmxWebConnection.java
index 1f5b3996..2f810c7c 100644
--- a/sdmx-facade/sdmx-facade-web/src/main/java/be/nbb/sdmx/facade/web/SdmxWebConnection.java
+++ b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/web/SdmxWebConnection.java
@@ -29,4 +29,7 @@ public interface SdmxWebConnection extends SdmxConnection {
@Nonnull
Duration ping() throws IOException;
+
+ @Nonnull
+ String getDriver() throws IOException;
}
diff --git a/sdmx-facade/sdmx-facade-web/src/main/java/be/nbb/sdmx/facade/web/SdmxWebManager.java b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/web/SdmxWebManager.java
similarity index 65%
rename from sdmx-facade/sdmx-facade-web/src/main/java/be/nbb/sdmx/facade/web/SdmxWebManager.java
rename to sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/web/SdmxWebManager.java
index 0fd57132..eed76c94 100644
--- a/sdmx-facade/sdmx-facade-web/src/main/java/be/nbb/sdmx/facade/web/SdmxWebManager.java
+++ b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/web/SdmxWebManager.java
@@ -19,19 +19,14 @@
import be.nbb.sdmx.facade.web.spi.SdmxWebContext;
import be.nbb.sdmx.facade.web.spi.SdmxWebDriver;
import be.nbb.sdmx.facade.LanguagePriorityList;
-import be.nbb.sdmx.facade.util.HasCache;
-import be.nbb.sdmx.facade.util.UnexpectedIOException;
import java.io.IOException;
import java.net.ProxySelector;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.ServiceLoader;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -43,6 +38,10 @@
import javax.net.ssl.SSLSocketFactory;
import lombok.AccessLevel;
import be.nbb.sdmx.facade.SdmxManager;
+import java.util.Comparator;
+import java.util.Optional;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.stream.StreamSupport;
/**
*
@@ -50,7 +49,7 @@
*/
@lombok.RequiredArgsConstructor(access = AccessLevel.PRIVATE)
@lombok.extern.java.Log
-public final class SdmxWebManager implements SdmxManager, HasCache {
+public final class SdmxWebManager implements SdmxManager {
@Nonnull
public static SdmxWebManager ofServiceLoader() {
@@ -64,34 +63,30 @@ public static SdmxWebManager of(@Nonnull SdmxWebDriver... drivers) {
@Nonnull
public static SdmxWebManager of(@Nonnull Iterable extends SdmxWebDriver> drivers) {
- List driverList = new ArrayList<>();
- drivers.forEach(driverList::add);
-
- ConcurrentMap sourceByName = new ConcurrentHashMap<>();
- updateSourceMap(sourceByName, driverList.stream().flatMap(o -> tryGetDefaultSources(o)));
+ List orderedListOfDrivers = StreamSupport
+ .stream(drivers.spliterator(), false)
+ .sorted(Comparator.comparing(SdmxWebDriver::getRank).reversed().thenComparing(SdmxWebDriver::getName))
+ .collect(Collectors.toList());
- HasCache cacheSupport = HasCache.of(ConcurrentHashMap::new, (o, n) -> applyCache(n, driverList));
+ CopyOnWriteArrayList sources = orderedListOfDrivers
+ .stream()
+ .flatMap(SdmxWebManager::tryGetDefaultSources)
+ .collect(Collectors.toCollection(CopyOnWriteArrayList::new));
- return new SdmxWebManager(
- new AtomicReference<>(LanguagePriorityList.ANY),
- new AtomicReference<>(SdmxWebContext.builder().build()),
- driverList, sourceByName, cacheSupport);
+ return new SdmxWebManager(orderedListOfDrivers, sources);
}
- private final AtomicReference languages;
- private final AtomicReference context;
+ private final AtomicReference context = new AtomicReference<>(SdmxWebContext.builder().build());
private final List drivers;
- private final ConcurrentMap sourceByName;
- private final HasCache cacheSupport;
+ private final CopyOnWriteArrayList sources;
@Override
public SdmxWebConnection getConnection(String name) throws IOException {
Objects.requireNonNull(name);
- SdmxWebSource source = sourceByName.get(name);
- if (source == null) {
- throw new IOException("Cannot find entry point for '" + name + "'");
- }
+ SdmxWebSource source = lookupSource(name)
+ .orElseThrow(() -> new IOException("Cannot find entry point for '" + name + "'"));
+
return getConnection(source);
}
@@ -99,33 +94,21 @@ public SdmxWebConnection getConnection(String name) throws IOException {
public SdmxWebConnection getConnection(@Nonnull SdmxWebSource source) throws IOException {
Objects.requireNonNull(source);
- SdmxWebDriver driver = drivers
- .stream()
- .filter(o -> source.getDriver().equals(o.getName()))
- .findFirst()
+ SdmxWebDriver driver = lookupDriver(source.getDriver())
.orElseThrow(() -> new IOException("Failed to find a suitable driver for '" + source + "'"));
- return tryConnect(driver, source, languages.get(), context.get());
+ return tryConnect(driver, source, context.get());
}
@Override
public LanguagePriorityList getLanguages() {
- return languages.get();
+ return context.get().getLanguages();
}
@Override
public void setLanguages(LanguagePriorityList languages) {
- this.languages.set(languages != null ? languages : LanguagePriorityList.ANY);
- }
-
- @Override
- public ConcurrentMap getCache() {
- return cacheSupport.getCache();
- }
-
- @Override
- public void setCache(ConcurrentMap cache) {
- this.cacheSupport.setCache(cache);
+ LanguagePriorityList newObj = languages != null ? languages : LanguagePriorityList.ANY;
+ this.context.set(context.get().toBuilder().languages(newObj).build());
}
@Nonnull
@@ -160,11 +143,12 @@ public void setLogger(@Nullable Logger logger) {
@Nonnull
public List getSources() {
- return new ArrayList<>(sourceByName.values());
+ return Collections.unmodifiableList(sources);
}
public void setSources(@Nonnull List list) {
- updateSourceMap(sourceByName, list.stream());
+ sources.clear();
+ sources.addAll(list);
}
@Nonnull
@@ -178,38 +162,39 @@ public List getDrivers() {
@Nonnull
public Collection getSupportedProperties(@Nonnull String driver) {
- return drivers
- .stream()
- .filter(o -> driver.equals(o.getName()))
+ Objects.requireNonNull(driver);
+ return lookupDriver(driver)
.map(SdmxWebDriver::getSupportedProperties)
- .findFirst()
.orElse(Collections.emptyList());
}
- private static void applyCache(ConcurrentMap cache, List drivers) {
- drivers.stream()
- .filter(HasCache.class::isInstance)
- .forEach(o -> ((HasCache) o).setCache(cache));
+ private Optional lookupSource(String name) {
+ return sources
+ .stream()
+ .filter(o -> name.equals(o.getName()))
+ .findFirst();
}
- private static void updateSourceMap(ConcurrentMap sourceByName, Stream list) {
- sourceByName.clear();
- list.forEach(o -> sourceByName.put(o.getName(), o));
+ private Optional lookupDriver(String name) {
+ return drivers
+ .stream()
+ .filter(o -> name.equals(o.getName()))
+ .findFirst();
}
@SuppressWarnings("null")
- private static SdmxWebConnection tryConnect(SdmxWebDriver driver, SdmxWebSource s, LanguagePriorityList l, SdmxWebContext c) throws IOException {
+ private static SdmxWebConnection tryConnect(SdmxWebDriver driver, SdmxWebSource s, SdmxWebContext c) throws IOException {
SdmxWebConnection result;
try {
- result = driver.connect(s, l, c);
+ result = driver.connect(s, c);
} catch (RuntimeException ex) {
- log.log(Level.WARNING, "Unexpected exception while connecting", ex);
- throw new UnexpectedIOException(ex);
+ c.getLogger().log(Level.WARNING, "Unexpected exception while connecting", ex);
+ throw new IOException(ex);
}
if (result == null) {
- log.log(Level.WARNING, "Unexpected null connection");
+ c.getLogger().log(Level.WARNING, "Unexpected null connection");
throw new IOException("Unexpected null connection");
}
diff --git a/sdmx-facade/sdmx-facade-web/src/main/java/be/nbb/sdmx/facade/web/SdmxWebSource.java b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/web/SdmxWebSource.java
similarity index 100%
rename from sdmx-facade/sdmx-facade-web/src/main/java/be/nbb/sdmx/facade/web/SdmxWebSource.java
rename to sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/web/SdmxWebSource.java
diff --git a/sdmx-facade/sdmx-facade-web/src/main/java/be/nbb/sdmx/facade/web/spi/SdmxWebContext.java b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/web/spi/SdmxWebContext.java
similarity index 89%
rename from sdmx-facade/sdmx-facade-web/src/main/java/be/nbb/sdmx/facade/web/spi/SdmxWebContext.java
rename to sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/web/spi/SdmxWebContext.java
index 2008f20e..7619c61b 100644
--- a/sdmx-facade/sdmx-facade-web/src/main/java/be/nbb/sdmx/facade/web/spi/SdmxWebContext.java
+++ b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/web/spi/SdmxWebContext.java
@@ -16,6 +16,7 @@
*/
package be.nbb.sdmx.facade.web.spi;
+import be.nbb.sdmx.facade.LanguagePriorityList;
import be.nbb.sdmx.facade.web.SdmxWebManager;
import java.net.ProxySelector;
import java.util.logging.Logger;
@@ -30,6 +31,10 @@
@lombok.Builder(builderClassName = "Builder", toBuilder = true)
public class SdmxWebContext {
+ @lombok.NonNull
+ @lombok.Builder.Default
+ LanguagePriorityList languages = LanguagePriorityList.ANY;
+
@lombok.NonNull
@lombok.Builder.Default
ProxySelector proxySelector = ProxySelector.getDefault();
diff --git a/sdmx-facade/sdmx-facade-web/src/main/java/be/nbb/sdmx/facade/web/spi/SdmxWebDriver.java b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/web/spi/SdmxWebDriver.java
similarity index 92%
rename from sdmx-facade/sdmx-facade-web/src/main/java/be/nbb/sdmx/facade/web/spi/SdmxWebDriver.java
rename to sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/web/spi/SdmxWebDriver.java
index 6da48560..9fd1b245 100644
--- a/sdmx-facade/sdmx-facade-web/src/main/java/be/nbb/sdmx/facade/web/spi/SdmxWebDriver.java
+++ b/sdmx-facade/sdmx-facade-api/src/main/java/be/nbb/sdmx/facade/web/spi/SdmxWebDriver.java
@@ -16,7 +16,6 @@
*/
package be.nbb.sdmx.facade.web.spi;
-import be.nbb.sdmx.facade.LanguagePriorityList;
import be.nbb.sdmx.facade.web.SdmxWebConnection;
import be.nbb.sdmx.facade.web.SdmxWebSource;
import java.io.IOException;
@@ -34,10 +33,11 @@ public interface SdmxWebDriver {
@Nonnull
String getName();
+ int getRank();
+
@Nonnull
SdmxWebConnection connect(
@Nonnull SdmxWebSource source,
- @Nonnull LanguagePriorityList languages,
@Nonnull SdmxWebContext context
) throws IOException, IllegalArgumentException;
@@ -46,4 +46,7 @@ SdmxWebConnection connect(
@Nonnull
Collection getSupportedProperties();
+
+ static final int NATIVE_RANK = Byte.MAX_VALUE;
+ static final int WRAPPED_RANK = 0;
}
diff --git a/sdmx-facade/sdmx-facade-api/src/test/java/be/nbb/sdmx/facade/DimentionTest.java b/sdmx-facade/sdmx-facade-api/src/test/java/be/nbb/sdmx/facade/DimentionTest.java
index 8b004017..347f0e07 100644
--- a/sdmx-facade/sdmx-facade-api/src/test/java/be/nbb/sdmx/facade/DimentionTest.java
+++ b/sdmx-facade/sdmx-facade-api/src/test/java/be/nbb/sdmx/facade/DimentionTest.java
@@ -30,10 +30,11 @@ public class DimentionTest {
final String someLabel = "Dim 1";
@Test
+ @SuppressWarnings("null")
public void testBuilder() {
- assertThatNullPointerException().isThrownBy(builder()::build).withMessage("id");
- assertThatNullPointerException().isThrownBy(builder().id(null)::build).withMessage("id");
- assertThatNullPointerException().isThrownBy(builder().id(someId).label(null)::build).withMessage("label");
+ assertThatNullPointerException().isThrownBy(() -> builder().build()).withMessageContaining("id");
+ assertThatNullPointerException().isThrownBy(() -> builder().id(null).build()).withMessageContaining("id");
+ assertThatNullPointerException().isThrownBy(() -> builder().id(someId).label(null).build()).withMessageContaining("label");
assertThatNullPointerException().isThrownBy(() -> builder().codes(null));
assertThatExceptionOfType(UnsupportedOperationException.class)
diff --git a/sdmx-facade/sdmx-facade-web/pom.xml b/sdmx-facade/sdmx-facade-connectors/pom.xml
similarity index 79%
rename from sdmx-facade/sdmx-facade-web/pom.xml
rename to sdmx-facade/sdmx-facade-connectors/pom.xml
index f7630c0a..de80c226 100644
--- a/sdmx-facade/sdmx-facade-web/pom.xml
+++ b/sdmx-facade/sdmx-facade-connectors/pom.xml
@@ -5,23 +5,19 @@
be.nbb.sdmx
sdmx-facade-parent
- 2.2.2
+ 2.2.3
- sdmx-facade-web
+ sdmx-facade-connectors
jar
- 9244dfa854
- RELEASE802
+
+ d08affb9df
-
- netbeans
- http://bits.netbeans.org/maven2/
-
jitpack.io
https://jitpack.io
@@ -35,11 +31,6 @@
SDMX
${sdmx-connectors.version}
-
- org.netbeans.api
- org-openide-util-lookup
- ${netbeans.version}
-
@@ -69,6 +60,10 @@
${project.groupId}
sdmx-facade-util
+
+ ${project.groupId}
+ sdmx-facade-util-web
+
com.github.amattioc
SDMX
@@ -89,5 +84,10 @@
sdmx-facade-samples
test
+
+ ${project.groupId}
+ sdmx-facade-util-xml
+ test
+
diff --git a/sdmx-facade/sdmx-facade-web/src/main/java/internal/connectors/ConnectorRestClient.java b/sdmx-facade/sdmx-facade-connectors/src/main/java/internal/connectors/ConnectorRestClient.java
similarity index 76%
rename from sdmx-facade/sdmx-facade-web/src/main/java/internal/connectors/ConnectorRestClient.java
rename to sdmx-facade/sdmx-facade-connectors/src/main/java/internal/connectors/ConnectorRestClient.java
index aa7385f1..8b1201a6 100644
--- a/sdmx-facade/sdmx-facade-web/src/main/java/internal/connectors/ConnectorRestClient.java
+++ b/sdmx-facade/sdmx-facade-connectors/src/main/java/internal/connectors/ConnectorRestClient.java
@@ -17,14 +17,11 @@
package internal.connectors;
import be.nbb.sdmx.facade.DataCursor;
-import be.nbb.sdmx.facade.DataQuery;
-import be.nbb.sdmx.facade.DataQueryDetail;
import be.nbb.sdmx.facade.DataStructure;
import be.nbb.sdmx.facade.DataStructureRef;
import be.nbb.sdmx.facade.Dataflow;
import be.nbb.sdmx.facade.DataflowRef;
-import be.nbb.sdmx.facade.LanguagePriorityList;
-import be.nbb.sdmx.facade.parser.ObsParser;
+import be.nbb.sdmx.facade.parser.DataFactory;
import static internal.web.SdmxWebProperty.*;
import be.nbb.sdmx.facade.util.NoOpCursor;
import java.io.IOException;
@@ -45,6 +42,8 @@
import java.util.Arrays;
import java.util.Collections;
import be.nbb.sdmx.facade.web.spi.SdmxWebContext;
+import internal.web.DataRequest;
+import it.bancaditalia.oss.sdmx.api.PortableTimeSeries;
/**
*
@@ -68,13 +67,13 @@ public interface GenericSupplier {
}
@Nonnull
- public static SdmxWebClient.Supplier of(@Nonnull SpecificSupplier supplier) {
- return (source, langs, context) -> {
+ public static SdmxWebClient.Supplier of(@Nonnull SpecificSupplier supplier, @Nonnull DataFactory dataFactory) {
+ return (source, context) -> {
try {
RestSdmxClient client = supplier.get();
client.setEndpoint(source.getEndpoint().toURI());
- configure(client, source.getProperties(), langs, context);
- return new ConnectorRestClient(source.getName(), client);
+ configure(client, source.getProperties(), context);
+ return new ConnectorRestClient(source.getName(), client, dataFactory);
} catch (URISyntaxException ex) {
throw new RuntimeException(ex);
}
@@ -82,12 +81,12 @@ public static SdmxWebClient.Supplier of(@Nonnull SpecificSupplier supplier) {
}
@Nonnull
- public static SdmxWebClient.Supplier of(@Nonnull GenericSupplier supplier) {
- return (source, langs, context) -> {
+ public static SdmxWebClient.Supplier of(@Nonnull GenericSupplier supplier, @Nonnull DataFactory dataFactory) {
+ return (source, context) -> {
try {
RestSdmxClient client = supplier.get(source.getEndpoint().toURI(), source.getProperties());
- configure(client, source.getProperties(), langs, context);
- return new ConnectorRestClient(source.getName(), client);
+ configure(client, source.getProperties(), context);
+ return new ConnectorRestClient(source.getName(), client, dataFactory);
} catch (URISyntaxException ex) {
throw new RuntimeException(ex);
}
@@ -100,6 +99,14 @@ public static SdmxWebClient.Supplier of(@Nonnull GenericSupplier supplier) {
@lombok.NonNull
private final RestSdmxClient connector;
+ @lombok.NonNull
+ private final DataFactory dataFactory;
+
+ @Override
+ public String getName() throws IOException {
+ return name;
+ }
+
@Override
public List getFlows() throws IOException {
try {
@@ -133,16 +140,15 @@ public DataStructure getStructure(DataStructureRef ref) throws IOException {
}
@Override
- public DataCursor getData(DataflowRef flowRef, DataQuery query, DataStructure dsd) throws IOException {
+ public DataCursor getData(DataRequest request, DataStructure dsd) throws IOException {
try {
- return connector instanceof HasDataCursor
- ? getCursor((HasDataCursor) connector, flowRef, dsd, query)
- : getAdaptedCursor(connector, flowRef, dsd, query);
+ List> data = getData(connector, request, dsd);
+ return PortableTimeSeriesCursor.of(data, dataFactory, dsd);
} catch (SdmxException ex) {
if (Connectors.isNoResultMatchingQuery(ex)) {
return NoOpCursor.noOp();
}
- throw wrap(ex, "Failed to get data '%s' with %s from '%s'", flowRef, query, name);
+ throw wrap(ex, "Failed to get data '%s' from '%s'", request, name);
}
}
@@ -175,28 +181,24 @@ public Duration ping() throws IOException {
READ_TIMEOUT_PROPERTY
));
- private static DataCursor getCursor(HasDataCursor connector, DataflowRef flowRef, DataStructure dsd, DataQuery query) throws SdmxException, IOException {
- return connector.getDataCursor(flowRef, dsd, query.getKey(), isSeriesKeyOnly(query));
- }
-
- private static DataCursor getAdaptedCursor(RestSdmxClient connector, DataflowRef flowRef, DataStructure dsd, DataQuery query) throws SdmxException {
- return new PortableTimeSeriesCursor(connector.getTimeSeries(Connectors.fromFlowQuery(flowRef, dsd.getRef()), Connectors.fromStructure(dsd), query.getKey().toString(), null, null, isSeriesKeyOnly(query), null, false), ObsParser.standard());
- }
-
- private static boolean isSeriesKeyOnly(DataQuery query) {
- return query.getDetail().equals(DataQueryDetail.SERIES_KEYS_ONLY);
+ private static List> getData(RestSdmxClient connector, DataRequest request, DataStructure dsd) throws SdmxException {
+ return connector.getTimeSeries(Connectors.fromFlowQuery(request.getFlowRef(), dsd.getRef()), Connectors.fromStructure(dsd), request.getKey().toString(), null, null, request.getFilter().isSeriesKeyOnly(), null, false);
}
private static IOException wrap(SdmxException ex, String format, Object... args) {
return new IOException(String.format(format, args), ex);
}
- private static void configure(RestSdmxClient client, Map, ?> info, LanguagePriorityList langs, SdmxWebContext context) {
- client.setLanguages(Connectors.fromLanguages(langs));
+ private static void configure(RestSdmxClient client, Map, ?> info, SdmxWebContext context) {
+ client.setLanguages(Connectors.fromLanguages(context.getLanguages()));
client.setConnectTimeout(getConnectTimeout(info));
client.setReadTimeout(getReadTimeout(info));
client.setProxySelector(context.getProxySelector());
client.setSslSocketFactory(context.getSslSocketFactory());
// TODO: maxRedirections
}
+
+ static {
+ ConnectorsConfigFix.fixConfiguration();
+ }
}
diff --git a/sdmx-facade/sdmx-facade-web/src/main/java/internal/connectors/Connectors.java b/sdmx-facade/sdmx-facade-connectors/src/main/java/internal/connectors/Connectors.java
similarity index 100%
rename from sdmx-facade/sdmx-facade-web/src/main/java/internal/connectors/Connectors.java
rename to sdmx-facade/sdmx-facade-connectors/src/main/java/internal/connectors/Connectors.java
diff --git a/sdmx-facade/sdmx-facade-connectors/src/main/java/internal/connectors/ConnectorsConfigFix.java b/sdmx-facade/sdmx-facade-connectors/src/main/java/internal/connectors/ConnectorsConfigFix.java
new file mode 100644
index 00000000..8d54c0bc
--- /dev/null
+++ b/sdmx-facade/sdmx-facade-connectors/src/main/java/internal/connectors/ConnectorsConfigFix.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2018 National Bank of Belgium
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
+ * by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * http://ec.europa.eu/idabc/eupl
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ */
+package internal.connectors;
+
+import it.bancaditalia.oss.sdmx.util.Configuration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * @author Philippe Charles
+ */
+@lombok.experimental.UtilityClass
+class ConnectorsConfigFix {
+
+ static void fixConfiguration() {
+// Logger.getLogger(ConnectorRestClient.class.getName())
+// .log(Level.FINE, "Connectors config fix: before");
+
+ Handler handler = addVoidHandlerBeforeInit();
+ Map