diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 1ee2e3b..1ab9369 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,10 +1,11 @@
version: 2
updates:
- - package-ecosystem: "maven"
+ - package-ecosystem: maven
target-branch: "develop"
directory: "/"
schedule:
- interval: "daily"
+ interval: "weekly"
+ day: "saturday"
open-pull-requests-limit: 10
- package-ecosystem: "github-actions"
target-branch: "develop"
diff --git a/.github/workflows/java-ea-maven.yml b/.github/workflows/java-ea-maven.yml
index 6ec751a..7906c03 100644
--- a/.github/workflows/java-ea-maven.yml
+++ b/.github/workflows/java-ea-maven.yml
@@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- java: [ '-ea' ]
+ java: [ 20 ]
os: [ ubuntu-latest ]
name: JDK${{ matrix.java }} on ${{ matrix.os }}
@@ -19,7 +19,7 @@ jobs:
steps:
- name: Checkout source code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
diff --git a/.github/workflows/java-maven.yml b/.github/workflows/java-maven.yml
index f1197e5..411b138 100644
--- a/.github/workflows/java-maven.yml
+++ b/.github/workflows/java-maven.yml
@@ -1,10 +1,10 @@
-name: Java with Maven
+name: Java8+ with Maven
on: [ push, pull_request ]
jobs:
build-and-test-job:
- if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
+ if: github.event_name == 'pull_request' || startsWith(github.ref, 'refs/heads/develop') || startsWith(github.ref, 'refs/tags/v')
strategy:
fail-fast: false
matrix:
@@ -16,7 +16,7 @@ jobs:
steps:
- name: Checkout source code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
@@ -28,11 +28,31 @@ jobs:
java-version: ${{ matrix.java }}
cache: 'maven'
+ - name: Pre-download dependencies with Maven
+ run: mvn -U -B -ntp dependency:go-offline
+
- name: Build and (headless) test with Maven
uses: smithki/xvfb-action@v1.1.2
with:
run: mvn -U -B -ntp package
+ auto-merge-job:
+ needs: build-and-test-job
+ if: startsWith(github.repository, 'nbbrd/') && github.event_name == 'pull_request' && github.actor == 'dependabot[bot]'
+ permissions:
+ contents: write
+ pull-requests: write
+
+ name: Auto-merge on dependabot PR
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Merge PR
+ run: gh pr merge --auto --rebase "$PR_URL"
+ env:
+ PR_URL: ${{github.event.pull_request.html_url}}
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
+
snapshot-job:
needs: build-and-test-job
if: startsWith(github.repository, 'nbbrd/') && startsWith(github.ref, 'refs/heads/develop')
@@ -46,7 +66,7 @@ jobs:
steps:
- name: Checkout source code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
@@ -96,7 +116,7 @@ jobs:
steps:
- name: Checkout source code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 77764be..613257d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,10 +7,29 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
+## [3.1.0] - 2023-10-16
+
+This is a feature release of SDMX extensions for JDemetra+ v3.
+[JDemetra+ v3.1.1 or later](https://github.com/jdemetra/jdplus-main) version is required to run it.
+
+### Added
+
+- Allow configuration by environment variables
+
+### Fixed
+
+- Fix favicons transparency, cache and loading
+- Fix dimensions and attributes autocompletion
+
+### Changed
+
+- Bump sdmx-dl from 3.0.0-beta.11 to [3.0.0-beta.12](https://github.com/nbbrd/sdmx-dl/releases/tag/v3.0.0-beta.12)
+
## [3.0.0] - 2023-06-14
This is the **initial release** of SDMX extensions for JDemetra+ v3.
[JDemetra+ v3.0.2 or later](https://github.com/jdemetra/jdplus-main) version is required to run it.
-[Unreleased]: https://github.com/nbbrd/jdplus-sdmx/compare/v3.0.0...HEAD
+[Unreleased]: https://github.com/nbbrd/jdplus-sdmx/compare/v3.1.0...HEAD
+[3.1.0]: https://github.com/nbbrd/jdplus-sdmx/compare/v3.0.0...v3.1.0
[3.0.0]: https://github.com/nbbrd/jdplus-sdmx/releases/tag/v3.0.0
diff --git a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/pom.xml b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/pom.xml
index 92daf5e..79866ac 100644
--- a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/pom.xml
+++ b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/pom.xml
@@ -7,7 +7,7 @@
com.github.nbbrd.jdplus-sdmx
jdplus-sdmx-base-parent
- 3.0.0
+ 3.1.0
jdplus-sdmx-base-api
diff --git a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/internal/sdmx/base/api/SdmxCubeConnection.java b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/internal/sdmx/base/api/SdmxCubeConnection.java
index 246a322..b957c05 100644
--- a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/internal/sdmx/base/api/SdmxCubeConnection.java
+++ b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/internal/sdmx/base/api/SdmxCubeConnection.java
@@ -25,6 +25,7 @@
import jdplus.toolkit.base.tsp.cube.CubeId;
import jdplus.toolkit.base.tsp.cube.CubeSeries;
import jdplus.toolkit.base.tsp.cube.CubeSeriesWithData;
+import lombok.NonNull;
import nbbrd.design.VisibleForTesting;
import sdmxdl.*;
import sdmxdl.ext.SdmxCubeUtil;
@@ -45,22 +46,23 @@
@lombok.RequiredArgsConstructor
public final class SdmxCubeConnection implements CubeConnection {
- public static SdmxCubeConnection of(Connection connection, DataflowRef ref, List dimensions, String labelAttribute, String sourceLabel) throws IOException {
- Dataflow flow = connection.getFlow(ref);
- DataStructure dsd = connection.getStructure(ref);
+ public static SdmxCubeConnection of(Connection connection, FlowRef ref, List dimensions, String labelAttribute, String sourceLabel, boolean displayCodes) throws IOException {
+ Flow flow = connection.getFlow(ref);
+ Structure dsd = connection.getStructure(ref);
CubeId root = getOrLoadRoot(dimensions, dsd);
- return new SdmxCubeConnection(connection, flow, dsd, root, labelAttribute, sourceLabel);
+ return new SdmxCubeConnection(connection, flow, dsd, root, labelAttribute, sourceLabel, displayCodes);
}
private final Connection connection;
- private final Dataflow flow;
- private final DataStructure dsd;
+ private final Flow flow;
+ private final Structure dsd;
private final CubeId root;
private final String labelAttribute;
private final String sourceLabel;
+ private final boolean displayCodes;
@Override
- public Optional testConnection() {
+ public @NonNull Optional testConnection() {
try {
connection.testConnection();
return Optional.empty();
@@ -70,12 +72,12 @@ public Optional testConnection() {
}
@Override
- public CubeId getRoot() {
+ public @NonNull CubeId getRoot() {
return root;
}
@Override
- public Stream getAllSeries(CubeId ref) throws IOException {
+ public @NonNull Stream getAllSeries(@NonNull CubeId ref) throws IOException {
KeyConverter converter = KeyConverter.of(dsd, ref);
return SdmxCubeUtil
.getAllSeries(connection, flow.getRef(), converter.toKey(ref))
@@ -83,7 +85,7 @@ public Stream getAllSeries(CubeId ref) throws IOException {
}
@Override
- public Stream getAllSeriesWithData(CubeId ref) throws IOException {
+ public @NonNull Stream getAllSeriesWithData(@NonNull CubeId ref) throws IOException {
KeyConverter converter = KeyConverter.of(dsd, ref);
return SdmxCubeUtil
.getAllSeriesWithData(connection, flow.getRef(), converter.toKey(ref))
@@ -91,7 +93,7 @@ public Stream getAllSeriesWithData(CubeId ref) throws IOExce
}
@Override
- public Optional getSeries(CubeId id) throws IOException {
+ public @NonNull Optional getSeries(@NonNull CubeId id) throws IOException {
KeyConverter converter = KeyConverter.of(dsd, id);
return SdmxCubeUtil
.getSeries(connection, flow.getRef(), converter.toKey(id))
@@ -99,7 +101,7 @@ public Optional getSeries(CubeId id) throws IOException {
}
@Override
- public Optional getSeriesWithData(CubeId ref) throws IOException {
+ public @NonNull Optional getSeriesWithData(@NonNull CubeId ref) throws IOException {
KeyConverter converter = KeyConverter.of(dsd, ref);
return SdmxCubeUtil
.getSeriesWithData(connection, flow.getRef(), converter.toKey(ref))
@@ -107,7 +109,7 @@ public Optional getSeriesWithData(CubeId ref) throws IOExcep
}
@Override
- public Stream getChildren(CubeId ref) throws IOException {
+ public @NonNull Stream getChildren(@NonNull CubeId ref) throws IOException {
KeyConverter converter = KeyConverter.of(dsd, ref);
String dimensionId = ref.getDimensionId(ref.getLevel());
int dimensionIndex = SdmxCubeUtil.getDimensionIndexById(dsd, dimensionId).orElseThrow(RuntimeException::new);
@@ -118,12 +120,12 @@ public Stream getChildren(CubeId ref) throws IOException {
}
@Override
- public String getDisplayName() {
+ public @NonNull String getDisplayName() {
return String.format(Locale.ROOT, "%s ~ %s", sourceLabel, flow.getName());
}
@Override
- public String getDisplayName(CubeId id) {
+ public @NonNull String getDisplayName(CubeId id) {
if (id.isVoid()) {
return "All";
}
@@ -131,11 +133,13 @@ public String getDisplayName(CubeId id) {
}
@Override
- public String getDisplayNodeName(CubeId id) {
+ public @NonNull String getDisplayNodeName(CubeId id) {
if (id.isVoid()) {
return "All";
}
- return getDisplayNodeName(dsd, id);
+ return displayCodes
+ ? getDimensionCodeId(id)
+ : getDimensionCodeLabel(id, dsd);
}
@Override
@@ -152,7 +156,12 @@ private static CubeSeriesWithData cubeSeriesWithDataOf(KeyConverter converter, S
return new CubeSeriesWithData(converter.fromKey(series.getKey()), series.getMeta().get(labelAttribute), series.getMeta(), getData(series));
}
- private static String getDisplayNodeName(DataStructure dsd, CubeId ref) {
+ private static String getDimensionCodeId(CubeId ref) {
+ int index = ref.getLevel() - 1;
+ return ref.getDimensionValue(index);
+ }
+
+ private static String getDimensionCodeLabel(CubeId ref, Structure dsd) {
if (ref.isRoot()) {
return "Invalid reference '" + dump(ref) + "'";
}
@@ -169,7 +178,7 @@ private static String dump(CubeId ref) {
}
@VisibleForTesting
- static Key getKey(DataStructure dsd, CubeId ref) {
+ static Key getKey(Structure dsd, CubeId ref) {
if (ref.isRoot()) {
return Key.ALL;
}
@@ -186,11 +195,11 @@ static Key getKey(DataStructure dsd, CubeId ref) {
@lombok.RequiredArgsConstructor
static final class KeyConverter {
- static KeyConverter of(DataStructure dsd, CubeId ref) {
+ static KeyConverter of(Structure dsd, CubeId ref) {
return new KeyConverter(dsd, new CubeIdBuilder(dsd, ref));
}
- final DataStructure dsd;
+ final Structure dsd;
final CubeIdBuilder builder;
public Key toKey(CubeId a) {
@@ -208,7 +217,7 @@ private static final class CubeIdBuilder {
private final int[] indices;
private final String[] dimValues;
- CubeIdBuilder(DataStructure dsd, CubeId ref) {
+ CubeIdBuilder(Structure dsd, CubeId ref) {
this.ref = ref;
this.indices = new int[ref.getDepth()];
for (int i = 0; i < indices.length; i++) {
@@ -271,13 +280,13 @@ private static TsUnit getTsUnit(Obs obs) {
}
}
- private static CubeId getOrLoadRoot(List dimensions, DataStructure dsd) {
+ private static CubeId getOrLoadRoot(List dimensions, Structure dsd) {
return dimensions.isEmpty()
? CubeId.root(loadDefaultDimIds(dsd))
: CubeId.root(dimensions);
}
- private static List loadDefaultDimIds(DataStructure dsd) {
+ private static List loadDefaultDimIds(Structure dsd) {
return dsd
.getDimensions()
.stream()
diff --git a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/internal/sdmx/base/api/SdmxCubeItems.java b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/internal/sdmx/base/api/SdmxCubeItems.java
index 146ec46..5d78ba5 100644
--- a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/internal/sdmx/base/api/SdmxCubeItems.java
+++ b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/internal/sdmx/base/api/SdmxCubeItems.java
@@ -18,7 +18,7 @@
import jdplus.sdmx.base.api.file.SdmxFileBean;
import jdplus.toolkit.base.tsp.HasFilePaths;
-import sdmxdl.file.SdmxFileSource;
+import sdmxdl.file.FileSource;
import java.io.File;
import java.io.FileNotFoundException;
@@ -29,16 +29,12 @@
@lombok.experimental.UtilityClass
public class SdmxCubeItems {
- public static SdmxFileSource resolveFileSet(HasFilePaths paths, SdmxFileBean bean) throws FileNotFoundException {
- SdmxFileSource.Builder result = SdmxFileSource.builder().data(paths.resolveFilePath(bean.getFile()));
+ public static FileSource resolveFileSet(HasFilePaths paths, SdmxFileBean bean) throws FileNotFoundException {
+ FileSource.Builder result = FileSource.builder().data(paths.resolveFilePath(bean.getFile()));
File structure = bean.getStructureFile();
if (structure != null && !structure.toString().isEmpty()) {
result.structure(paths.resolveFilePath(structure));
}
- String dialect = bean.getDialect();
- if (dialect != null && !dialect.isEmpty()) {
- result.dialect(dialect);
- }
return result.build();
}
}
diff --git a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/internal/sdmx/base/api/SdmxPropertiesSupport.java b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/internal/sdmx/base/api/SdmxPropertiesSupport.java
index 1098c61..dd9c950 100644
--- a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/internal/sdmx/base/api/SdmxPropertiesSupport.java
+++ b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/internal/sdmx/base/api/SdmxPropertiesSupport.java
@@ -18,6 +18,9 @@
import jdplus.sdmx.base.api.HasSdmxProperties;
import lombok.AccessLevel;
+import lombok.NonNull;
+import nbbrd.io.function.IORunnable;
+import sdmxdl.Languages;
import sdmxdl.SdmxManager;
import java.util.concurrent.atomic.AtomicReference;
@@ -27,21 +30,25 @@
* @author Philippe Charles
*/
@lombok.AllArgsConstructor(access = AccessLevel.PRIVATE)
-public final class SdmxPropertiesSupport implements HasSdmxProperties {
+public final class SdmxPropertiesSupport> implements HasSdmxProperties {
- public static HasSdmxProperties of(Supplier defaultManager, Runnable onManagerChange) {
- return new SdmxPropertiesSupport(
- defaultManager,
- new AtomicReference<>(defaultManager.get()),
- onManagerChange);
+ public static > HasSdmxProperties of(Supplier defaultManager, Runnable onManagerChange) {
+ return new SdmxPropertiesSupport<>(
+ defaultManager, new AtomicReference<>(defaultManager.get()), onManagerChange,
+ () -> Languages.ANY, new AtomicReference<>(Languages.ANY), IORunnable.noOp().asUnchecked()
+ );
}
private final Supplier defaultManager;
private final AtomicReference manager;
private final Runnable onManagerChange;
+ private final Supplier defaultLanguages;
+ private final AtomicReference languages;
+ private final Runnable onLanguagesChange;
+
@Override
- public M getSdmxManager() {
+ public @NonNull M getSdmxManager() {
return manager.get();
}
@@ -52,4 +59,17 @@ public void setSdmxManager(M manager) {
onManagerChange.run();
}
}
+
+ @Override
+ public @NonNull Languages getLanguages() {
+ return languages.get();
+ }
+
+ @Override
+ public void setLanguages(Languages languages) {
+ Languages old = this.languages.get();
+ if (this.languages.compareAndSet(old, languages != null ? languages : defaultLanguages.get())) {
+ onLanguagesChange.run();
+ }
+ }
}
diff --git a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/HasSdmxProperties.java b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/HasSdmxProperties.java
index 1b263f8..440af67 100644
--- a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/HasSdmxProperties.java
+++ b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/HasSdmxProperties.java
@@ -16,19 +16,23 @@
*/
package jdplus.sdmx.base.api;
+import lombok.NonNull;
import nbbrd.design.ThreadSafe;
-import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
+import sdmxdl.Languages;
import sdmxdl.SdmxManager;
/**
* @author Philippe Charles
*/
@ThreadSafe
-public interface HasSdmxProperties {
+public interface HasSdmxProperties> {
- @NonNull
- M getSdmxManager();
+ @NonNull M getSdmxManager();
void setSdmxManager(@Nullable M manager);
+
+ @NonNull Languages getLanguages();
+
+ void setLanguages(@Nullable Languages languages);
}
diff --git a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/file/SdmxFileBean.java b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/file/SdmxFileBean.java
index a1943d1..f0841ea 100644
--- a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/file/SdmxFileBean.java
+++ b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/file/SdmxFileBean.java
@@ -31,6 +31,7 @@ public final class SdmxFileBean implements FileBean {
private File file;
private File structureFile;
+ @Deprecated
private String dialect;
private List dimensions;
private String labelAttribute;
diff --git a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/file/SdmxFileProvider.java b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/file/SdmxFileProvider.java
index b142a15..4a13e98 100644
--- a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/file/SdmxFileProvider.java
+++ b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/file/SdmxFileProvider.java
@@ -16,23 +16,24 @@
*/
package jdplus.sdmx.base.api.file;
-import jdplus.toolkit.base.api.timeseries.TsProvider;
+import internal.sdmx.base.api.SdmxCubeConnection;
+import internal.sdmx.base.api.SdmxCubeItems;
+import internal.sdmx.base.api.SdmxPropertiesSupport;
import jdplus.sdmx.base.api.HasSdmxProperties;
+import jdplus.toolkit.base.api.timeseries.TsProvider;
import jdplus.toolkit.base.tsp.*;
import jdplus.toolkit.base.tsp.cube.CubeConnection;
import jdplus.toolkit.base.tsp.cube.CubeSupport;
import jdplus.toolkit.base.tsp.stream.HasTsStream;
import jdplus.toolkit.base.tsp.stream.TsStreamAsProvider;
import jdplus.toolkit.base.tsp.util.ResourcePool;
-import internal.sdmx.base.api.SdmxCubeConnection;
-import internal.sdmx.base.api.SdmxCubeItems;
-import internal.sdmx.base.api.SdmxPropertiesSupport;
+import lombok.NonNull;
import nbbrd.io.Resource;
import nbbrd.service.ServiceProvider;
import sdmxdl.Connection;
-import sdmxdl.DataflowRef;
+import sdmxdl.FlowRef;
import sdmxdl.file.SdmxFileManager;
-import sdmxdl.file.SdmxFileSource;
+import sdmxdl.file.FileSource;
import java.io.File;
import java.io.IOException;
@@ -82,12 +83,12 @@ public SdmxFileProvider() {
}
@Override
- public String getDisplayName() {
+ public @NonNull String getDisplayName() {
return "SDMX Files";
}
@Override
- public String getFileDescription() {
+ public @NonNull String getFileDescription() {
return "SDMX file";
}
@@ -97,34 +98,34 @@ public boolean accept(File pathname) {
}
@Override
- public String getDisplayName(DataSource dataSource) throws IllegalArgumentException {
+ public @NonNull String getDisplayName(@NonNull DataSource dataSource) throws IllegalArgumentException {
return getSourceLabel(decodeBean(dataSource));
}
@Override
- public String getDisplayName(DataSet dataSet) throws IllegalArgumentException {
+ public @NonNull String getDisplayName(@NonNull DataSet dataSet) throws IllegalArgumentException {
return cubeSupport.getDisplayName(dataSet);
}
@Override
- public String getDisplayName(IOException exception) throws IllegalArgumentException {
+ public @NonNull String getDisplayName(@NonNull IOException exception) throws IllegalArgumentException {
return cubeSupport.getDisplayName(exception);
}
@Override
- public String getDisplayNodeName(DataSet dataSet) throws IllegalArgumentException {
+ public @NonNull String getDisplayNodeName(@NonNull DataSet dataSet) throws IllegalArgumentException {
return cubeSupport.getDisplayNodeName(dataSet);
}
private static CubeConnection openConnection(DataSource dataSource, HasSdmxProperties properties, HasFilePaths paths, SdmxFileParam param) throws IOException {
SdmxFileBean bean = param.get(dataSource);
- SdmxFileSource files = SdmxCubeItems.resolveFileSet(paths, bean);
+ FileSource files = SdmxCubeItems.resolveFileSet(paths, bean);
- DataflowRef flow = files.asDataflowRef();
+ FlowRef flow = files.asDataflowRef();
- Connection conn = properties.getSdmxManager().getConnection(files);
+ Connection conn = properties.getSdmxManager().getConnection(files, properties.getLanguages());
try {
- return SdmxCubeConnection.of(conn, flow, bean.getDimensions(), bean.getLabelAttribute(), getSourceLabel(bean));
+ return SdmxCubeConnection.of(conn, flow, bean.getDimensions(), bean.getLabelAttribute(), getSourceLabel(bean), false);
} catch (IOException ex) {
Resource.ensureClosed(ex, conn);
throw ex;
diff --git a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/web/SdmxWebProvider.java b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/web/SdmxWebProvider.java
index 63668bc..17ae313 100644
--- a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/web/SdmxWebProvider.java
+++ b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/main/java/jdplus/sdmx/base/api/web/SdmxWebProvider.java
@@ -16,33 +16,26 @@
*/
package jdplus.sdmx.base.api.web;
-import jdplus.toolkit.base.api.timeseries.Ts;
-import jdplus.toolkit.base.api.timeseries.TsInformationType;
-import jdplus.toolkit.base.api.timeseries.TsProvider;
+import internal.sdmx.base.api.SdmxCubeConnection;
+import internal.sdmx.base.api.SdmxPropertiesSupport;
import jdplus.sdmx.base.api.HasSdmxProperties;
+import jdplus.toolkit.base.api.timeseries.TsProvider;
import jdplus.toolkit.base.tsp.*;
-import jdplus.toolkit.base.tsp.DataSet;
import jdplus.toolkit.base.tsp.cube.BulkCubeConnection;
import jdplus.toolkit.base.tsp.cube.CubeConnection;
import jdplus.toolkit.base.tsp.cube.CubeSupport;
import jdplus.toolkit.base.tsp.stream.HasTsStream;
import jdplus.toolkit.base.tsp.stream.TsStreamAsProvider;
-import jdplus.toolkit.base.tsp.util.IOCacheFactoryLoader;
+import jdplus.toolkit.base.tsp.util.ShortLivedCachingLoader;
import jdplus.toolkit.base.tsp.util.ResourcePool;
-import internal.sdmx.base.api.SdmxCubeConnection;
-import internal.sdmx.base.api.SdmxPropertiesSupport;
import nbbrd.io.Resource;
import nbbrd.service.ServiceProvider;
-import org.checkerframework.checker.nullness.qual.NonNull;
-import sdmxdl.*;
+import sdmxdl.Connection;
+import sdmxdl.FlowRef;
import sdmxdl.web.SdmxWebManager;
import java.io.IOException;
-import java.util.Comparator;
-import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
/**
* @author Philippe Charles
@@ -83,12 +76,12 @@ public SdmxWebProvider() {
this.mutableListSupport = HasDataSourceMutableList.of(NAME, pool::remove);
this.monikerSupport = HasDataMoniker.usingUri(NAME);
this.beanSupport = HasDataSourceBean.of(NAME, param, param.getVersion());
- this.cubeSupport = CubeSupport.of(NAME, pool.asFactory(o -> openConnection(o, properties, param)), param::getCubeIdParam);
+ this.cubeSupport = CubeSupport.of(NAME, pool.asFactory(o -> openConnection(o, properties, param, displayCodes.get())), param::getCubeIdParam);
this.tsSupport = TsStreamAsProvider.of(NAME, cubeSupport, monikerSupport, pool::clear);
}
@Override
- public String getDisplayName() {
+ public @lombok.NonNull String getDisplayName() {
return "SDMX Web Services";
}
@@ -103,50 +96,15 @@ public void setDisplayCodes(boolean displayCodes) {
}
}
- @NonNull
- public Ts getTs(@NonNull SdmxWebBean bean, @NonNull Key key, @NonNull TsInformationType type) throws IOException {
- String[] dimsInNaturalOrder = dimsInNaturalOrder(getSdmxManager(), bean.getSource(), DataflowRef.parse(bean.getFlow()));
-
- if (!Key.ALL.equals(key) && key.size() != dimsInNaturalOrder.length) {
- throw new IllegalArgumentException("Invalid key '" + key + "'");
- }
-
- // we need to sort dimensions by wildcard in key because of provider issue
- Comparator c = (l, r) -> key.isWildcard(l) ? (key.isWildcard(r) ? 0 : 1) : (key.isWildcard(r) ? -1 : 0);
- List sortedDims = IntStream.range(0, dimsInNaturalOrder.length).boxed()
- .sorted(c.thenComparingInt(o -> o))
- .map(o -> dimsInNaturalOrder[o])
- .collect(Collectors.toList());
- bean.setDimensions(sortedDims);
-
- DataSet.Builder b = DataSet.builder(encodeBean(bean), key.isSeries() ? DataSet.Kind.SERIES : DataSet.Kind.COLLECTION);
- if (!Key.ALL.equals(key)) {
- IntStream.range(0, dimsInNaturalOrder.length)
- .filter(o -> !key.isWildcard(o))
- .forEach(o -> b.parameter(dimsInNaturalOrder[o], key.get(o)));
- }
- return getTs(toMoniker(b.build()), type);
- }
-
- private static String[] dimsInNaturalOrder(SdmxWebManager supplier, String source, DataflowRef flow) throws IOException {
- try (Connection c = supplier.getConnection(source)) {
- return c.getStructure(flow)
- .getDimensions()
- .stream()
- .map(Dimension::getId)
- .toArray(String[]::new);
- }
- }
-
- private static CubeConnection openConnection(DataSource source, HasSdmxProperties properties, SdmxWebParam param) throws IOException {
+ private static CubeConnection openConnection(DataSource source, HasSdmxProperties properties, SdmxWebParam param, boolean displayCodes) throws IOException {
SdmxWebBean bean = param.get(source);
- DataflowRef flow = DataflowRef.parse(bean.getFlow());
+ FlowRef flow = FlowRef.parse(bean.getFlow());
- Connection conn = properties.getSdmxManager().getConnection(bean.getSource());
+ Connection conn = properties.getSdmxManager().getConnection(bean.getSource(), properties.getLanguages());
try {
- CubeConnection result = SdmxCubeConnection.of(conn, flow, bean.getDimensions(), bean.getLabelAttribute(), bean.getSource());
- return BulkCubeConnection.of(result, bean.getCache(), IOCacheFactoryLoader.get());
+ CubeConnection result = SdmxCubeConnection.of(conn, flow, bean.getDimensions(), bean.getLabelAttribute(), bean.getSource(), displayCodes);
+ return BulkCubeConnection.of(result, bean.getCache(), ShortLivedCachingLoader.get());
} catch (IOException ex) {
Resource.ensureClosed(ex, conn);
throw ex;
diff --git a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/test/java/_demo/SdmxFakeWebDemo.java b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/test/java/_demo/SdmxFakeWebDemo.java
index 621a387..7bc60bc 100644
--- a/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/test/java/_demo/SdmxFakeWebDemo.java
+++ b/jdplus-sdmx-base/jdplus-sdmx-base-parent/jdplus-sdmx-base-api/src/test/java/_demo/SdmxFakeWebDemo.java
@@ -23,7 +23,7 @@
import sdmxdl.Feature;
import sdmxdl.web.SdmxWebManager;
import tests.sdmxdl.api.RepoSamples;
-import tests.sdmxdl.web.MockedDriver;
+import tests.sdmxdl.web.spi.MockedDriver;
import java.io.IOException;
import java.util.EnumSet;
diff --git a/jdplus-sdmx-base/jdplus-sdmx-base-parent/pom.xml b/jdplus-sdmx-base/jdplus-sdmx-base-parent/pom.xml
index 4e6234c..c44acee 100644
--- a/jdplus-sdmx-base/jdplus-sdmx-base-parent/pom.xml
+++ b/jdplus-sdmx-base/jdplus-sdmx-base-parent/pom.xml
@@ -5,7 +5,7 @@
com.github.nbbrd.jdplus-sdmx
jdplus-sdmx-base
- 3.0.0
+ 3.1.0
jdplus-sdmx-base-parent
diff --git a/jdplus-sdmx-base/pom.xml b/jdplus-sdmx-base/pom.xml
index 42594bd..083c0eb 100644
--- a/jdplus-sdmx-base/pom.xml
+++ b/jdplus-sdmx-base/pom.xml
@@ -6,7 +6,7 @@
com.github.nbbrd.jdplus-sdmx
jdplus-sdmx
- 3.0.0
+ 3.1.0
jdplus-sdmx-base
diff --git a/jdplus-sdmx-bom/pom.xml b/jdplus-sdmx-bom/pom.xml
index 4b47a23..68b82d4 100644
--- a/jdplus-sdmx-bom/pom.xml
+++ b/jdplus-sdmx-bom/pom.xml
@@ -7,7 +7,7 @@
com.github.nbbrd.jdplus-sdmx
jdplus-sdmx
- 3.0.0
+ 3.1.0
jdplus-sdmx-bom
@@ -20,13 +20,18 @@
- com.github.nbbrd.jdplus-sdmx
- jdplus-sdmx-cli-plugin
+ ${project.groupId}
+ jdplus-sdmx-base
${project.version}
- com.github.nbbrd.jdplus-sdmx
- jdplus-sdmx-desktop-plugin
+ ${project.groupId}
+ jdplus-sdmx-cli
+ ${project.version}
+
+
+ ${project.groupId}
+ jdplus-sdmx-desktop
${project.version}
@@ -37,7 +42,7 @@
org.codehaus.mojo
flatten-maven-plugin
- 1.4.1
+ 1.5.0
bom
${project.build.directory}
@@ -84,7 +89,7 @@
org.jreleaser
jreleaser-maven-plugin
- 1.5.1
+ 1.8.0
release-assets
diff --git a/jdplus-sdmx-cli/jdplus-sdmx-cli-plugin/pom.xml b/jdplus-sdmx-cli/jdplus-sdmx-cli-plugin/pom.xml
index 7e72c9c..b4c8172 100644
--- a/jdplus-sdmx-cli/jdplus-sdmx-cli-plugin/pom.xml
+++ b/jdplus-sdmx-cli/jdplus-sdmx-cli-plugin/pom.xml
@@ -6,7 +6,7 @@
com.github.nbbrd.jdplus-sdmx
jdplus-sdmx-cli
- 3.0.0
+ 3.1.0
jdplus-sdmx-cli-plugin
diff --git a/jdplus-sdmx-cli/pom.xml b/jdplus-sdmx-cli/pom.xml
index d43ac03..680483e 100644
--- a/jdplus-sdmx-cli/pom.xml
+++ b/jdplus-sdmx-cli/pom.xml
@@ -6,7 +6,7 @@
com.github.nbbrd.jdplus-sdmx
jdplus-sdmx
- 3.0.0
+ 3.1.0
jdplus-sdmx-cli
diff --git a/jdplus-sdmx-desktop/jdplus-sdmx-desktop-plugin/pom.xml b/jdplus-sdmx-desktop/jdplus-sdmx-desktop-plugin/pom.xml
index cbd27b0..476ef7d 100644
--- a/jdplus-sdmx-desktop/jdplus-sdmx-desktop-plugin/pom.xml
+++ b/jdplus-sdmx-desktop/jdplus-sdmx-desktop-plugin/pom.xml
@@ -6,7 +6,7 @@
com.github.nbbrd.jdplus-sdmx
jdplus-sdmx-desktop
- 3.0.0
+ 3.1.0
jdplus-sdmx-desktop-plugin
@@ -100,6 +100,10 @@
org.netbeans.api
*
+
+ com.github.nbbrd.java-io-util
+ *
+
@@ -113,46 +117,8 @@
com.github.nbbrd.sdmx-dl
- sdmx-dl-provider-ri
+ sdmx-dl-standalone
${sdmx-dl.version}
-
-
- com.github.nbbrd.java-io-util
- *
-
-
-
-
- com.github.nbbrd.sdmx-dl
- sdmx-dl-format-kryo
- ${sdmx-dl.version}
-
-
- com.github.nbbrd.java-io-util
- *
-
-
-
-
- com.github.nbbrd.java-net-proxy
- java-net-proxy
- 1.0.1
-
-
- io.github.hakky54
- sslcontext-kickstart
- 8.0.0
-
-
- slf4j-api
- org.slf4j
-
-
-
-
- org.slf4j
- slf4j-jdk14
- 2.0.7
com.github.nbbrd.java-desktop-util
diff --git a/jdplus-sdmx-desktop/jdplus-sdmx-desktop-plugin/src/main/java/internal/sdmx/desktop/plugin/Caches.java b/jdplus-sdmx-desktop/jdplus-sdmx-desktop-plugin/src/main/java/internal/sdmx/desktop/plugin/Caches.java
new file mode 100644
index 0000000..f5dcc9d
--- /dev/null
+++ b/jdplus-sdmx-desktop/jdplus-sdmx-desktop-plugin/src/main/java/internal/sdmx/desktop/plugin/Caches.java
@@ -0,0 +1,106 @@
+package internal.sdmx.desktop.plugin;
+
+import jdplus.toolkit.base.tsp.util.ShortLivedCache;
+import jdplus.toolkit.base.tsp.util.ShortLivedCachingLoader;
+
+import java.time.Duration;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+public final class Caches {
+
+ private Caches() {
+ throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
+ }
+
+ public static ConcurrentMap asConcurrentMap(ShortLivedCache cache) {
+ return new ConcurrentMap() {
+ @Override
+ public V putIfAbsent(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean remove(Object key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean replace(K key, V oldValue, V newValue) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public V replace(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int size() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public V get(Object key) {
+ return cache.get((K) key);
+ }
+
+ @Override
+ public V put(K key, V value) {
+ cache.put(key, value);
+ return null;
+ }
+
+ @Override
+ public V remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void putAll(Map extends K, ? extends V> m) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set keySet() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Collection values() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set> entrySet() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ public static ConcurrentMap ttlCacheAsMap(Duration duration) {
+ return asConcurrentMap(ShortLivedCachingLoader.get().ofTtl(duration));
+ }
+}
diff --git a/jdplus-sdmx-desktop/jdplus-sdmx-desktop-plugin/src/main/java/internal/sdmx/desktop/plugin/CustomNetwork.java b/jdplus-sdmx-desktop/jdplus-sdmx-desktop-plugin/src/main/java/internal/sdmx/desktop/plugin/CustomNetwork.java
deleted file mode 100644
index 6a8ba6d..0000000
--- a/jdplus-sdmx-desktop/jdplus-sdmx-desktop-plugin/src/main/java/internal/sdmx/desktop/plugin/CustomNetwork.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package internal.sdmx.desktop.plugin;
-
-import internal.http.curl.CurlHttpURLConnection;
-import java.net.ProxySelector;
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLSocketFactory;
-import nbbrd.net.proxy.SystemProxySelector;
-import nl.altindag.ssl.SSLFactory;
-import sdmxdl.web.Network;
-import sdmxdl.web.URLConnectionFactory;
-
-@lombok.Value
-@lombok.Builder(toBuilder = true)
-public final class CustomNetwork implements Network {
-
- boolean curlBackend;
- boolean autoProxy;
- boolean defaultTrustMaterial;
- boolean systemTrustMaterial;
-
- @lombok.NonNull
- @lombok.Getter(lazy = true)
- private final ProxySelector lazyProxySelector = initProxySelector();
-
- @lombok.NonNull
- @lombok.Getter(lazy = true)
- private final SSLFactory lazySSLFactory = initSSLFactory();
-
- private ProxySelector initProxySelector() {
- return autoProxy ? SystemProxySelector.ofServiceLoader() : ProxySelector.getDefault();
- }
-
- private SSLFactory initSSLFactory() {
- SSLFactory.Builder result = SSLFactory.builder();
- if (defaultTrustMaterial) {
- result.withDefaultTrustMaterial();
- }
- if (systemTrustMaterial) {
- result.withSystemTrustMaterial();
- }
- return result.build();
- }
-
- @Override
- public HostnameVerifier getHostnameVerifier() {
- return getLazySSLFactory().getHostnameVerifier();
- }
-
- @Override
- public ProxySelector getProxySelector() {
- return getLazyProxySelector();
- }
-
- @Override
- public SSLSocketFactory getSSLSocketFactory() {
- return getLazySSLFactory().getSslSocketFactory();
- }
-
- @Override
- public URLConnectionFactory getURLConnectionFactory() {
- return curlBackend ? CurlHttpURLConnection::of : URLConnectionFactory.getDefault();
- }
-}
diff --git a/jdplus-sdmx-desktop/jdplus-sdmx-desktop-plugin/src/main/java/internal/sdmx/desktop/plugin/SdmxAutoCompletion.java b/jdplus-sdmx-desktop/jdplus-sdmx-desktop-plugin/src/main/java/internal/sdmx/desktop/plugin/SdmxAutoCompletion.java
index b600e27..c0a7068 100644
--- a/jdplus-sdmx-desktop/jdplus-sdmx-desktop-plugin/src/main/java/internal/sdmx/desktop/plugin/SdmxAutoCompletion.java
+++ b/jdplus-sdmx-desktop/jdplus-sdmx-desktop-plugin/src/main/java/internal/sdmx/desktop/plugin/SdmxAutoCompletion.java
@@ -1,168 +1,115 @@
/*
* Copyright 2017 National Bank of Belgium
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
+ *
+ * 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
+ *
+ * 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
+ * See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
package internal.sdmx.desktop.plugin;
-import sdmxdl.Dataflow;
-import sdmxdl.DataflowRef;
-import sdmxdl.Dimension;
-import sdmxdl.LanguagePriorityList;
-import sdmxdl.web.SdmxWebManager;
-import sdmxdl.web.SdmxWebSource;
-import jdplus.toolkit.desktop.plugin.TsManager;
-import jdplus.sdmx.base.api.web.SdmxWebProvider;
import ec.util.completion.AutoCompletionSource;
-import static ec.util.completion.AutoCompletionSource.Behavior.ASYNC;
-import static ec.util.completion.AutoCompletionSource.Behavior.NONE;
-import static ec.util.completion.AutoCompletionSource.Behavior.SYNC;
import ec.util.completion.ExtAutoCompletionSource;
import ec.util.completion.swing.CustomListCellRenderer;
-import java.io.IOException;
-import java.net.Proxy;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLConnection;
+import internal.sdmx.base.api.SdmxCubeItems;
+import jdplus.sdmx.base.api.HasSdmxProperties;
+import jdplus.sdmx.base.api.file.SdmxFileBean;
+import jdplus.sdmx.base.api.file.SdmxFileProvider;
+import jdplus.sdmx.base.api.web.SdmxWebBean;
+import jdplus.sdmx.base.api.web.SdmxWebProvider;
+import lombok.NonNull;
+import sdmxdl.*;
+import sdmxdl.file.FileSource;
+import sdmxdl.web.SdmxWebManager;
+import sdmxdl.web.WebSource;
+
+import javax.swing.*;
+import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Comparator;
-import java.util.HashMap;
import java.util.List;
+import java.util.Optional;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Predicate;
import java.util.function.Supplier;
+
+import static ec.util.completion.AutoCompletionSource.Behavior.*;
import static java.util.stream.Collectors.toList;
-import javax.net.ssl.HttpsURLConnection;
-import javax.swing.Icon;
-import javax.swing.ImageIcon;
-import javax.swing.JList;
-import javax.swing.ListCellRenderer;
-import nbbrd.desktop.favicon.DomainName;
-import nbbrd.desktop.favicon.FaviconRef;
-import nbbrd.desktop.favicon.FaviconSupport;
-import nbbrd.desktop.favicon.URLConnectionFactory;
-import org.openide.util.ImageUtilities;
-import sdmxdl.Attribute;
-import sdmxdl.Connection;
-import sdmxdl.SdmxManager;
-import sdmxdl.SdmxSource;
-import sdmxdl.ext.Registry;
-import sdmxdl.ext.spi.Dialect;
-import sdmxdl.web.Network;
/**
- *
* @author Philippe Charles
*/
public abstract class SdmxAutoCompletion {
- public abstract AutoCompletionSource getSource();
+ public abstract @NonNull AutoCompletionSource getSource();
- public abstract ListCellRenderer getRenderer();
+ public abstract @NonNull ListCellRenderer> getRenderer();
- public static SdmxAutoCompletion onDialect(Registry registry) {
- return new DialectCompletion(registry);
+ public static @NonNull SdmxAutoCompletion onWebSource(@NonNull SdmxWebProvider provider) {
+ return new WebSourceCompletion(provider);
}
- public static SdmxAutoCompletion onWebSource(SdmxWebManager manager) {
- return new WebSourceCompletion(manager);
+ public static @NonNull SdmxAutoCompletion onFlow(@NonNull SdmxWebProvider provider, @NonNull SdmxWebBean bean, @NonNull ConcurrentMap