diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000..a514403b
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,132 @@
+# This is a basic workflow to help you get started with MATLAB Actions
+
+name: SDMX Build and test
+
+# Controls when the action will run.
+on:
+ # Triggers the workflow on push or pull request events but only for the main branch
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+jobs:
+ build-java:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ # Setup job
+ - name: Set up JDK 8 for x64
+ uses: actions/setup-java@v3
+ with:
+ java-version: '8'
+ distribution: 'temurin'
+ architecture: x64
+ - run: echo $JAVA_HOME
+
+ # Build project according to SDMX instructions
+ - name: Build JAR
+ run: |
+ cd JAVA && \
+ mvn clean package -Dmaven.test.skip.exec
+
+ # Keep JAR file to use in MATLAB
+ - name: Archive MATLAB JAR for next job
+ uses: actions/upload-artifact@v3
+ with:
+ name: SDMX
+ path: JAVA/target/SDMX-3.1.0.jar
+ if-no-files-found: error
+ retention-days: 1
+
+ build-test-matlab:
+ permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+ needs: build-java
+ # The type of runner that the job will run on
+ runs-on: ubuntu-latest
+
+ # Steps represent a sequence of tasks that will be executed as part of the job
+ steps:
+ # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
+ - uses: actions/checkout@v4
+
+ - name: Download a single artifact
+ uses: actions/download-artifact@v3
+ with:
+ name: SDMX
+ path: MATLAB/tbx/lib
+
+ # Sets up MATLAB on the GitHub Actions runner
+ - name: Setup MATLAB
+ uses: matlab-actions/setup-matlab@v1
+ with:
+ release: R2024a
+
+ # Run buildtool to test and package MATLAB.
+ - name: Run buildtool
+ uses: matlab-actions/run-command@v1
+ with:
+ command: openProject('MATLAB/SDMX.prj'), buildtool
+
+ # Upload MATLAB Toolbox, it won't be there if the test failed
+ - name: Archive MATLAB Toolbox
+ uses: actions/upload-artifact@v3
+ with:
+ name: MatSDMX
+ path: |
+ MATLAB/releases/SDMX.mltbx
+ if-no-files-found: ignore
+
+ # Set up pages to show reports. This needs to run independent of the previous results.
+ # Previous here is buildtool, since upload is canceled on failure
+ - name: Setup Pages
+ if: success() || failure()
+ uses: actions/configure-pages@v3
+
+ # Upload test reports
+ - name: Upload Artifact
+ if: success() || failure()
+ uses: actions/upload-pages-artifact@v2
+ with:
+ # upload entire directory
+ path: MATLAB/tests/reports
+
+ deploy-results:
+ runs-on: ubuntu-latest
+ needs: build-test-matlab
+ if: ${{ always() }}
+
+ permissions:
+ pages: write
+ id-token: write
+
+ environment:
+ # environment created automatically by GitHub
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+
+ steps:
+ # Deploy reports to GitHub Pages
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v2
+
+ # Publish the report address to GitHub Pages
+ - name: Create Annotation with links
+ run: |
+ echo 'Test results report' >> $GITHUB_STEP_SUMMARY
+ echo 'Code coverage report' >> $GITHUB_STEP_SUMMARY
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
index de25ca9c..95f57811 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,8 @@ JAVA/bin/
JAVA/target/
maven-system
target
+
+MATLAB/.buildtool/
+MATLAB/releases/
+MATLAB/tbx/lib/
+MATLAB/tests/reports/
diff --git a/BUILD b/BUILD
index 9e797aa0..523101cf 100644
--- a/BUILD
+++ b/BUILD
@@ -1 +1 @@
-20230210-1402
\ No newline at end of file
+20240409-0913
\ No newline at end of file
diff --git a/JAVA/build.xml b/JAVA/build.xml
index e399391a..4aff29bb 100644
--- a/JAVA/build.xml
+++ b/JAVA/build.xml
@@ -40,6 +40,8 @@
+
+
@@ -55,8 +57,6 @@
-
-
diff --git a/JAVA/pom.xml b/JAVA/pom.xml
index b468896f..6bf8cbd7 100644
--- a/JAVA/pom.xml
+++ b/JAVA/pom.xml
@@ -3,8 +3,8 @@
4.0.0it.bancaditalia.oss
- sdmx
- 3.0.6
+ SDMX
+ 3.1.0SDMXSdmx Connectors for Statistical Software
@@ -32,19 +32,6 @@
-
- scm:git:https://github.com/amattioc/SDMX.git
- scm:git:https://github.com/amattioc/SDMX.git
- https://github.com/amattioc/SDMX/tree/master
-
-
-
-
- ossrh
- https://oss.sonatype.org/content/repositories/snapshots
-
-
-
UTF-81.8
@@ -52,197 +39,6 @@
Autogenerated release description
-
-
-
- fix-missing-modules-jdk11
-
- [11,)
-
-
-
- javax.xml.bind
- jaxb-api
- 2.4.0-b180830.0359
- provided
-
-
-
-
-
- compile-stata
-
-
- sdmx.compile.stata
- true
-
-
-
-
- com.stata
- stata-sfi
- 14.0
-
-
-
-
-
- org.codehaus.mojo
- build-helper-maven-plugin
- 3.1.0
-
-
- generate-sources
-
- add-source
-
-
-
- stata_src
-
-
-
-
-
-
-
-
-
- external
-
-
- sdmx.external.build
- true
-
-
-
-
-
- maven-assembly-plugin
- 3.1.0
-
-
- package
-
- single
-
-
- false
-
- ${project.build.sourceDirectory}/../assembly/assembly-excel.xml
- ${project.build.sourceDirectory}/../assembly/assembly-matlab.xml
- ${project.build.sourceDirectory}/../assembly/assembly-sas.xml
- ${project.build.sourceDirectory}/../assembly/assembly-stata.xml
-
-
-
-
-
-
- maven-dependency-plugin
- 3.0.2
-
-
- copy-packages
- verify
-
- copy
-
-
-
-
- it.bancaditalia.oss
- sdmx
- ${project.version}
- SDMX.jar
- true
- ../RJSDMX/inst/java
-
-
- it.bancaditalia.oss
- sdmx
- ${project.version}
- SDMX.jar
- true
- ../STATA/jar
-
-
-
-
-
-
-
- maven-scm-plugin
- 1.9.5
-
-
- commit-release
- verify
-
- add
- checkin
- check-local-modification
-
-
- ../
- ../
- /../RJSDMX/inst/java/SDMX.jar,/STATA/jar/SDMX.jar
- Release v${project.version}
- false
-
-
-
- push-tags
- deploy
-
- checkin
- tag
-
-
- ..
- ..
- v${project.version}
- Version ${project.version}
- true
-
-
-
-
-
- de.jutzig
- github-release-plugin
- 1.2.0
-
-
- github-release
- deploy
-
- release
-
-
-
-
- Release ${project.version}
- v${project.version}
- ${sdmx.release.description}
- true
- true
-
-
- ${project.build.directory}
-
- ${project.artifactId}*.jar
- *.tar.gz
-
-
-
-
-
-
-
-
-
-
junit
@@ -251,118 +47,4 @@
test
-
-
-
-
- org.codehaus.mojo
- buildnumber-maven-plugin
- 1.4
-
-
- validate
-
- create
-
-
-
-
- false
- false
- SNAPSHOT
-
-
-
- maven-jar-plugin
- 3.0.1
-
-
-
- true
- lib/
- it.bancaditalia.oss.sdmx.helper.SDMXHelper
-
-
- ${maven.build.timestamp}
- ${buildNumber}
- it.bancaditalia.oss.sdmx
-
-
-
-
-
- maven-source-plugin
- 3.0.1
-
-
- attach-sources
-
- jar-no-fork
-
-
-
-
-
- maven-javadoc-plugin
- 3.4.1
-
-
- attach-javadocs
-
- jar
-
-
- none
-
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- 3.0.0-M4
-
-
- **/AllTests*
-
-
-
-
- org.apache.maven.plugins
- maven-failsafe-plugin
- 3.0.0-M4
-
-
- maven-deploy-plugin
- 2.7
-
- true
-
-
-
- maven-gpg-plugin
- 1.6
-
-
- sign-artifacts
- verify
-
- sign
-
-
-
-
-
- org.sonatype.plugins
- nexus-staging-maven-plugin
- 1.6.8
- true
-
- ossrh
- https://oss.sonatype.org/
- true
-
-
-
-
diff --git a/JAVA/src/main/assembly/assembly-excel.xml b/JAVA/src/main/assembly/assembly-excel.xml
deleted file mode 100644
index aaf88f30..00000000
--- a/JAVA/src/main/assembly/assembly-excel.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-
- sdmx-excel
-
- tar.gz
-
- false
-
-
- ../EXCEL
-
- false
-
- **/*
-
-
-
-
-
- lib
- SDMX.jar
-
- it.bancaditalia.oss:sdmx:jar:${sdmx.version}
-
-
-
-
\ No newline at end of file
diff --git a/JAVA/src/main/assembly/assembly-matlab.xml b/JAVA/src/main/assembly/assembly-matlab.xml
deleted file mode 100644
index aff4f807..00000000
--- a/JAVA/src/main/assembly/assembly-matlab.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-
- sdmx-matlab
-
- tar.gz
-
- false
-
-
- ../MATLAB
-
- false
-
- **/*
-
-
-
-
-
- lib
- SDMX.jar
-
- it.bancaditalia.oss:sdmx:jar:${sdmx.version}
-
-
-
-
\ No newline at end of file
diff --git a/JAVA/src/main/assembly/assembly-sas.xml b/JAVA/src/main/assembly/assembly-sas.xml
deleted file mode 100644
index a38afa32..00000000
--- a/JAVA/src/main/assembly/assembly-sas.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-
- sdmx-sas
-
- tar.gz
-
- false
-
-
- ../SAS
-
- false
-
- **/*
-
-
-
-
-
- lib
- SDMX.jar
-
- it.bancaditalia.oss:sdmx:jar:${sdmx.version}
-
-
-
-
\ No newline at end of file
diff --git a/JAVA/src/main/assembly/assembly-stata.xml b/JAVA/src/main/assembly/assembly-stata.xml
deleted file mode 100644
index 7bd366a2..00000000
--- a/JAVA/src/main/assembly/assembly-stata.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-
- sdmx-stata
-
- tar.gz
-
- false
-
-
- ../STATA
-
- false
-
- **/*
-
-
-
-
-
- jar
- SDMX.jar
-
- it.bancaditalia.oss:sdmx:jar:${sdmx.version}
-
-
-
-
\ No newline at end of file
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/GenericSDMXClient.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/GenericSDMXClient.java
index 178a156d..7b958112 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/GenericSDMXClient.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/GenericSDMXClient.java
@@ -20,12 +20,11 @@
*/
package it.bancaditalia.oss.sdmx.api;
-import java.net.URI;
+import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
+
import java.util.List;
import java.util.Map;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
-
/**
* @author Attilio Mattiocco
*
@@ -118,13 +117,15 @@ public List> getTimeSeries(Dataflow dataflow, DataFlo
* @param filter the filter
* @param startTime start time of the observations to be gathered
* @param endTime end time of the observations to be gathered
+ * @param attributes comma separated string with the attributes to be returned ('none' or 'all' special values)
+ * @param measures comma separated string with the measures to be returned ('none' or 'all' special values)
* @param updatedAfter if set, only data updated after the given date will be retrieved (e.g. '2014-01-01')
* @param includeHistory boolean flag for enabling getting the history of revisions
* @throws SdmxException
*/
public List> getTimeSeries(Dataflow dataflow, DataFlowStructure dsd, String resource, String filter,
String startTime, String endTime,
- boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException;
+ String attributes, String measures, String updatedAfter, boolean includeHistory) throws SdmxException;
/**
*
Gets a list of available codes for the various dimensions, with the specified filters on components. Only in SDMX v3 providers
@@ -147,7 +148,7 @@ public List> getTimeSeries(Dataflow dataflow, DataFlo
* @param filter the filter
* @throws SdmxException
*/
- public Integer getAvailableTimeSeriesNumber(Dataflow df, String filter) throws SdmxException;
+ public Map getAvailableTimeSeriesNumber(Dataflow df, String filter) throws SdmxException;
/**
*
Checks id this is a secure provider, needing credentials. To be used
@@ -164,21 +165,6 @@ public List> getTimeSeries(Dataflow dataflow, DataFlo
*/
public void setCredentials(String user, String pw);
- /**
- *
Gets the URL of the web service for this provider client
- * @return the endpoint URL
- * @throws SdmxException
- */
- public URI getEndpoint() throws SdmxException;
-
- /**
- *
Sets the URL of the web service for this provider client
- */
- /**
- * @param endpoint
- */
- public void setEndpoint(URI endpoint);
-
/**
*
Gets the exact URL corresponding to the data query in input for this client
* @param resource the id of the time series
@@ -202,11 +188,4 @@ public String buildDataURL(Dataflow dataflow, String resource,
* @return the client name
*/
public String getName();
-
- /**
- *
Sets the name of this client
- * @param name the name of this client
- */
-
- public void setName(String name);
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/PortableDataSet.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/PortableDataSet.java
index 5e585a3d..de00656b 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/PortableDataSet.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/PortableDataSet.java
@@ -21,6 +21,9 @@
package it.bancaditalia.oss.sdmx.api;
import java.io.Serializable;
+import java.time.Year;
+import java.time.YearMonth;
+import java.time.temporal.TemporalAdjusters;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
@@ -31,7 +34,9 @@
import javax.swing.table.DefaultTableModel;
import it.bancaditalia.oss.sdmx.exceptions.DataStructureException;
+import it.bancaditalia.oss.sdmx.exceptions.SdmxInvalidParameterException;
import it.bancaditalia.oss.sdmx.util.Configuration;
+import it.bancaditalia.oss.sdmx.util.WeekConverter;
/**
* Java container for a dataset/table. In the various statistical tools it will be transformed by a converter into a
@@ -45,6 +50,7 @@ public class PortableDataSet implements Serializable
private static final long serialVersionUID = 1L;
public static final String TIME_LABEL = "TIME_PERIOD";
+ public static final String FREQ_LABEL = "FREQ";
public static final String OBS_LABEL = "OBS_VALUE";
public static final String ID_LABEL = "ID";
@@ -54,6 +60,7 @@ public class PortableDataSet implements Serializable
private boolean errorFlag = false;
private boolean numeric = false;
private String errorObjects = null;
+ private String dataflow = null;
private DefaultTableModel model = null;
@@ -77,6 +84,14 @@ public PortableDataSet(List> tslist) throws
setTimeSeries(tslist);
}
+ public String getDataflow() {
+ return dataflow;
+ }
+
+ public void setDataflow(String dataflow) {
+ this.dataflow = dataflow;
+ }
+
/**
* Returns the index of a column in this dataset given its name.
*
@@ -168,6 +183,53 @@ public String[] getTimeStamps() throws DataStructureException
return (result);
}
+ /**
+ * @return A flattened array containing all observations timestamps in gregorian format (end of period).
+ * @throws DataStructureException If any error occurs
+ * @throws SdmxInvalidParameterException
+ */
+ public String[] getGregorianTimeStamps() throws DataStructureException, SdmxInvalidParameterException
+ {
+ int rows = getRowCount();
+ String[] result = new String[rows];
+ String freq = "D";
+ int freqCol = -1;
+ int timeCol = getColumnIndex(TIME_LABEL);
+ try{
+ freqCol = getColumnIndex(FREQ_LABEL);
+ }
+ catch(DataStructureException dse){
+ // set daily freq - do nothing and cross fingers
+ }
+ for (int i = 0; i < rows; i++)
+ {
+ String time = (String) getValueAt(i, timeCol);
+ if(freqCol != -1){
+ freq = (String) getValueAt(i, freqCol);
+ }
+
+ if(freq.equalsIgnoreCase("M")){
+ result[i] = YearMonth.parse(time).atEndOfMonth().toString();
+ }
+ else if(freq.equalsIgnoreCase("Q")){
+ result[i] = time.replace("Q1", "03-31").replace("Q2", "06-30").replace("Q3", "09-30").replace("Q4", "12-31");
+ }
+ else if(freq.equalsIgnoreCase("A")){
+ result[i] = Year.parse(time).atMonth(12).atEndOfMonth().toString();
+ }
+ else if(freq.equalsIgnoreCase("H")){
+ result[i] = ((String) getValueAt(i, timeCol)).replace("S1", "06-30").replace("S2", "12-31");
+ }
+ else if(freq.equalsIgnoreCase("W")){
+ result[i] = WeekConverter.convert((String) getValueAt(i, timeCol));
+ }
+ else{
+ result[i] = ((String) getValueAt(i, timeCol));
+ }
+ }
+ return (result);
+ }
+
/**
* @return A flattened array containing all observations values for all series in this dataset.
* @throws DataStructureException If any error occurs
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/PortableTimeSeries.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/PortableTimeSeries.java
index fdf064f3..93fbda2e 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/PortableTimeSeries.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/PortableTimeSeries.java
@@ -20,8 +20,6 @@
*/
package it.bancaditalia.oss.sdmx.api;
-import static java.util.stream.Collectors.joining;
-
import java.io.Serializable;
import java.util.AbstractList;
import java.util.AbstractMap;
@@ -284,30 +282,6 @@ public String getAttribute(String code)
return getAttributesMap().get(code);
}
- /**
- * Set the series' attributes names and values. Any previous attribute, if defined, will be cleared.
- *
- * @param attributes A non-null map containing attribute bindings.
- */
- @Deprecated
- public void setAttributes(Map attributes)
- {
- getAttributesMap().clear();
- getAttributesMap().putAll(attributes);
- }
-
- /**
- * Adds or update an attribute value.
- *
- * @param key The name of series' attribute. Must be non-null.
- * @param value The value of the attribute.
- */
- @Deprecated
- public void addAttribute(String key, String value)
- {
- this.getAttributesMap().put(key, value);
- }
-
/**
* @return a map of codes for each defined dimension, with dimensions as keys and codes as values.
*/
@@ -624,6 +598,7 @@ public String toString()
{
buffer.append((first ? "" : ", ") + attrName + "=");
buffer.append(getObsLevelAttributes(attrName));
+ buffer.append("\n");
first = false;
}
@@ -655,6 +630,17 @@ public String getAttributeValue(String code)
return getAttribute(code);
}
+ /**
+ * Add an attribute to this time series.
+ *
+ * @deprecated Use {@link #getAttributesMap()} instead.
+ */
+ @Deprecated
+ public void addAttribute(String code, String value)
+ {
+ attributes.put(code, value);
+ }
+
/**
* Get a String[] in the format "key=value" for each defined attribute in this {@link PortableTimeSeries}.
*
@@ -685,18 +671,6 @@ public void setAttributes(List attributes)
this.getAttributesMap().put(pair.split("=")[0], pair.split("=")[1]);
}
- /**
- * Sets an attribute for this series.
- *
- * @param attribute a string in the format "key=value" representing the attribute to set.
- * @deprecated Use {@link #getAttributesMap()}.{@link Map#put(Object, Object) put(String, String)} instead.
- */
- @Deprecated
- public void addAttribute(String attribute)
- {
- addAttribute(attribute.split("=")[0], attribute.split("=")[1]);
- }
-
/**
* Get a list of Strings in the format "key=value" for each defined dimension in this {@link PortableTimeSeries}.
*
@@ -743,18 +717,6 @@ public String[] getDimensionsArray()
return result;
}
- /**
- * Sets an dimension for this series.
- *
- * @param dimension a string in the format "key=value" representing the dimension to set.
- * @deprecated Use {@link #getDimensionsMap()}.{@link Map#put(Object, Object) put(String, String)} instead.
- */
- @Deprecated
- public void addDimension(String dimension)
- {
- addDimension(dimension.split("=")[0], dimension.split("=")[1]);
- }
-
/**
* Gets a list of statuses for each observation in this {@link PortableTimeSeries}.
*
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/SDMXVersion.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/SDMXVersion.java
new file mode 100644
index 00000000..ab0c6b26
--- /dev/null
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/api/SDMXVersion.java
@@ -0,0 +1,6 @@
+package it.bancaditalia.oss.sdmx.api;
+
+public enum SDMXVersion
+{
+ V2, V3;
+}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/Provider.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/Provider.java
index fe89b661..661c6399 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/Provider.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/Provider.java
@@ -21,22 +21,14 @@
package it.bancaditalia.oss.sdmx.client;
import java.net.URI;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManagerFactory;
-
import it.bancaditalia.oss.sdmx.api.DataFlowStructure;
import it.bancaditalia.oss.sdmx.api.Dataflow;
import it.bancaditalia.oss.sdmx.api.SDMXReference;
+import it.bancaditalia.oss.sdmx.api.SDMXVersion;
import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
/**
@@ -44,26 +36,24 @@
* @author Valentino Pinna
*
*/
-public class Provider {
- private String name;
+public class Provider
+{
+ private final String name;
+ private final URI endpoint;
+ private final SDMXVersion sdmxVersion;
+ private final boolean needsURLEncoding;
+ private final boolean supportsCompression;
private String description;
- private URI endpoint;
- private String sdmxVersion;
private boolean needsCredentials;
- private boolean needsURLEncoding;
- private boolean supportsCompression;
private boolean full = false;
- private boolean isCustom = false;
// key: flow id (full) --> flow
- private Map flows;
+ private Map flows;
// key: dsd id (full) --> structure
private Map dsdNameToStructureCache = null;
- private SSLSocketFactory sslSocketFactory;
- public Provider(String name, URI endpoint, KeyStore trustStore, boolean needsCredentials,
- boolean needsURLEncoding, boolean supportsCompression, String description,
- boolean isCustom, String sdmxVersion) throws SdmxException {
+ public Provider(String name, URI endpoint, boolean needsCredentials, boolean needsURLEncoding, boolean supportsCompression, String description, SDMXVersion sdmxVersion) throws SdmxException
+ {
this.name = name;
this.endpoint = endpoint;
this.description = description;
@@ -72,150 +62,108 @@ public Provider(String name, URI endpoint, KeyStore trustStore, boolean needsCre
this.needsCredentials = needsCredentials;
this.needsURLEncoding = needsURLEncoding;
this.supportsCompression = supportsCompression;
- this.isCustom = isCustom;
this.sdmxVersion = sdmxVersion;
-
- try {
- if (trustStore != null)
- {
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
- tmf.init(trustStore);
-
- SSLContext context = SSLContext.getInstance("TLS");
- context.init(null, tmf.getTrustManagers(), new SecureRandom());
-
- this.sslSocketFactory = context.getSocketFactory();
- }
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- } catch (KeyStoreException e) {
- e.printStackTrace();
- } catch (KeyManagementException e) {
- e.printStackTrace();
- }
- }
-
- public String getName() {
- return name;
}
- public void setName(String name) {
- this.name = name;
+ public String getName()
+ {
+ return name;
}
- public URI getEndpoint() {
+ public URI getEndpoint()
+ {
return endpoint;
}
- public void setEndpoint(URI endpoint) {
- this.endpoint = endpoint;
- }
-
- public void setFlows(Map flows) {
+ public void setFlows(Map flows)
+ {
this.flows = flows;
}
- public void setFlow(Dataflow flow) {
- /* BUG: flow is inserted using just the id, but this.flows is set up using the
- * full identifier, this creates duplicates inside this.flows. */
- //this.flows.put(flow.getId(), flow);
+ public void setFlow(Dataflow flow)
+ {
+ /*
+ * BUG: flow is inserted using just the id, but this.flows is set up using the
+ * full identifier, this creates duplicates inside this.flows.
+ */
+ // this.flows.put(flow.getId(), flow);
this.flows.put(flow.getFullIdentifier(), flow);
}
-
- public Dataflow getFlow(String dataflow) {
- if (flows.containsKey(dataflow)) {
+ public Dataflow getFlow(String dataflow)
+ {
+ if (flows.containsKey(dataflow))
return flows.get(dataflow);
- } else {
- // it could be because we got the simple flow id (e.g. from getTimSeries).
- // We try to handle it matching the id (if any) and returning the first available agency and the latest version
- return flows.values()
- .stream()
- .filter(df -> df.getId().equals(dataflow))
- .max(Comparator.comparing(Dataflow::getVersion))
- .orElse(null);
- }
- }
-
- public Map getFlows() {
+
+ // it could be because we got the simple flow id (e.g. from getTimSeries).
+ // We try to handle it matching the id (if any) and returning the first
+ // available agency and the latest version
+ return flows.values().stream().filter(df -> df.getId().equals(dataflow)).max(Comparator.comparing(Dataflow::getVersion)).orElse(null);
+ }
+
+ public Map getFlows()
+ {
return flows;
}
- public SDMXReference getDSDIdentifier(String dataflow) {
- SDMXReference dsdid = null;
+ public SDMXReference getDSDIdentifier(String dataflow)
+ {
Dataflow df = getFlow(dataflow);
- if(df != null){
- dsdid = df.getDsdIdentifier();
- }
- return dsdid;
+ return df != null ? df.getDsdIdentifier() : null;
}
- public DataFlowStructure getDSD(String dsdID) {
+ public DataFlowStructure getDSD(String dsdID)
+ {
return dsdNameToStructureCache.get(dsdID);
}
- public void setDSD(String dsdID, DataFlowStructure dsd) {
+ public void setDSD(String dsdID, DataFlowStructure dsd)
+ {
this.dsdNameToStructureCache.put(dsdID, dsd);
}
- public String getDescription() {
+ public String getDescription()
+ {
return description;
}
- public void setDescription(String description) {
+ public void setDescription(String description)
+ {
this.description = description;
}
- public boolean isNeedsCredentials() {
+ public boolean isNeedsCredentials()
+ {
return needsCredentials;
}
- public void setNeedsCredentials(boolean needsCredentials) {
+ public void setNeedsCredentials(boolean needsCredentials)
+ {
this.needsCredentials = needsCredentials;
}
- public void setFull(boolean full) {
+ public void setFull(boolean full)
+ {
this.full = full;
}
- public boolean isFull() {
+ public boolean isFull()
+ {
return full;
}
- public boolean isNeedsURLEncoding() {
+ public boolean isNeedsURLEncoding()
+ {
return needsURLEncoding;
}
- public void setNeedsURLEncoding(boolean needsURLEncoding) {
- this.needsURLEncoding = needsURLEncoding;
- }
-
- public boolean isSupportsCompression() {
+ public boolean isSupportsCompression()
+ {
return supportsCompression;
}
- public void setSupportsCompression(boolean supportsCompression) {
- this.supportsCompression = supportsCompression;
- }
-
- public void setCustom(boolean isCustom) {
- this.isCustom = isCustom;
- }
-
- public boolean isCustom() {
- return isCustom;
- }
-
- public SSLSocketFactory getSSLSocketFactory() {
- return sslSocketFactory;
- }
-
- public String getSdmxVersion() {
+ public SDMXVersion getSdmxVersion()
+ {
return sdmxVersion;
}
-
- public void setSdmxVersion(String sdmxVersion) {
- this.sdmxVersion = sdmxVersion;
- }
-
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/RestSdmx30Client.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/RestSdmx30Client.java
index 2ca07800..b3954473 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/RestSdmx30Client.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/RestSdmx30Client.java
@@ -20,19 +20,7 @@
*/
package it.bancaditalia.oss.sdmx.client;
-import java.net.URI;
-import java.net.URL;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-
-import javax.net.ssl.SSLSocketFactory;
-
-import it.bancaditalia.oss.sdmx.api.DataFlowStructure;
-import it.bancaditalia.oss.sdmx.api.Dataflow;
-import it.bancaditalia.oss.sdmx.api.Dimension;
-import it.bancaditalia.oss.sdmx.api.Message;
-import it.bancaditalia.oss.sdmx.api.PortableTimeSeries;
+import it.bancaditalia.oss.sdmx.api.*;
import it.bancaditalia.oss.sdmx.event.DataFooterMessageEvent;
import it.bancaditalia.oss.sdmx.event.RestSdmxEvent;
import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
@@ -42,6 +30,15 @@
import it.bancaditalia.oss.sdmx.parser.v30.AvailabilityParser;
import it.bancaditalia.oss.sdmx.parser.v30.Sdmx30Queries;
import it.bancaditalia.oss.sdmx.parser.v30.SeriesCountParser;
+import it.bancaditalia.oss.sdmx.util.QueryRunner;
+
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+
+import static it.bancaditalia.oss.sdmx.api.SDMXVersion.V3;
+import static it.bancaditalia.oss.sdmx.util.QueryRunner.runQuery;
/**
* @author Attilio Mattiocco
@@ -50,51 +47,50 @@
public class RestSdmx30Client extends RestSdmxClient
{
- protected final String LATEST_VERSION = "+";
-
- public RestSdmx30Client(String name, URI endpoint, SSLSocketFactory sslSocketFactory, boolean needsCredentials, boolean needsURLEncoding,
- boolean supportsCompression)
- {
- super(name, endpoint, sslSocketFactory, needsCredentials, needsURLEncoding, supportsCompression);
- this.sdmxVersion = SDMXClientFactory.SDMX_V3;
- this.latestKeyword = this.LATEST_VERSION;
- }
-
- public RestSdmx30Client(String name, URI endpoint, boolean needsCredentials, boolean needsURLEncoding, boolean supportsCompression)
+ public RestSdmx30Client(Provider provider)
{
- this(name, endpoint, null, needsCredentials, needsURLEncoding, supportsCompression);
- this.sdmxVersion = SDMXClientFactory.SDMX_V3;
- this.latestKeyword = this.LATEST_VERSION;
+ super(provider);
+ this.sdmxVersion = V3;
+ this.LATEST_VERSION = "+";
+ this.ALL_KEYWORD = "*";
}
@Override
public List> getTimeSeries(Dataflow dataflow, DataFlowStructure dsd, String tsKey,
String startTime, String endTime,
boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException {
- return getTimeSeries(dataflow, dsd, tsKey, null, startTime, endTime, serieskeysonly, updatedAfter, includeHistory);
+ // old V2 calls can be mapped to V3 ones
+ return getTimeSeries(dataflow, dsd, tsKey, null, startTime, endTime, serieskeysonly ? "none" : "all", serieskeysonly ? "none" : "all", updatedAfter, includeHistory);
}
@Override
public List> getTimeSeries(Dataflow dataflow, DataFlowStructure dsd, String tsKey, String filter,
String startTime, String endTime,
- boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException {
- return postProcess(getData(dataflow, dsd, tsKey, filter, startTime, endTime, serieskeysonly, updatedAfter, includeHistory));
+ String attributes, String measures, String updatedAfter, boolean includeHistory) throws SdmxException {
+ return postProcess(getData(dataflow, dsd, tsKey, filter, startTime, endTime, attributes, measures, updatedAfter, includeHistory));
}
@Override
public Map> getAvailableCubeRegion(Dataflow dataflow, String filter, String mode) throws SdmxException {
URL query = buildAvailabilityQuery(dataflow, filter, mode);
- return runQuery(new AvailabilityParser(), query, null, null);
+ return runQuery(new AvailabilityParser(), query, handleHttpHeaders("application/vnd.sdmx.structure+xml;version=2.1"));
}
@Override
- public Integer getAvailableTimeSeriesNumber(Dataflow dataflow, String filter) throws SdmxException {
- URL query = buildAvailabilityQueryByKey(dataflow, filter, "exact");
- return runQuery(new SeriesCountParser(), query, null, null);
+ public Map getAvailableTimeSeriesNumber(Dataflow dataflow, String filter) throws SdmxException {
+ URL query = buildAvailabilityQuery(dataflow, filter, "exact");
+ return runQuery(new SeriesCountParser(), query, handleHttpHeaders("application/vnd.sdmx.structure+xml;version=2.1"));
+ }
+
+ @Override
+ public String buildDataURL(Dataflow dataflow, String resource, String startTime, String endTime, boolean seriesKeyOnly, String updatedAfter,
+ boolean includeHistory) throws SdmxException
+ {
+ return buildDataQuery(dataflow, null, resource, startTime, endTime, null, null, updatedAfter, includeHistory).toString();
}
protected DataParsingResult getData(Dataflow dataflow, DataFlowStructure dsd, String tsKey, String filter, String startTime, String endTime,
- boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException
+ String attributes, String measures, String updatedAfter, boolean includeHistory) throws SdmxException
{
if(tsKey != null && !tsKey.isEmpty()){
if(tsKey.contains("+")){
@@ -112,23 +108,23 @@ protected DataParsingResult getData(Dataflow dataflow, DataFlowStructure dsd, St
}
}
- URL query = buildDataQuery(dataflow, tsKey, filter, startTime, endTime, serieskeysonly, updatedAfter, includeHistory);
+ URL query = buildDataQuery(dataflow, tsKey, filter, startTime, endTime, attributes, measures, updatedAfter, includeHistory);
String dumpName = "data_" + dataflow.getId() + "_" + filter; //.replaceAll("\\p{Punct}", "_");
- DataParsingResult ts = runQuery(new CompactDataParser(dsd, dataflow, !serieskeysonly), query,
- "application/vnd.sdmx.structurespecificdata+xml;version=2.1", dumpName);
+ DataParsingResult ts = runQuery(new CompactDataParser(dsd, dataflow, !("none".equals(attributes) && "none".equals(measures))), query,
+ getName(), dumpName, handleHttpHeaders("application/vnd.sdmx.structurespecificdata+xml;version=2.1"));
Message msg = ts.getMessage();
if (msg != null)
{
LOGGER.log(Level.INFO, "The sdmx call returned messages in the footer:\n {0}", msg);
RestSdmxEvent event = new DataFooterMessageEvent(query, msg);
- dataFooterMessageEventListener.onSdmxEvent(event);
+ QueryRunner.getDataFooterMessageEventListener().onSdmxEvent(event);
}
return ts;
}
private String mapSDMX2KeytoSDMX3FIlter(String tsKey, DataFlowStructure dsd) throws SdmxInvalidParameterException {
String filter = "";
- Dimension[] dims = (Dimension[]) dsd.getDimensions().toArray();
+ Dimension[] dims = dsd.getDimensions().toArray(new Dimension[0]);
String delims = "[.]";
String[] tokens = tsKey.split(delims);
if(tokens.length > dims.length)
@@ -142,42 +138,43 @@ private String mapSDMX2KeytoSDMX3FIlter(String tsKey, DataFlowStructure dsd) thr
}
protected URL buildDataQuery(Dataflow dataflow, String tsKey, String filter, String startTime, String endTime,
- boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException
+ String attributes, String measures, String updatedAfter, boolean includeHistory) throws SdmxException
{
- if (endpoint != null && dataflow != null)
+ if (provider.getEndpoint() != null && dataflow != null)
return Sdmx30Queries
- .createDataQuery(endpoint, dataflow.getFullIdentifier(), tsKey, filter, startTime, endTime, serieskeysonly, updatedAfter, includeHistory)
+ .createDataQuery(provider.getEndpoint(), dataflow.getFullIdentifier(), tsKey, filter, startTime, endTime,
+ attributes, measures, updatedAfter, includeHistory)
.buildQuery();
else
- throw new RuntimeException("Invalid query parameters: dataflow=" + dataflow + " endpoint=" + endpoint);
+ throw new RuntimeException("Invalid query parameters: dataflow=" + dataflow + " endpoint=" + provider.getEndpoint());
}
protected URL buildDSDQuery(String dsd, String agency, String version, boolean full) throws SdmxException
{
- if (endpoint != null && agency != null && !agency.isEmpty() && dsd != null && !dsd.isEmpty())
- return Sdmx30Queries.createStructureQuery(endpoint, dsd, agency, version, full).buildQuery();
+ if (provider.getEndpoint() != null && agency != null && !agency.isEmpty() && dsd != null && !dsd.isEmpty())
+ return Sdmx30Queries.createStructureQuery(provider.getEndpoint(), dsd, agency, version, full).buildQuery();
else
- throw new RuntimeException("Invalid query parameters: agency=" + agency + " dsd=" + dsd + " endpoint=" + endpoint);
+ throw new RuntimeException("Invalid query parameters: agency=" + agency + " dsd=" + dsd + " endpoint=" + provider.getEndpoint());
}
protected URL buildFlowQuery(String dataflow, String agency, String version) throws SdmxException
{
- return Sdmx30Queries.createDataflowQuery(endpoint, dataflow, agency, version).buildQuery();
+ return Sdmx30Queries.createDataflowQuery(provider.getEndpoint(), dataflow, agency, version).buildQuery();
}
protected URL buildCodelistQuery(String codeList, String agency, String version) throws SdmxException
{
- return Sdmx30Queries.createCodelistQuery(endpoint, codeList, agency, version).buildQuery();
+ return Sdmx30Queries.createCodelistQuery(provider.getEndpoint(), codeList, agency, version).buildQuery();
}
protected URL buildAvailabilityQuery(Dataflow dataflow, String filter, String mode) throws SdmxException
{
- return Sdmx30Queries.createAvailabilityQuery(endpoint, dataflow.getFullIdentifier(), filter, mode).buildQuery();
+ return Sdmx30Queries.createAvailabilityQuery(provider.getEndpoint(), dataflow.getFullIdentifier(), filter, mode).buildQuery();
}
protected URL buildAvailabilityQueryByKey(Dataflow dataflow, String filter, String mode) throws SdmxException
{
- return Sdmx30Queries.createAvailabilityQueryByKey(endpoint, dataflow.getFullIdentifier(), filter, mode).buildQuery();
+ return Sdmx30Queries.createAvailabilityQueryByKey(provider.getEndpoint(), dataflow.getFullIdentifier(), filter, mode).buildQuery();
}
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/RestSdmxClient.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/RestSdmxClient.java
index 0a56ee98..c13b0a88 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/RestSdmxClient.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/RestSdmxClient.java
@@ -20,71 +20,27 @@
*/
package it.bancaditalia.oss.sdmx.client;
-import static it.bancaditalia.oss.sdmx.util.Configuration.getLanguages;
-import static java.lang.String.format;
-import static java.util.stream.Collectors.joining;
+import it.bancaditalia.oss.sdmx.api.*;
+import it.bancaditalia.oss.sdmx.event.DataFooterMessageEvent;
+import it.bancaditalia.oss.sdmx.event.RestSdmxEvent;
+import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
+import it.bancaditalia.oss.sdmx.exceptions.SdmxInvalidParameterException;
+import it.bancaditalia.oss.sdmx.exceptions.SdmxXmlContentException;
+import it.bancaditalia.oss.sdmx.parser.v21.*;
+import it.bancaditalia.oss.sdmx.util.Configuration;
+import it.bancaditalia.oss.sdmx.util.QueryRunner;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.Proxy;
-import java.net.ProxySelector;
-import java.net.URI;
-import java.net.URISyntaxException;
import java.net.URL;
-import java.net.URLConnection;
-import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.InflaterInputStream;
-import java.util.zip.ZipInputStream;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSocketFactory;
-import javax.swing.LayoutFocusTraversalPolicy;
-import javax.xml.stream.XMLEventReader;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamException;
-import it.bancaditalia.oss.sdmx.api.Codelist;
-import it.bancaditalia.oss.sdmx.api.DataFlowStructure;
-import it.bancaditalia.oss.sdmx.api.Dataflow;
-import it.bancaditalia.oss.sdmx.api.GenericSDMXClient;
-import it.bancaditalia.oss.sdmx.api.SDMXReference;
-import it.bancaditalia.oss.sdmx.api.Message;
-import it.bancaditalia.oss.sdmx.api.PortableTimeSeries;
-import it.bancaditalia.oss.sdmx.event.DataFooterMessageEvent;
-import it.bancaditalia.oss.sdmx.event.OpenEvent;
-import it.bancaditalia.oss.sdmx.event.RedirectionEvent;
-import it.bancaditalia.oss.sdmx.event.RestSdmxEvent;
-import it.bancaditalia.oss.sdmx.event.RestSdmxEventListener;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxExceptionFactory;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxIOException;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxInvalidParameterException;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxRedirectionException;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxXmlContentException;
-import it.bancaditalia.oss.sdmx.parser.v21.CodelistParser;
-import it.bancaditalia.oss.sdmx.parser.v21.CompactDataParser;
-import it.bancaditalia.oss.sdmx.parser.v21.DataParsingResult;
-import it.bancaditalia.oss.sdmx.parser.v21.DataStructureParser;
-import it.bancaditalia.oss.sdmx.parser.v21.DataflowParser;
-import it.bancaditalia.oss.sdmx.parser.v21.Sdmx21Queries;
-import it.bancaditalia.oss.sdmx.util.Configuration;
+import static it.bancaditalia.oss.sdmx.api.SDMXVersion.V2;
+import static it.bancaditalia.oss.sdmx.util.QueryRunner.runQuery;
+import static java.util.stream.Collectors.joining;
/**
* @author Attilio Mattiocco
@@ -92,110 +48,31 @@
*/
public class RestSdmxClient implements GenericSDMXClient
{
- private static final String SOURCE_CLASS = RestSdmxClient.class.getSimpleName();
protected static final Logger LOGGER = Configuration.getSdmxLogger();
- protected String sdmxVersion = SDMXClientFactory.SDMX_V2;
- protected String name;
- protected final boolean needsURLEncoding;
- protected final boolean supportsCompression;
+ protected SDMXVersion sdmxVersion = V2;
- protected ProxySelector proxySelector;
- protected SSLSocketFactory sslSocketFactory;
- protected HostnameVerifier hostnameVerifier;
- protected final boolean dotStat = false;
- protected /* final */ URI endpoint;
protected boolean needsCredentials = false;
protected boolean containsCredentials = false;
protected String user = null;
protected String pw = null;
- protected int readTimeout;
- protected int connectTimeout;
- protected RestSdmxEventListener dataFooterMessageEventListener = RestSdmxEventListener.NO_OP_LISTENER;
- protected RestSdmxEventListener redirectionEventListener = RestSdmxEventListener.NO_OP_LISTENER;
- protected RestSdmxEventListener openEventListener = RestSdmxEventListener.NO_OP_LISTENER;
- protected int maxRedirects = 20;
- protected final String LATEST_VERSION = "latest";
- protected final String ALL_AGENCIES = "all";
- protected String latestKeyword = LATEST_VERSION;
-
- public RestSdmxClient(String name, URI endpoint, SSLSocketFactory sslSocketFactory, boolean needsCredentials, boolean needsURLEncoding, boolean supportsCompression)
- {
- this.endpoint = endpoint;
- this.name = name;
- this.needsCredentials = needsCredentials;
- this.needsURLEncoding = needsURLEncoding;
- this.supportsCompression = supportsCompression;
- this.proxySelector = null;
- this.sslSocketFactory = sslSocketFactory;
- this.hostnameVerifier = null;
- readTimeout = Configuration.getReadTimeout(getClass().getSimpleName());
- connectTimeout = Configuration.getConnectTimeout(getClass().getSimpleName());
-// languages = LanguageRange.parse(Configuration.getLang());
- }
-
- public RestSdmxClient(String name, URI endpoint, boolean needsCredentials, boolean needsURLEncoding, boolean supportsCompression)
- {
- this(name, endpoint, null, needsCredentials, needsURLEncoding, supportsCompression);
- }
-
- public void setProxySelector(ProxySelector proxySelector)
- {
- this.proxySelector = proxySelector;
- }
-
- public void setSslSocketFactory(SSLSocketFactory sslSocketFactory)
- {
- this.sslSocketFactory = sslSocketFactory;
- }
-
- public void setHostnameVerifier(HostnameVerifier hostnameVerifier)
- {
- this.hostnameVerifier = hostnameVerifier;
- }
-
- public void setReadTimeout(int timeout)
- {
- this.readTimeout = timeout;
- }
-
- public void setConnectTimeout(int timeout)
- {
- this.connectTimeout = timeout;
- }
-
-// public void setLanguages(List languages)
-// {
-// this.languages = languages;
-// }
-
- public void setDataFooterMessageEventListener(RestSdmxEventListener eventListener)
- {
- this.dataFooterMessageEventListener = eventListener;
- }
-
- public void setRedirectionEventListener(RestSdmxEventListener eventListener)
- {
- this.redirectionEventListener = eventListener;
- }
-
- public void setOpenEventListener(RestSdmxEventListener eventListener)
- {
- this.openEventListener = eventListener;
- }
+ protected final Provider provider;
+ protected String LATEST_VERSION = "latest";
+ protected String ALL_KEYWORD = "all";
- public void setMaxRedirects(int maxRedirects)
+ public RestSdmxClient(Provider provider)
{
- this.maxRedirects = maxRedirects;
+ this.provider = provider;
+ this.needsCredentials = provider.isNeedsCredentials();
}
@Override
public Map getDataflows() throws SdmxException
{
Map result = null;
- URL query = buildFlowQuery(ALL_AGENCIES, "all", latestKeyword);
- List flows = runQuery(new DataflowParser(), query, null, "dataflow_all");
+ URL query = buildFlowQuery(ALL_KEYWORD, ALL_KEYWORD, LATEST_VERSION);
+ List flows = runQuery(new DataflowParser(), query, "dataflow_all", getName(), handleHttpHeaders("application/vnd.sdmx.structure+xml;version=2.1"));
if (flows.size() > 0)
{
result = new HashMap<>();
@@ -203,9 +80,8 @@ public Map getDataflows() throws SdmxException
result.put(dataflow.getFullIdentifier(), dataflow);
}
else
- {
throw new SdmxXmlContentException("The query returned zero dataflows");
- }
+
return result;
}
@@ -213,10 +89,10 @@ public Map getDataflows() throws SdmxException
public Dataflow getDataflow(String dataflow, String agency, String version) throws SdmxException
{
Dataflow result = null;
- if(agency == null) agency = ALL_AGENCIES;
- if(version == null) version = this.latestKeyword;
+ if(agency == null) agency = ALL_KEYWORD;
+ if(version == null) version = this.LATEST_VERSION;
URL query = buildFlowQuery(dataflow, agency, version);
- List flows = runQuery(new DataflowParser(), query, null, "dataflow_" + dataflow);
+ List flows = runQuery(new DataflowParser(), query, getName(), "dataflow_" + dataflow, handleHttpHeaders("application/vnd.sdmx.structure+xml;version=2.1"));
if (flows.size() >= 1)
result = flows.get(0);
else
@@ -233,7 +109,7 @@ public DataFlowStructure getDataFlowStructure(SDMXReference dsd, boolean full) t
else
{
URL query = buildDSDQuery(dsd.getId(), dsd.getAgency(), dsd.getVersion(), full);
- return runQuery(new DataStructureParser(), query, null, "datastructure_" + dsd.getId()).get(0);
+ return runQuery(new DataStructureParser(), query, getName(), "datastructure_" + dsd.getId(), handleHttpHeaders("application/vnd.sdmx.structure+xml;version=2.1")).get(0);
}
}
@@ -241,7 +117,7 @@ public DataFlowStructure getDataFlowStructure(SDMXReference dsd, boolean full) t
public Codelist getCodes(String codeList, String agency, String version) throws SdmxException
{
URL query = buildCodelistQuery(codeList, agency, version);
- return runQuery(new CodelistParser(), query, null, "codelist_" + codeList);
+ return runQuery(new CodelistParser(), query, getName(), "codelist_" + codeList, handleHttpHeaders("application/vnd.sdmx.structure+xml;version=2.1"));
}
@Override
@@ -255,11 +131,8 @@ public List> getTimeSeries(Dataflow dataflow, DataFlo
@Override
public List> getTimeSeries(Dataflow dataflow, DataFlowStructure dsd, String resource, String filter,
String startTime, String endTime,
- boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException {
- if(filter != null && !filter.isEmpty())
- throw new SdmxInvalidParameterException("This method can only be called on SDMX V3 providers.");
- else
- return getTimeSeries(dataflow, dsd, resource, startTime, endTime, serieskeysonly, updatedAfter, includeHistory);
+ String attributes, String measures, String updatedAfter, boolean includeHistory) throws SdmxException {
+ throw new SdmxInvalidParameterException("This method can only be called on SDMX V3 providers.");
}
@Override
@@ -268,7 +141,7 @@ public Map> getAvailableCubeRegion(Dataflow dataflow, Strin
}
@Override
- public Integer getAvailableTimeSeriesNumber(Dataflow dataflow, String filter) throws SdmxException {
+ public Map getAvailableTimeSeriesNumber(Dataflow dataflow, String filter) throws SdmxException {
throw new SdmxInvalidParameterException("This method can only be called on SDMX V3 providers.");
}
@@ -278,13 +151,14 @@ protected DataParsingResult getData(Dataflow dataflow, DataFlowStructure dsd, St
URL query = buildDataQuery(dataflow, resource, startTime, endTime, serieskeysonly, updatedAfter, includeHistory);
String dumpName = "data_" + dataflow.getId() + "_" + resource; //.replaceAll("\\p{Punct}", "_");
DataParsingResult ts = runQuery(new CompactDataParser(dsd, dataflow, !serieskeysonly), query,
- "application/vnd.sdmx.structurespecificdata+xml;version=2.1", dumpName);
+ getName(), dumpName, handleHttpHeaders("application/vnd.sdmx.structurespecificdata+xml;version=2.1"));
+
Message msg = ts.getMessage();
if (msg != null)
{
LOGGER.log(Level.INFO, "The sdmx call returned messages in the footer:\n {0}", msg);
RestSdmxEvent event = new DataFooterMessageEvent(query, msg);
- dataFooterMessageEventListener.onSdmxEvent(event);
+ QueryRunner.getDataFooterMessageEventListener().onSdmxEvent(event);
}
return ts;
}
@@ -304,36 +178,15 @@ public void setCredentials(String user, String pw)
this.containsCredentials = true;
}
- @Override
- public URI getEndpoint()
- {
- return endpoint;
- }
-
- @Override
- public void setEndpoint(URI endpoint)
- {
- this.endpoint = endpoint;
- }
-
@Override
public String getName()
{
- return name;
- }
-
- @Override
- public void setName(String name)
- {
- this.name = name;
- }
-
- public String getSdmxVersion() {
- return sdmxVersion;
+ return provider.getName();
}
- public void setSdmxVersion(String sdmxVersion) {
- this.sdmxVersion = sdmxVersion;
+ public String getSdmxVersion()
+ {
+ return sdmxVersion.toString();
}
@Override
@@ -343,307 +196,32 @@ public String buildDataURL(Dataflow dataflow, String resource, String startTime,
return buildDataQuery(dataflow, resource, startTime, endTime, seriesKeyOnly, updatedAfter, includeHistory).toString();
}
- /**
- * Returns a reader over the result of an http query.
- *
- * @param query a non-null query
- * @param acceptHeader a nullable accept header
- * @return a non-null reader
- *
- * @throws SdmxException
- */
- protected final T runQuery(Parser parser, URL query, String acceptHeader, String dumpName) throws SdmxException
- {
- final String sourceMethod = "runQuery";
- LOGGER.entering(SOURCE_CLASS, sourceMethod);
-
- URLConnection conn = null;
- URL url = null;
- LOGGER.log(Level.INFO, "Contacting web service with query: {0}", query);
-
- try
- {
- int code;
- url = query;
- URL originalURL = url;
-
- Proxy proxy = (proxySelector != null ? proxySelector : ProxySelector.getDefault()).select(url.toURI()).get(0);
- LOGGER.fine("Using proxy: " + proxy);
-
- openEventListener.onSdmxEvent(new OpenEvent(url, acceptHeader, getLanguages(), proxy));
-
- int redirects = 0;
- do
- {
- conn = url.openConnection(proxy);
-
- if (conn instanceof HttpsURLConnection && sslSocketFactory != null)
- {
- LOGGER.fine("Using custom SSLSocketFactory for provider " + name);
- ((HttpsURLConnection) conn).setSSLSocketFactory(sslSocketFactory);
- }
-
- if (conn instanceof HttpsURLConnection && hostnameVerifier != null)
- {
- LOGGER.fine("Using custom HostnameVerifier for provider " + name);
- ((HttpsURLConnection) conn).setHostnameVerifier(hostnameVerifier);
- }
-
- conn.setReadTimeout(readTimeout);
- conn.setConnectTimeout(connectTimeout);
-
- if (conn instanceof HttpURLConnection)
- {
- ((HttpURLConnection) conn).setRequestMethod("GET");
- ((HttpURLConnection) conn).setInstanceFollowRedirects(false);
- handleHttpHeaders((HttpURLConnection) conn, acceptHeader);
- }
-
- code = conn instanceof HttpURLConnection ? ((HttpURLConnection) conn).getResponseCode() : HttpURLConnection.HTTP_OK;
- if (code == HttpURLConnection.HTTP_PROXY_AUTH)
- {
- LOGGER.fine("Error with proxy. Second attempt after forcing acces to http website in first place.");
- URI uritest= new URI("http://google.com");
- URL urltest = uritest.toURL();
- conn = urltest.openConnection(proxy);
- ((HttpURLConnection) conn).setRequestMethod("GET");
- code = conn instanceof HttpURLConnection ? ((HttpURLConnection) conn).getResponseCode() : HttpURLConnection.HTTP_OK;
- conn = url.openConnection(proxy);
- ((HttpURLConnection) conn).setRequestMethod("GET");
- code = conn instanceof HttpURLConnection ? ((HttpURLConnection) conn).getResponseCode() : HttpURLConnection.HTTP_OK;
-
- }
- if (isRedirection(code))
- {
- URL redirection = getRedirectionURL(conn, code);
-// if (conn instanceof HttpURLConnection)
-// ((HttpURLConnection) conn).disconnect();
- if (isDowngradingProtocolOnRedirect(originalURL, redirection)) {
- throw new SdmxRedirectionException("Downgrading protocol on redirect from '" + originalURL + "' to '" + redirection + "'");
- }
- LOGGER.log(Level.INFO, "Redirecting to: {0}", redirection);
- RestSdmxEvent event = new RedirectionEvent(url, redirection);
- redirectionEventListener.onSdmxEvent(event);
- url = redirection;
- redirects++;
- }
- } while (isRedirection(code) && !(isMaxRedirectionReached(redirects)));
-
- if (isMaxRedirectionReached(redirects)) {
- throw new SdmxRedirectionException("Max redirection reached");
- }
-
- if (code == HttpURLConnection.HTTP_OK)
- {
- LOGGER.fine("Connection opened. Code: " + code);
- InputStream stream = conn.getInputStream();
- String encoding = conn.getContentEncoding() == null ? "" : conn.getContentEncoding();
- if (encoding.equalsIgnoreCase("gzip"))
- stream = new GZIPInputStream(stream);
- else if (encoding.equalsIgnoreCase("deflate"))
- stream = new InflaterInputStream(stream);
- else if (conn.getContentType() != null && conn.getContentType().contains("application/octet-stream"))
- {
- stream = new ZipInputStream(stream);
- ((ZipInputStream) stream).getNextEntry();
- }
-
- if (Configuration.isDumpXml() && dumpName != null) // skip providers < sdmx v2.1
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] buf = new byte[4096];
- int i;
- while ((i = stream.read(buf, 0, 4096)) > 0)
- baos.write(buf, 0, i);
- baos.close();
-// String resource = URLDecoder.decode(url.getPath(), StandardCharsets.UTF_8.name()).replaceAll(endpoint.getPath() + "/?", "")
-// .replaceFirst("/$", "").replaceAll("\\p{Punct}", "_") + ".xml";
- System.err.println(Configuration.getDumpPrefix());
- File dumpfilename = new File(Configuration.getDumpPrefix() + File.separator + name, dumpName + ".xml");
- if (!dumpfilename.getParentFile().exists() && !dumpfilename.getParentFile().mkdirs()) {
- LOGGER.warning("Error creating path to dump file: " + dumpfilename);
- }
- else{
- LOGGER.info("Dumping xml to file " + dumpfilename.getAbsolutePath());
- FileOutputStream dumpfile = new FileOutputStream(dumpfilename);
- dumpfile.write(baos.toByteArray());
- dumpfile.close();
- stream = new ByteArrayInputStream(baos.toByteArray());
- }
- }
-
- try (Reader reader = new InputStreamReader(stream, StandardCharsets.UTF_8))
- {
- XMLInputFactory inputFactory = XMLInputFactory.newFactory();
- preventXXE(inputFactory);
- BufferedReader br = skipBOM(reader);
- // InputStream in = new ByteArrayInputStream(xmlBuffer);
- XMLEventReader eventReader = inputFactory.createXMLEventReader(br);
-
- return parser.parse(eventReader, getLanguages());
- }
- }
- else
- {
- InputStream is = ((HttpURLConnection)conn).getErrorStream();
- if(is != null){
- String msg = new BufferedReader(new InputStreamReader(is)).readLine();
- LOGGER.severe(msg);
- }
- SdmxException ex = SdmxExceptionFactory.createRestException(code, null, null);
- if (conn instanceof HttpURLConnection)
- ((HttpURLConnection) conn).disconnect();
- throw ex;
- }
- }
- catch (IOException e)
- {
- LOGGER.severe("Exception. Class: " + e.getClass().getName() + " - Message: " + e.getMessage());
- LOGGER.log(Level.FINER, "Exception: ", e);
- throw SdmxExceptionFactory.wrap(e);
- }
- catch (XMLStreamException e)
- {
- LOGGER.severe("Exception caught parsing results from call to provider " + name);
- LOGGER.log(Level.FINER, "Exception: ", e);
- throw SdmxExceptionFactory.wrap(e);
- }
- catch (URISyntaxException e)
- {
- LOGGER.severe("Exception caught parsing results from call to provider " + name);
- LOGGER.log(Level.FINER, "Exception: ", e);
- throw SdmxExceptionFactory.wrap(e);
- }
- finally
- {
- if (conn != null && conn instanceof HttpURLConnection)
- ((HttpURLConnection) conn).disconnect();
- }
- }
-
- protected void handleHttpHeaders(HttpURLConnection conn, String acceptHeader)
- {
- String lList = Configuration.getLanguages().stream()
- .map(lr -> format(Locale.US, "%s;q=%.1f", lr.getRange(), lr.getWeight()))
- .collect(joining(","));
- conn.addRequestProperty("Accept-Language", lList);
- if (containsCredentials)
- {
- LOGGER.fine("Setting http authorization");
- // https://stackoverflow.com/questions/1968416/how-to-do-http-authentication-in-android/1968873#1968873
- //String auth = Base64.encodeToString((user + ":" + pw).getBytes(), Base64.NO_WRAP);
- String auth = java.util.Base64.getEncoder().encodeToString((user + ":" + pw).getBytes());
- conn.setRequestProperty("Authorization", "Basic " + auth);
- }
- if (supportsCompression)
- {
- conn.addRequestProperty("Accept-Encoding", "gzip,deflate");
- }
- if (acceptHeader != null && !"".equals(acceptHeader))
- conn.setRequestProperty("Accept", acceptHeader);
- else
- conn.setRequestProperty("Accept", "*/*");
- }
-
protected URL buildDataQuery(Dataflow dataflow, String resource, String startTime, String endTime, boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException
{
- if (endpoint != null && dataflow != null && resource != null && !resource.isEmpty())
+ if (provider.getEndpoint() != null && dataflow != null && resource != null && !resource.isEmpty())
return Sdmx21Queries
- .createDataQuery(endpoint, dataflow.getFullIdentifier(), resource, startTime, endTime, serieskeysonly, updatedAfter, includeHistory, null)
+ .createDataQuery(provider.getEndpoint(), dataflow.getFullIdentifier(), resource, startTime, endTime, serieskeysonly, updatedAfter, includeHistory, null)
.buildSdmx21Query();
else
- throw new SdmxInvalidParameterException("Invalid query parameters: dataflow=" + dataflow + " resource=" + resource + " endpoint=" + endpoint);
+ throw new SdmxInvalidParameterException("Invalid query parameters: dataflow=" + dataflow + " resource=" + resource + " endpoint=" + provider.getEndpoint());
}
protected URL buildDSDQuery(String dsd, String agency, String version, boolean full) throws SdmxException
{
- if (endpoint != null && agency != null && !agency.isEmpty() && dsd != null && !dsd.isEmpty())
- return Sdmx21Queries.createStructureQuery(endpoint, dsd, agency, version, full).buildSdmx21Query();
+ if (provider.getEndpoint() != null && agency != null && !agency.isEmpty() && dsd != null && !dsd.isEmpty())
+ return Sdmx21Queries.createStructureQuery(provider.getEndpoint(), dsd, agency, version, full).buildSdmx21Query();
else
- throw new RuntimeException("Invalid query parameters: agency=" + agency + " dsd=" + dsd + " endpoint=" + endpoint);
+ throw new RuntimeException("Invalid query parameters: agency=" + agency + " dsd=" + dsd + " endpoint=" + provider.getEndpoint());
}
protected URL buildFlowQuery(String dataflow, String agency, String version) throws SdmxException
{
- return Sdmx21Queries.createDataflowQuery(endpoint, dataflow, agency, version).buildSdmx21Query();
+ return Sdmx21Queries.createDataflowQuery(provider.getEndpoint(), dataflow, agency, version).buildSdmx21Query();
}
protected URL buildCodelistQuery(String codeList, String agency, String version) throws SdmxException
{
- return Sdmx21Queries.createCodelistQuery(endpoint, codeList, agency, version).buildSdmx21Query();
- }
-
- private static boolean isRedirection(int code)
- {
- return (code >= HttpURLConnection.HTTP_MULT_CHOICE && code <= HttpURLConnection.HTTP_SEE_OTHER)
- || code == 307; // TEMPORARY REDIRECT
- }
-
- private static URL getRedirectionURL(URLConnection conn, int code) throws SdmxIOException
- {
- String location = conn.getHeaderField("Location");
- if (location == null || location.isEmpty())
- {
- throw new SdmxIOException("The endpoint returned redirect code: " + code + ", but the location was empty.", null);
- }
- try
- {
- return new URL(location);
- }
- catch (MalformedURLException ex)
- {
- throw new SdmxIOException("The endpoint returned redirect code: " + code + ", but the location was malformed: '" + location + "'.", null);
- }
- }
-
- // some 2.0 providers are apparently adding a BOM
- public BufferedReader skipBOM(Reader xmlBuffer) throws SdmxException
- {
- BufferedReader br = new BufferedReader(xmlBuffer) {
- @Override
- public void close() throws IOException
- {
- LOGGER.fine("GenericDataParser::skipBOM: closing stream.");
- super.close();
- }
- };
- try
- {
- // java uses Unicode big endian
- char[] cbuf = new char[1];
- // TODO: Source of problems here
- br.mark(1);
- br.read(cbuf, 0, 1);
- LOGGER.fine(String.format("0x%2s", Integer.toHexString(cbuf[0])));
- if ((byte) cbuf[0] == (byte) 0xfeff)
- {
- LOGGER.fine("BOM found and skipped");
- }
- else
- {
- // TODO: Source of problems here
- LOGGER.fine("GenericDataParser::skipBOM: Resetting stream.");
- br.reset();
- }
- }
- catch (IOException e)
- {
- throw SdmxExceptionFactory.wrap(e);
- }
- return br;
- }
-
- // https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#XMLInputFactory_.28a_StAX_parser.29
- private static void preventXXE(XMLInputFactory factory)
- {
- if (factory.isPropertySupported(XMLInputFactory.SUPPORT_DTD))
- {
- factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
- }
- if (factory.isPropertySupported(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES))
- {
- factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
- }
+ return Sdmx21Queries.createCodelistQuery(provider.getEndpoint(), codeList, agency, version).buildSdmx21Query();
}
/**
@@ -656,20 +234,32 @@ protected List> postProcess(DataParsingResult result)
{
return result;
}
-
- private boolean isMaxRedirectionReached(int redirects) {
- return redirects > maxRedirects;
- }
-
- /**
- * https://en.wikipedia.org/wiki/Downgrade_attack
- *
- * @param oldUrl
- * @param newUrl
- * @return
- */
- private static boolean isDowngradingProtocolOnRedirect(URL oldUrl, URL newUrl) {
- return "https".equalsIgnoreCase(oldUrl.getProtocol())
- && !"https".equalsIgnoreCase(newUrl.getProtocol());
+
+ public Map handleHttpHeaders(String acceptHeader)
+ {
+ Map headers = new HashMap<>();
+ String lList = Configuration.getLanguages().stream()
+ .map(lr -> String.format(Locale.US, "%s;q=%.1f", lr.getRange(), lr.getWeight()))
+ .collect(joining(","));
+
+ headers.put("Accept-Language", lList);
+ if (containsCredentials)
+ {
+ LOGGER.fine("Setting http authorization");
+ // https://stackoverflow.com/questions/1968416/how-to-do-http-authentication-in-android/1968873#1968873
+ //String auth = Base64.encodeToString((user + ":" + pw).getBytes(), Base64.NO_WRAP);
+ String auth = java.util.Base64.getEncoder().encodeToString((user + ":" + pw).getBytes());
+ headers.put("Authorization", "Basic " + auth);
+ }
+
+ if (provider.isSupportsCompression())
+ headers.put("Accept-Encoding", "gzip,deflate");
+
+ if (acceptHeader != null && !"".equals(acceptHeader))
+ headers.put("Accept", acceptHeader);
+ else
+ headers.put("Accept", "*/*");
+ headers.put("user-agent", "RJSDMX");
+ return headers;
}
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/SASClientHandler.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/SASClientHandler.java
index 3c1f1ffc..19857474 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/SASClientHandler.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/SASClientHandler.java
@@ -349,7 +349,7 @@ public static int makeGetTimeSeries(String provider, String tsKey, String startT
obsmetadata = null;
try
{
- List> result = SdmxClientHandler.getTimeSeries(provider, null, tsKey, null, startTime, endTime, false, null, false);
+ List> result = SdmxClientHandler.getTimeSeries(provider, tsKey, startTime, endTime, false, null, false);
if (!result.isEmpty())
{
// check size of full result as a table
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/SDMXClientFactory.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/SDMXClientFactory.java
index c753492f..1db66973 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/SDMXClientFactory.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/SDMXClientFactory.java
@@ -20,61 +20,47 @@
*/
package it.bancaditalia.oss.sdmx.client;
+import static it.bancaditalia.oss.sdmx.api.SDMXVersion.V2;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
import java.net.ProxySelector;
import java.net.URI;
import java.net.URISyntaxException;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
import java.util.NavigableMap;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import it.bancaditalia.oss.sdmx.api.GenericSDMXClient;
+import it.bancaditalia.oss.sdmx.api.SDMXVersion;
import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxExceptionFactory;
import it.bancaditalia.oss.sdmx.exceptions.SdmxInvalidParameterException;
import it.bancaditalia.oss.sdmx.exceptions.SdmxUnknownProviderException;
import it.bancaditalia.oss.sdmx.util.Configuration;
import it.bancaditalia.oss.sdmx.util.SdmxProxySelector;
/**
- *
Java Factory class for creating the Sdmx Clients.
+ *
+ * Java Factory class for creating the Sdmx Clients.
*
* @author Attilio Mattiocco
*
*/
-public class SDMXClientFactory {
+public class SDMXClientFactory
+{
- private static final String ECB_PROVIDER = "https://sdw-wsrest.ecb.europa.eu/service";
- private static final String ISTAT_PROVIDER_POP = "http://sdmx.istat.it/WS_CENSPOP/rest";
- private static final String ISTAT_RI_PROVIDER = "https://esploradati.istat.it/SDMXWS/rest";
- private static final String ISTAT_PROVIDER_AGR = "http://sdmx.istat.it/WS_CENSAGR/rest";
- private static final String ISTAT_PROVIDER_IND = "http://sdmx.istat.it/WS_CIS/rest";
- private static final String INSEE_PROVIDER = "https://bdm.insee.fr/series/sdmx";
- private static final String UNDATA_PROVIDER = "http://data.un.org/WS/rest";
- private static final String WITS_PROVIDER = "http://wits.worldbank.org/API/V1/SDMX/V21/rest";
- private static final String ILO_PROVIDER = "https://www.ilo.org/sdmx/rest";
- private static final String ABS_PROVIDER = "https://api.data.abs.gov.au";
- private static final String UNICEF_PROVIDER = "https://sdmx.data.unicef.org/ws/public/sdmxapi/rest";
- private static final String BIS_PROVIDER = "https://stats.bis.org/api/v1";
- public static final String SDMX_V2 = "SDMX_V2"; // 2.0 or 2.1
- public static final String SDMX_V3 = "SDMX_V3"; //new 3.0
- //read the configuration file
- static {
+ // read the configuration file
+ static
+ {
providers = new TreeMap<>();
logger = Configuration.getSdmxLogger();
- try {
- initBuiltInProviders();
+ try
+ {
initExternalProviders();
- } catch (SdmxException e) {
+ }
+ catch (SdmxException e)
+ {
e.printStackTrace();
}
}
@@ -83,279 +69,151 @@ public class SDMXClientFactory {
protected static Logger logger;
private static NavigableMap providers;
-
- /**
- * Initialize the internal sdmx providers
- * @throws SdmxException
- *
- */
- private static void initBuiltInProviders() throws SdmxException{
- addBuiltInProvider("ECB", ECB_PROVIDER, false, false, true, "European Central Bank", false, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("ISTAT_RI", ISTAT_RI_PROVIDER, false, false, false, "Italian National Institute of Statistics", false, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("ISTAT_CENSUS_POP", ISTAT_PROVIDER_POP, false, false, false, "ISTAT - Population and housing census 2011", false, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("ISTAT_CENSUS_AGR", ISTAT_PROVIDER_AGR, false, false, false, "ISTAT - Agricultural census 2010", false, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("ISTAT_CENSUS_IND", ISTAT_PROVIDER_IND, false, false, false, "ISTAT - Industry and services census 2011", false, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("INSEE", INSEE_PROVIDER, false, false, true, "National Institute of Statistics and Economic Studies", false, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("UNDATA", UNDATA_PROVIDER, false, false, false, "Data access system to UN databases", false, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("WITS", WITS_PROVIDER, false, false, false, "World Integrated Trade Solutions", false, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("ILO", ILO_PROVIDER, false, false, false, "International Labour Organization", false, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("ABS", ABS_PROVIDER, false, false, false, "Australian Bureau of Statistics - SDMX 2.1", false, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("UNICEF", UNICEF_PROVIDER, false, false, true, "UNICEF", false, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("BIS_PUBLIC", BIS_PROVIDER, false, false, true, "Bank for International Settlements", false, SDMXClientFactory.SDMX_V2);
-
- //add internal providers
- addBuiltInProvider("ISTAT", null, false, false, false, "Italian National Institute of Statistics ", true, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("OECD", null, false, false, false, "The Organisation for Economic Co-operation and Development", true, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("StatsEE", null, false, false, false, "Statistics Estonia (BETA)", true, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("OECD_RESTR", null, true, false, false, "The Organisation for Economic Co-operation and Development, RESTRICTED ACCESS", true, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("IMF2", null, false, false, false, "New International Monetary Fund endpoint", true, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("NBB", null, false, false, false, "National Bank Belgium", true, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("WB", null, false, false, false, "World Bank - World Development Indicators", true, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("INEGI", null, false, false, false, "Instituto Nacional de Estadistica y Geografia", true, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("EUROSTAT", null, false, false, false, "Eurostat", true, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("EUROSTAT_COMEXT", null, false, false, false, "Eurostat - COMEXT", true, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("EUROSTAT_GROW", null, false, false, false, "Eurostat - DG GROW", true, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("EUROSTAT_COMP", null, false, false, false, "Eurostat - DG COMP", true, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("EUROSTAT_EMPL", null, false, false, false, "Eurostat - DG EMPL", true, SDMXClientFactory.SDMX_V2);
- addBuiltInProvider("BBK", null, false, false, false, "Deutsche Bundesbank", true, SDMXClientFactory.SDMX_V2);
- }
-
/**
- * Initialize the sdmx providers from the configuration file
- * @throws SdmxException
- */
- private static void initExternalProviders() throws SdmxException{
- //external providers set in the configuration file
- String external = Configuration.getExternalProviders();
- if(external != null && !external.isEmpty()){
- String[] ids = external.trim().split("\\s*,\\s*");
- for (int i = 0; i < ids.length; i++) {
- addExternalProvider(ids[i]);
- }
- }
- }
-
- /**
- * General method for creating an SdmxClient.
- *
- * @param name The name of the provider to create.
- * @param endpoint the {@link URI} of the provider to create.
- * @param needsCredentials true if the provider needs authentication.
- * @param needsURLEncoding true if the provider needs the URL to be encoded.
- * @param supportsCompression true if the provider supports HTTP compression features.
- * @param description The description of the provider
- * @param isCustom true if the provider has an implementing class in the package it.bancaditalia.oss.sdmx.client.custom
- * @param sdmxVersion the major version of the SDMX standard of this provider (SDMX_V2 or SDMX_V3)
+ * Initialize the sdmx providers from the configuration file
*
- * @throws SdmxException if there is an error creating the provider.
+ * @throws SdmxException
*/
- public static void addProvider(String name, URI endpoint, boolean needsCredentials,
- boolean needsURLEncoding, boolean supportsCompression, String description,
- boolean isCustom, String sdmxVersion) throws SdmxException{
- Provider p = new Provider(name, endpoint, null, needsCredentials, needsURLEncoding, supportsCompression, description, isCustom, sdmxVersion);
- providers.put(name, p);
+ private static void initExternalProviders() throws SdmxException
+ {
+ // external providers set in the configuration file
+ String external = Configuration.getExternalProviders();
+ if (external != null && !external.isEmpty())
+ {
+ String[] ids = external.trim().split("\\s*,\\s*");
+ for (int i = 0; i < ids.length; i++)
+ addExternalProvider(ids[i]);
+ }
}
/**
- * General method for creating an SdmxClient.
- *
- * @param name The name of the provider to create.
- * @param endpoint the {@link URI} of the provider to create.
- * @param needsCredentials true if the provider needs authentication.
- * @param needsURLEncoding true if the provider needs the URL to be encoded.
- * @param supportsCompression true if the provider supports HTTP compression features.
- * @param description The description of the provider
- * @param isCustom true if the provider has an implementing class in the package it.bancaditalia.oss.sdmx.client.custom
+ * General method for creating an SdmxClient.
+ *
+ * @param name The name of the provider to create.
+ * @param endpoint the {@link URI} of the provider to create.
+ * @param needsCredentials true if the provider needs authentication.
+ * @param needsURLEncoding true if the provider needs the URL to be encoded.
+ * @param supportsCompression true if the provider supports HTTP compression
+ * features.
+ * @param description The description of the provider
*
- * @throws SdmxException if there is an error creating the provider.
+ * @throws SdmxException if there is an error creating the provider.
*/
- public static void addProvider(String name, URI endpoint, boolean needsCredentials,
- boolean needsURLEncoding, boolean supportsCompression, String description,
- boolean isCustom) throws SdmxException{
- Provider p = new Provider(name, endpoint, null, needsCredentials, needsURLEncoding, supportsCompression, description, isCustom, SDMX_V2);
- providers.put(name, p);
+ public static void addProvider(String name, URI endpoint, boolean needsCredentials, boolean needsURLEncoding, boolean supportsCompression, String description) throws SdmxException
+ {
+ addProvider(name, endpoint, needsCredentials, needsURLEncoding, supportsCompression, description, V2);
}
/**
- * General method for creating an SdmxClient.
- *
- * @param name The name of the provider to create.
- * @param endpoint the {@link URI} of the provider to create.
- * @param trustStore A truststore to use to connect to this provider.
- * @param needsCredentials true if the provider needs authentication.
- * @param needsURLEncoding true if the provider needs the URL to be encoded.
- * @param supportsCompression true if the provider supports HTTP compression features.
- * @param description The description of the provider
- * @param isCustom true if the provider has an implementing class in the package it.bancaditalia.oss.sdmx.client.custom
- * @param sdmxVersion the major version of the SDMX standard of this provider (SDMX_V2 or SDMX_V3)
- *
- * @throws SdmxException if there is an error creating the provider.
- */
- public static void addProvider(String name, URI endpoint, KeyStore trustStore, boolean needsCredentials,
- boolean needsURLEncoding, boolean supportsCompression, String description,
- boolean isCustom, String sdmxVersion) throws SdmxException{
- Provider p = new Provider(name, endpoint, trustStore, needsCredentials, needsURLEncoding, supportsCompression, description, isCustom, sdmxVersion);
- providers.put(name, p);
- }
-
- /**
* General method for creating an SdmxClient.
*
- * @param name The name of the provider to create.
- * @param endpoint the {@link URI} of the provider to create.
- * @param trustStore A truststore to use to connect to this provider.
- * @param needsCredentials true if the provider needs authentication.
- * @param needsURLEncoding true if the provider needs the URL to be encoded.
- * @param supportsCompression true if the provider supports HTTP compression features.
- * @param description The description of the provider
- * @param isCustom true if the provider has an implementing class in the package it.bancaditalia.oss.sdmx.client.custom
+ * @param name The name of the provider to create.
+ * @param endpoint the {@link URI} of the provider to create.
+ * @param needsCredentials true if the provider needs authentication.
+ * @param needsURLEncoding true if the provider needs the URL to be encoded.
+ * @param supportsCompression true if the provider supports HTTP compression
+ * features.
+ * @param description The description of the provider
+ * @param sdmxVersion the major version of the SDMX standard of this
+ * provider (SDMX_V2 or SDMX_V3)
*
- * @throws SdmxException if there is an error creating the provider.
+ * @throws SdmxException if there is an error creating the provider.
*/
- public static void addProvider(String name, URI endpoint, KeyStore trustStore, boolean needsCredentials,
- boolean needsURLEncoding, boolean supportsCompression, String description,
- boolean isCustom) throws SdmxException{
- Provider p = new Provider(name, endpoint, trustStore, needsCredentials, needsURLEncoding, supportsCompression, description, isCustom, SDMX_V2);
+ public static void addProvider(String name, URI endpoint, boolean needsCredentials, boolean needsURLEncoding, boolean supportsCompression, String description, SDMXVersion sdmxVersion) throws SdmxException
+ {
+ Provider p = new Provider(name, endpoint, needsCredentials, needsURLEncoding, supportsCompression, description, sdmxVersion);
providers.put(name, p);
}
/**
- * Add a builtin provider and check whether the default values need to be overwritten with values defined in the configuration file.
- * @throws SdmxException
- */
- private static void addBuiltInProvider(final String name, final String endpoint, final Boolean needsCredentials,
- final Boolean needsURLEncoding, final Boolean supportsCompression, final String description,
- boolean isCustom, String sdmxVersion) throws SdmxException {
- try {
- final String providerName = Configuration.getConfiguration().getProperty("providers." + name + ".name", name);
- final String providerEndpoint = Configuration.getConfiguration().getProperty("providers." + name + ".endpoint", endpoint);
- final URI providerURL = null != providerEndpoint ? new URI(providerEndpoint) : null;
- final boolean providerNeedsCredentials = Boolean.parseBoolean(Configuration.getConfiguration().getProperty("providers." + name + ".needsCredentials", needsCredentials.toString()));
- final boolean providerNeedsURLEncoding = Boolean.parseBoolean(Configuration.getConfiguration().getProperty("providers." + name + ".needsURLEncoding", needsURLEncoding.toString()));
- final boolean providerSupportsCompression = Boolean.parseBoolean(Configuration.getConfiguration().getProperty("providers." + name + ".supportsCompression", supportsCompression.toString()));
- final String providerDescription = Configuration.getConfiguration().getProperty("providers." + name + ".description", description);
- final String providerSdmxVersion = Configuration.getConfiguration().getProperty("providers." + name + ".sdmxversion", sdmxVersion.toString());
- addProvider(providerName, providerURL, null, providerNeedsCredentials, providerNeedsURLEncoding, providerSupportsCompression, providerDescription, isCustom, providerSdmxVersion);
- } catch (URISyntaxException e) {
- logger.log(Level.SEVERE, "Exception. Class: {0} .Message: {1}", new Object[]{e.getClass().getName(), e.getMessage()});
- logger.log(Level.FINER, "", e);
+ * Add a external provider and check whether the default values need to be
+ * overwritten with values defined in the configuration file.
+ *
+ * @throws SdmxException
+ */
+ private static void addExternalProvider(final String id) throws SdmxException
+ {
+ try
+ {
+ final String providerName = Configuration.getProperty("providers." + id + ".name", id);
+ final String providerEndpoint = Configuration.getProperty("providers." + id + ".endpoint", (String) null);
+ if (providerEndpoint != null && !providerEndpoint.isEmpty())
+ {
+ URI providerURL = new URI(providerEndpoint);
+ boolean providerNeedsCredentials = Configuration.getProperty("providers." + id + ".needsCredentials", false);
+ boolean providerNeedsURLEncoding = Configuration.getProperty("providers." + id + ".needsURLEncoding", false);
+ boolean providerSupportsCompression = Configuration.getProperty("providers." + id + ".supportsCompression", false);
+ String providerDescription = Configuration.getProperty("providers." + id + ".description", id);
+ SDMXVersion providerSdmxVersion = Configuration.getProperty("providers." + id + ".sdmxversion", V2);
+ addProvider(providerName, providerURL, providerNeedsCredentials, providerNeedsURLEncoding, providerSupportsCompression, providerDescription, providerSdmxVersion);
+ }
+ else
+ {
+ logger.warning("No URL has been configured for the external provider: '" + id + "'. It will be skipped.");
+ return;
+ }
}
- }
-
- /**
- * Add a external provider and check whether the default values need to be overwritten with values defined in the configuration file.
- * @throws SdmxException
- */
- private static void addExternalProvider(final String id) throws SdmxException {
- try {
- final String providerName = Configuration.getConfiguration().getProperty("providers." + id + ".name", id);
- final String providerEndpoint = Configuration.getConfiguration().getProperty("providers." + id + ".endpoint");
- if(providerEndpoint != null && !providerEndpoint.isEmpty()){
- final URI providerURL = new URI(providerEndpoint);
- final boolean provdiderNeedsCredentials = Boolean.parseBoolean(Configuration.getConfiguration().getProperty("providers." + id + ".needsCredentials", "false"));
- final boolean providerNeedsURLEncoding = Boolean.parseBoolean(Configuration.getConfiguration().getProperty("providers." + id + ".needsURLEncoding", "false"));
- final boolean providerSupportsCompression = Boolean.parseBoolean(Configuration.getConfiguration().getProperty("providers." + id + ".supportsCompression", "false"));
- final String providerDescription = Configuration.getConfiguration().getProperty("providers." + id + ".description", id);
- final String providerSdmxVersion = Configuration.getConfiguration().getProperty("providers." + id + ".sdmxversion", SDMXClientFactory.SDMX_V2);
-
- String trustStoreLocation = Configuration.getConfiguration().getProperty("providers." + id + ".trustStore", "");
- KeyStore providerTrustStore = null;
- if (!"".equals(trustStoreLocation))
- try {
- InputStream trustStoreFile = new FileInputStream(new File(trustStoreLocation));
- providerTrustStore = KeyStore.getInstance(KeyStore.getDefaultType());
- providerTrustStore.load(trustStoreFile, "changeit".toCharArray());
- } catch (FileNotFoundException e) {
- logger.warning("Cannot open trust store at " + trustStoreLocation);
- } catch (GeneralSecurityException e) {
- e.printStackTrace();
- } catch (IOException e) {
- throw SdmxExceptionFactory.wrap(e);
- } finally {
- providerTrustStore = null;
- }
-
- addProvider(providerName, providerURL, providerTrustStore, provdiderNeedsCredentials, providerNeedsURLEncoding, providerSupportsCompression, providerDescription, false, providerSdmxVersion);
- }
- else{
- logger.warning("No URL has been configured for the external provider: '" + id + "'. It will be skipped.");
- return;
- }
- } catch (URISyntaxException e) {
- logger.log(Level.SEVERE, "Exception. Class: {0} .Message: {1}", new Object[]{e.getClass().getName(), e.getMessage()});
- logger.log(Level.FINER, "", e);
+ catch (URISyntaxException e)
+ {
+ logger.log(Level.SEVERE, "Exception. Class: {0} .Message: {1}", new Object[] { e.getClass().getName(), e.getMessage() });
+ logger.log(Level.FINER, "", e);
}
- }
+ }
/**
- * General method for creating an SdmxClient.
- *
- * @param providerName A non-null provider identification short name.
+ * General method for creating an SdmxClient.
+ *
+ * @param providerName A non-null provider identification short name.
* @return The client.
* @throws SdmxException if there is an error creating the client.
*/
- public static GenericSDMXClient createClient(String providerName) throws SdmxException {
+ public static GenericSDMXClient createClient(String providerName) throws SdmxException
+ {
final String sourceMethod = "createClient";
logger.entering(sourceClass, sourceMethod);
logger.fine("Create an SDMX client for '" + providerName + "'");
GenericSDMXClient client = null;
Provider provider = providers.get(providerName);
- if(provider == null){
+ if (provider == null)
throw new SdmxInvalidParameterException("The provider '" + providerName + "' is not available in this configuration.");
- }
- String hostname = null;
- if(provider != null && !provider.isCustom())
+ try
{
- hostname = provider.getEndpoint().getHost();
- if(provider.getEndpoint().getScheme().toLowerCase().startsWith("http")){
- if(provider.getSdmxVersion().trim().equalsIgnoreCase(SDMXClientFactory.SDMX_V2)){
- client = new RestSdmxClient(provider.getName(), provider.getEndpoint(), provider.getSSLSocketFactory(), provider.isNeedsCredentials(), provider.isNeedsURLEncoding(), provider.isSupportsCompression());
- }
- else if(provider.getSdmxVersion().trim().equalsIgnoreCase(SDMXClientFactory.SDMX_V3)){
- client = new RestSdmx30Client(provider.getName(), provider.getEndpoint(), provider.getSSLSocketFactory(), provider.isNeedsCredentials(), provider.isNeedsURLEncoding(), provider.isSupportsCompression());
- }
- else{
- throw new SdmxInvalidParameterException("The sdmx version '" + provider.getSdmxVersion() + "' is not supported.");
+ // Try to find a custom provider if an appropriate class exists
+ Class extends GenericSDMXClient> clazz = Class.forName("it.bancaditalia.oss.sdmx.client.custom." + providerName).asSubclass(GenericSDMXClient.class);
+ client = clazz.getConstructor(Provider.class).newInstance(provider);
+ }
+ catch (ClassNotFoundException e)
+ {
+ // No custom provider found, instantiate the generic SDMX client
+ if (provider.getEndpoint().getScheme().toLowerCase().startsWith("http"))
+ switch (provider.getSdmxVersion())
+ {
+ case V2: client = new RestSdmxClient(provider); break;
+ case V3: client = new RestSdmx30Client(provider); break;
+ default: throw new SdmxInvalidParameterException("Unsupported SDMX REST API version: " + provider.getSdmxVersion());
}
- }
- else
- {
+ else
throw new SdmxInvalidParameterException("The protocol '" + provider.getEndpoint().getScheme() + "' is not supported.");
- }
}
- else {
- ///legacy 2.0
- try {
- Class> clazz = Class.forName("it.bancaditalia.oss.sdmx.client.custom." + providerName);
- client = (GenericSDMXClient)clazz.newInstance();
- // apply customizations eventually added by user in configuration file
- // for now only endpoint can be overridden
- if (provider.getEndpoint() != null)
- client.setEndpoint(provider.getEndpoint());
-
- if (client.getEndpoint() != null)
- hostname = client.getEndpoint().getHost();
-
- client.setName(providerName);
- }
- catch (ClassNotFoundException e) {
- logger.severe("The provider '" + providerName + "' is not available in this configuration.");
- throw new SdmxUnknownProviderException(providerName, e);
- } catch (IllegalAccessException e) {
- logger.severe("The provider implementation it.bancaditalia.oss.sdmx.client.custom." + providerName + " does not define a default constructor.");
- throw new SdmxUnknownProviderException(providerName, e);
- } catch (InstantiationException e) {
- logger.severe("Could not instantiate provider implementation it.bancaditalia.oss.sdmx.client.custom." + providerName);
- throw new SdmxUnknownProviderException(providerName, e);
- }
+ catch (NoSuchMethodException | IllegalAccessException e)
+ {
+ logger.severe("The provider implementation it.bancaditalia.oss.sdmx.client.custom." + providerName + " does not define a default constructor.");
+ throw new SdmxUnknownProviderException(providerName, e);
+ }
+ catch (InstantiationException | InvocationTargetException e)
+ {
+ logger.severe("Could not instantiate provider implementation it.bancaditalia.oss.sdmx.client.custom." + providerName);
+ throw new SdmxUnknownProviderException(providerName, e);
}
+
+ String hostname = provider.getEndpoint().getHost();
// now set default proxy if necessary
- ProxySelector ps = ProxySelector.getDefault();
+ ProxySelector ps = ProxySelector.getDefault();
if (hostname != null && ps != null && ps instanceof SdmxProxySelector)
- ((SdmxProxySelector)ps).addToDefaultProxy(hostname);
+ ((SdmxProxySelector) ps).addToDefaultProxy(hostname);
logger.exiting(sourceClass, sourceMethod);
return client;
@@ -363,9 +221,12 @@ else if(provider.getSdmxVersion().trim().equalsIgnoreCase(SDMXClientFactory.SDMX
/**
* Get the list of all available SDMX Providers
- * @return A map of providers with keys as names and {@link Provider} instances as values.
+ *
+ * @return A map of providers with keys as names and {@link Provider} instances
+ * as values.
*/
- public static NavigableMap getProviders() {
- return providers;
- }
+ public static NavigableMap getProviders()
+ {
+ return providers;
+ }
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/SdmxClientHandler.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/SdmxClientHandler.java
index 5f4b931b..57c1c461 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/SdmxClientHandler.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/SdmxClientHandler.java
@@ -20,40 +20,22 @@
*/
package it.bancaditalia.oss.sdmx.client;
+import it.bancaditalia.oss.sdmx.api.*;
+import it.bancaditalia.oss.sdmx.client.custom.RestSdmx20Client;
+import it.bancaditalia.oss.sdmx.exceptions.*;
+import it.bancaditalia.oss.sdmx.util.Configuration;
+import it.bancaditalia.oss.sdmx.util.LoginDialog;
+
+import javax.swing.*;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.Map.Entry;
-import java.util.SortedMap;
-import java.util.TreeMap;
import java.util.logging.Logger;
import java.util.stream.Collectors;
-import javax.swing.JFrame;
-
-import it.bancaditalia.oss.sdmx.api.Codelist;
-import it.bancaditalia.oss.sdmx.api.DataFlowStructure;
-import it.bancaditalia.oss.sdmx.api.Dataflow;
-import it.bancaditalia.oss.sdmx.api.Dimension;
-import it.bancaditalia.oss.sdmx.api.GenericSDMXClient;
-import it.bancaditalia.oss.sdmx.api.SDMXReference;
-import it.bancaditalia.oss.sdmx.api.PortableDataSet;
-import it.bancaditalia.oss.sdmx.api.PortableTimeSeries;
-import it.bancaditalia.oss.sdmx.api.SdmxAttribute;
-import it.bancaditalia.oss.sdmx.client.custom.RestSdmx20Client;
-import it.bancaditalia.oss.sdmx.exceptions.DataStructureException;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxInvalidParameterException;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxUnknownProviderException;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxXmlContentException;
-import it.bancaditalia.oss.sdmx.util.Configuration;
-import it.bancaditalia.oss.sdmx.util.LoginDialog;
+import static it.bancaditalia.oss.sdmx.api.SDMXVersion.V2;
/**
*
@@ -118,44 +100,7 @@ public static void addLocalProvider(String provider, String endpoint, String des
"The enpoint of the provider has to be an existing local directory");
}
- SDMXClientFactory.addProvider(provider, epFile.toURI(), null, false, false, false, description, false);
- }
-
- /**
- * Adds a local provider
- *
- * @param provider a non-null, non-empty provider identification short name.
- * @param endpoint a non-null provider-defined endpoint url for queries
- * @param needsCredentials true if the provider needs authentication
- * @param needsURLEncoding true if the url must be encoded
- * @param supportsCompression true if the provider supports message compression
- * @param description an optional natural language description of the provider
- *
- * @throws SdmxException
- */
- public static void addProvider(String provider, String endpoint, boolean needsCredentials, boolean needsURLEncoding,
- boolean supportsCompression, String description) throws SdmxException
- {
-
- if (provider == null || provider.trim().isEmpty())
- {
- LOGGER.severe("The name of the provider cannot be null");
- throw new SdmxInvalidParameterException("The name of the provider cannot be null");
- }
- if (endpoint == null)
- {
- LOGGER.severe("The enpoint of the provider cannot be null");
- throw new SdmxInvalidParameterException("The endpoint of the provider cannot be null");
- }
- try
- {
- SDMXClientFactory.addProvider(provider, new URI(endpoint), null, needsCredentials, needsURLEncoding,
- supportsCompression, description, false);
- }
- catch (URISyntaxException e)
- {
- throw new SdmxInvalidParameterException(e.getMessage());
- }
+ SDMXClientFactory.addProvider(provider, epFile.toURI(), false, false, false, description, V2);
}
/**
@@ -172,7 +117,7 @@ public static void addProvider(String provider, String endpoint, boolean needsCr
* @throws SdmxException
*/
public static void addProvider(String provider, String endpoint, boolean needsCredentials, boolean needsURLEncoding,
- boolean supportsCompression, String description, String sdmxVersion) throws SdmxException
+ boolean supportsCompression, String description, SDMXVersion sdmxVersion) throws SdmxException
{
if (provider == null || provider.trim().isEmpty())
@@ -187,8 +132,7 @@ public static void addProvider(String provider, String endpoint, boolean needsCr
}
try
{
- SDMXClientFactory.addProvider(provider, new URI(endpoint), null, needsCredentials, needsURLEncoding,
- supportsCompression, description, false, sdmxVersion);
+ SDMXClientFactory.addProvider(provider, new URI(endpoint), needsCredentials, needsURLEncoding, supportsCompression, description, sdmxVersion);
}
catch (URISyntaxException e)
{
@@ -359,7 +303,7 @@ public static Map> filterCodes(String provider, Stri
}
- public static Integer getSeriesCount(String provider, String dataflow, String filter) throws SdmxException
+ public static Map getSeriesCount(String provider, String dataflow, String filter) throws SdmxException
{
if (provider == null || provider.trim().isEmpty())
{
@@ -483,50 +427,66 @@ public static Map getFlowObjects(String provider, String patte
return filterFlows(flows, pattern);
}
- public static PortableDataSet getTimeSeriesTable(String provider, String dataflow, String tsKey, String filter,
+ public static PortableDataSet getTimeSeriesTable(String provider, String tsKey,
String startTime, String endTime,
boolean serieskeysonly, String updatedAfter, boolean includeHistory)
throws SdmxException, DataStructureException
{
- return new PortableDataSet<>(getTimeSeries(provider, dataflow, tsKey, filter, startTime, endTime, serieskeysonly, updatedAfter, includeHistory));
+ return new PortableDataSet<>(getTimeSeries(provider, tsKey, startTime, endTime, serieskeysonly, updatedAfter, includeHistory));
}
- //shortcut for v2 API
- public static List> getTimeSeries(String provider, String tsKey, String startTime, String endTime) throws SdmxException
+ public static PortableDataSet getTimeSeriesTable2(String provider, String dataflow, String tsKey, String filter,
+ String startTime, String endTime,
+ String attributes, String measures, String updatedAfter, boolean includeHistory)
+ throws SdmxException, DataStructureException
{
- return getTimeSeries(provider, null, tsKey, null, startTime, endTime, false, null, false);
+
+ PortableDataSet ds = new PortableDataSet<>(getTimeSeries2(provider, dataflow, tsKey, filter, startTime, endTime, attributes, measures, updatedAfter, includeHistory));
+ ds.setDataflow(getFlow(provider, dataflow).getFullIdentifier());
+ return(ds);
}
- //full featured, valid for v2 and v3
- public static List> getTimeSeries(String provider, String dataflow, String tsKey, String filter,
+ //valid for sdmx v2
+ public static List> getTimeSeries(String provider, String tsKey,
String startTime, String endTime,
boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException
{
+
+ List> result = new ArrayList<>(); //SDMX 2.0 did not provide a way to specify multiple series keys
+ for (String keyId : tsKey.trim().split("\\s*;\\s*"))
+ result.addAll(getSingleTimeSeries(provider, keyId, startTime, endTime,
+ serieskeysonly, updatedAfter, includeHistory));
+ return (result);
+ }
+
+ //valid for sdmx v3
+ public static List> getTimeSeries2(String provider, String dataflow, String tsKey, String filter,
+ String startTime, String endTime,
+ String attributes, String measures, String updatedAfter, boolean includeHistory) throws SdmxException
+ {
if (provider == null || provider.trim().isEmpty())
{
LOGGER.severe("The name of the provider cannot be null");
throw new SdmxInvalidParameterException("The name of the provider cannot be null");
}
- if ((tsKey == null || tsKey.trim().isEmpty()) && (dataflow == null || dataflow.trim().isEmpty()))
+ if (dataflow == null || dataflow.trim().isEmpty())
{
- LOGGER.severe("Either the ts key or the dataflow must have valid values");
- throw new SdmxInvalidParameterException("Either the ts key or the dataflow must have valid values");
+ LOGGER.severe("The dataflow must have valid values");
+ throw new SdmxInvalidParameterException("The dataflow must have valid values");
}
- List> result = new ArrayList<>(); //SDMX 2.0 did not provide a way to specify multiple series keys
- if(tsKey != null && !tsKey.isEmpty()){
- for (String keyId : tsKey.trim().split("\\s*;\\s*"))
- result.addAll(getSingleTimeSeries(provider, dataflow, keyId, filter, startTime, endTime,
- serieskeysonly, updatedAfter, includeHistory));
- }
- else{
- result = getSingleTimeSeries(provider, dataflow, null, filter, startTime, endTime,
- serieskeysonly, updatedAfter, includeHistory);
- }
+ Dataflow df = getFlow(provider, dataflow);
+ DataFlowStructure dsd = getDataFlowStructure(provider, dataflow);
+
+ List> result = getClient(provider).getTimeSeries(df, dsd, tsKey, filter, startTime, endTime,
+ attributes, measures, updatedAfter, includeHistory);
+ if (result == null || result.size() == 0)
+ throw new SdmxXmlContentException(
+ "The query: key=" + tsKey + " and filter=" + filter + " did not match any time series on the provider for dataflow: " + dataflow);
return (result);
}
- private static List> getSingleTimeSeries(String provider, String dataflow, String tsKey, String filter,
+ private static List> getSingleTimeSeries(String provider, String tsKey,
String startTime, String endTime,
boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException
{
@@ -535,30 +495,28 @@ private static List> getSingleTimeSeries(String provi
LOGGER.severe("The name of the provider cannot be null");
throw new SdmxInvalidParameterException("The name of the provider cannot be null");
}
- if ((tsKey == null || tsKey.trim().isEmpty()) && (dataflow == null || dataflow.trim().isEmpty()))
+ if (tsKey == null || tsKey.trim().isEmpty())
{
- LOGGER.severe("Either the ts key or the dataflow must have valid values");
- throw new SdmxInvalidParameterException("Either the ts key or the dataflow must have valid values");
+ LOGGER.severe("The ts key must have valid values");
+ throw new SdmxInvalidParameterException("The ts key must have valid values");
}
List> result = null;
- if(dataflow == null || dataflow.isEmpty()){
- String[] tokens = extractFlowAndResource(tsKey);
- dataflow = tokens[0];
- tsKey = tokens[1];
- }
+ String[] tokens = extractFlowAndResource(tsKey);
+ String dataflow = tokens[0];
+ tsKey = tokens[1];
Dataflow df = getFlow(provider, dataflow);
DataFlowStructure dsd = getDataFlowStructure(provider, dataflow);
- result = getClient(provider).getTimeSeries(df, dsd, tsKey, filter, startTime, endTime, serieskeysonly, updatedAfter, includeHistory);
+ result = getClient(provider).getTimeSeries(df, dsd, tsKey, startTime, endTime, serieskeysonly, updatedAfter, includeHistory);
if (result == null || result.size() == 0)
throw new SdmxXmlContentException(
- "The query: key=" +tsKey + " and filter="+ filter + " did not match any time series on the provider for dataflow: " + dataflow);
+ "The query: key=" + tsKey + " did not match any time series on the provider for dataflow: " + dataflow);
return result;
}
- public static String getDataURL(String provider, String tsKey, String start, String end, boolean seriesKeysOnly,
+ public static String getDataURL(String provider, String dataflow, String resource, String start, String end, boolean seriesKeysOnly,
String updatedAfter, boolean includeHistory) throws SdmxException
{
if (provider == null || provider.trim().isEmpty())
@@ -566,17 +524,18 @@ public static String getDataURL(String provider, String tsKey, String start, Str
LOGGER.severe("The name of the provider cannot be null");
throw new SdmxInvalidParameterException("The name of the provider cannot be null");
}
- if (tsKey == null || tsKey.trim().isEmpty())
+ if (dataflow == null || dataflow.trim().isEmpty())
{
- LOGGER.severe("The tsKey cannot be null");
- throw new SdmxInvalidParameterException("The tsKey cannot be null");
+ LOGGER.severe("The dataflow cannot be null");
+ throw new SdmxInvalidParameterException("The dataflow cannot be null");
+ }
+ if (resource == null || resource.trim().isEmpty())
+ {
+ LOGGER.severe("The query cannot be null");
+ throw new SdmxInvalidParameterException("The query cannot be null");
}
- String[] tokens = extractFlowAndResource(tsKey);
- String dataflow = tokens[0];
- String resource = tokens[1];
Dataflow df = getFlow(provider, dataflow);
-
String result = getClient(provider).buildDataURL(df, resource, start, end, seriesKeysOnly, updatedAfter,
includeHistory);
return (result);
@@ -626,7 +585,7 @@ public static String dumpTimeSeriesList(List> ts)
return result.toString();
}
- public static String dumpTimeSeries(String provider, String dataflow, String id, String filter, String startTime, String endTime)
+ public static String dumpTimeSeries(String provider, String id, String startTime, String endTime)
throws SdmxException, DataStructureException
{
if (provider == null || provider.trim().isEmpty())
@@ -647,13 +606,13 @@ public static String dumpTimeSeries(String provider, String dataflow, String id,
if (!Configuration.isTable())
{
// Do it as a list of time series
- List> ts = getTimeSeries(provider, dataflow, id, filter, startTime, endTime, false, null, false);
+ List> ts = getTimeSeries(provider, id, startTime, endTime, false, null, false);
result = dumpTimeSeriesList(ts);
}
else
{
// do it as a table
- result = getTimeSeriesTable(provider, dataflow, id, filter, startTime, endTime, false, null, false).toString();
+ result = getTimeSeriesTable(provider, id, startTime, endTime, false, null, false).toString();
}
return result;
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/BBK.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/BBK.java
index 7af2a44e..c8c57b6d 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/BBK.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/BBK.java
@@ -20,8 +20,9 @@
*/
package it.bancaditalia.oss.sdmx.client.custom;
+import static it.bancaditalia.oss.sdmx.util.QueryRunner.runQuery;
+
import java.net.MalformedURLException;
-import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.logging.Level;
@@ -29,6 +30,7 @@
import it.bancaditalia.oss.sdmx.api.DataFlowStructure;
import it.bancaditalia.oss.sdmx.api.Dataflow;
import it.bancaditalia.oss.sdmx.api.Message;
+import it.bancaditalia.oss.sdmx.client.Provider;
import it.bancaditalia.oss.sdmx.client.RestSdmxClient;
import it.bancaditalia.oss.sdmx.client.SdmxClientHandler;
import it.bancaditalia.oss.sdmx.event.DataFooterMessageEvent;
@@ -37,66 +39,80 @@
import it.bancaditalia.oss.sdmx.exceptions.SdmxInvalidParameterException;
import it.bancaditalia.oss.sdmx.parser.v21.DataParsingResult;
import it.bancaditalia.oss.sdmx.parser.v21.GenericDataParser;
+import it.bancaditalia.oss.sdmx.util.QueryRunner;
/**
* @author Attilio Mattiocco
*
*/
-public class BBK extends RestSdmxClient{
- private static final String BBK_PROVIDER = "https://api.statistiken.bundesbank.de/rest";
-
- public BBK() throws URISyntaxException {
- super("Eurostat", new URI(BBK_PROVIDER), false, false, false);
+public class BBK extends RestSdmxClient
+{
+ public BBK(Provider p) throws URISyntaxException
+ {
+ super(p);
}
@Override
- protected URL buildFlowQuery(String dataflow, String agency, String version) throws SdmxException{
- try {
- return new URL(endpoint + "/metadata/dataflow/BBK" + (dataflow.equalsIgnoreCase("all") ? "" : ("/" + dataflow)));
- } catch (MalformedURLException e) {
- throw new SdmxInvalidParameterException("Invalid query parameters: dataflow: " + dataflow + ", endpoint=" + endpoint);
+ protected URL buildFlowQuery(String dataflow, String agency, String version) throws SdmxException
+ {
+ try
+ {
+ return new URL(provider.getEndpoint() + "/metadata/dataflow/BBK" + (dataflow.equalsIgnoreCase("all") ? "" : ("/" + dataflow)));
+ }
+ catch (MalformedURLException e)
+ {
+ throw new SdmxInvalidParameterException("Invalid query parameters: dataflow: " + dataflow + ", endpoint=" + provider.getEndpoint());
}
}
@Override
- protected URL buildDSDQuery(String dsd, String agency, String version, boolean full) throws SdmxException {
- try {
- return new URL(endpoint + "/metadata/datastructure/BBK" + (dsd.equalsIgnoreCase("all") ? "" : ("/" + dsd)) + "?references=children");
- } catch (MalformedURLException e) {
- throw new SdmxInvalidParameterException("Invalid query parameters: dsd: " + dsd + ", endpoint=" + endpoint);
+ protected URL buildDSDQuery(String dsd, String agency, String version, boolean full) throws SdmxException
+ {
+ try
+ {
+ return new URL(provider.getEndpoint() + "/metadata/datastructure/BBK" + (dsd.equalsIgnoreCase("all") ? "" : ("/" + dsd)) + "?references=children");
+ }
+ catch (MalformedURLException e)
+ {
+ throw new SdmxInvalidParameterException("Invalid query parameters: dsd: " + dsd + ", endpoint=" + provider.getEndpoint());
}
}
-
+
@Override
protected URL buildCodelistQuery(String codeList, String agency, String version) throws SdmxException
{
- try {
- return new URL(endpoint + "/metadata/codelist/BBK" + (codeList.equalsIgnoreCase("all") ? "" : ("/" + codeList)));
- } catch (MalformedURLException e) {
- throw new SdmxInvalidParameterException("Invalid query parameters: codelist: " + codeList + ", endpoint=" + endpoint);
+ try
+ {
+ return new URL(provider.getEndpoint() + "/metadata/codelist/BBK" + (codeList.equalsIgnoreCase("all") ? "" : ("/" + codeList)));
+ }
+ catch (MalformedURLException e)
+ {
+ throw new SdmxInvalidParameterException("Invalid query parameters: codelist: " + codeList + ", endpoint=" + provider.getEndpoint());
}
}
-
+
@Override
- protected DataParsingResult getData(Dataflow dataflow, DataFlowStructure dsd, String resource, String startTime, String endTime, boolean serieskeysonly,
- String updatedAfter, boolean includeHistory) throws SdmxException
+ protected DataParsingResult getData(Dataflow dataflow, DataFlowStructure dsd, String resource, String startTime, String endTime, boolean serieskeysonly, String updatedAfter,
+ boolean includeHistory) throws SdmxException
{
URL query = buildDataQuery(new Dataflow(dataflow.getId(), null, null, null), resource, startTime, endTime, false, null, false);
- DataParsingResult ts = runQuery(new GenericDataParser(dsd, dataflow, !serieskeysonly), query,
- "application/xml", null);
+ DataParsingResult ts = runQuery(new GenericDataParser(dsd, dataflow, !serieskeysonly), query, handleHttpHeaders("application/xml"));
Message msg = ts.getMessage();
if (msg != null)
{
LOGGER.log(Level.INFO, "The sdmx call returned messages in the footer:\n {0}", msg);
RestSdmxEvent event = new DataFooterMessageEvent(query, msg);
- dataFooterMessageEventListener.onSdmxEvent(event);
+ QueryRunner.getDataFooterMessageEventListener().onSdmxEvent(event);
}
return ts;
}
-
- public static void main(String[] args) throws SdmxException {
+
+ public static void main(String[] args) throws SdmxException
+ {
System.err.println(SdmxClientHandler.getDataFlowStructure("BBK", "BBAI3"));
- //System.err.println(SdmxClientHandler.getCodes("BBK", "BBAI3", "BBK_STD_FREQ"));
- //System.err.println(SdmxClientHandler.getTimeSeries("BBK", "BBAI3/Q............", null,null));
+ // System.err.println(SdmxClientHandler.getCodes("BBK", "BBAI3",
+ // "BBK_STD_FREQ"));
+ // System.err.println(SdmxClientHandler.getTimeSeries("BBK",
+ // "BBAI3/Q............", null,null));
}
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/DotStat.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/DotStat.java
index 82df16b9..f857c68f 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/DotStat.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/DotStat.java
@@ -20,8 +20,9 @@
*/
package it.bancaditalia.oss.sdmx.client.custom;
+import static it.bancaditalia.oss.sdmx.util.QueryRunner.runQuery;
+
import java.net.MalformedURLException;
-import java.net.URI;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
@@ -31,8 +32,10 @@
import it.bancaditalia.oss.sdmx.api.DataFlowStructure;
import it.bancaditalia.oss.sdmx.api.Dataflow;
+import it.bancaditalia.oss.sdmx.client.Provider;
import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
import it.bancaditalia.oss.sdmx.exceptions.SdmxExceptionFactory;
+import it.bancaditalia.oss.sdmx.exceptions.SdmxInvalidParameterException;
import it.bancaditalia.oss.sdmx.exceptions.SdmxXmlContentException;
import it.bancaditalia.oss.sdmx.parser.v20.DataStructureParser;
import it.bancaditalia.oss.sdmx.parser.v21.Sdmx21Queries;
@@ -43,24 +46,28 @@
* @author Attilio Mattiocco
*
*/
-public abstract class DotStat extends RestSdmx20Client {
-
+public abstract class DotStat extends RestSdmx20Client
+{
+
protected static Logger logger = Configuration.getSdmxLogger();
-
- public DotStat(String name, URI endpoint, boolean needsCredentials, String format) {
- super(name, endpoint, needsCredentials, null, format);
- }
- public DotStat(String name, URI endpoint, boolean needsCredentials) {
- super(name, endpoint, needsCredentials, null, "compact_v2");
+
+ public DotStat(Provider p, String format)
+ {
+ super(p, null, format);
}
+ public DotStat(Provider p)
+ {
+ this(p, "compact_v2");
+ }
@Override
- public Dataflow getDataflow(String dataflow, String agency, String version) throws SdmxException {
+ public Dataflow getDataflow(String dataflow, String agency, String version) throws SdmxException
+ {
// OECD (and .Stat infrastructure) does not handle flows. We simulate it
- URL query = buildFlowQuery(dataflow, ALL_AGENCIES, LATEST_VERSION );
- List dsds = runQuery(new DataStructureParser(), query, null, null);
- if(dsds.size() > 0)
+ URL query = buildFlowQuery(dataflow, ALL_KEYWORD, LATEST_VERSION);
+ List dsds = runQuery(new DataStructureParser(), query, null);
+ if (dsds.size() > 0)
{
DataFlowStructure dsd = dsds.get(0);
Dataflow result = new Dataflow(dsd, dsd.getName());
@@ -72,65 +79,66 @@ public Dataflow getDataflow(String dataflow, String agency, String version) thro
}
@Override
- public Map getDataflows() throws SdmxException {
+ public Map getDataflows() throws SdmxException
+ {
// OECD (and .Stat infrastructure) does not handle flows. We simulate it
- URL query = buildFlowQuery("ALL", ALL_AGENCIES, LATEST_VERSION );
- List dsds = runQuery(new DataStructureParser(), query, null, null);
- if(dsds.size() > 0)
+ URL query = buildFlowQuery("ALL", ALL_KEYWORD, LATEST_VERSION);
+ List dsds = runQuery(new DataStructureParser(), query, null);
+ if (dsds.size() > 0)
{
Map result = new HashMap<>();
- for (Iterator iterator = dsds.iterator(); iterator.hasNext();)
+ for (Iterator iterator = dsds.iterator(); iterator.hasNext();)
{
DataFlowStructure dsd = (DataFlowStructure) iterator.next();
Dataflow df = new Dataflow(dsd, dsd.getName());
df.setDsdIdentifier(dsd);
result.put(dsd.getId(), df);
}
-
+
return result;
}
else
throw new SdmxXmlContentException("The query returned zero dataflows");
}
-
+
@Override
- protected URL buildFlowQuery(String flow, String agency, String version) throws SdmxException{
- return(buildDSDQuery(flow, agency, version, false));
+ protected URL buildFlowQuery(String flow, String agency, String version) throws SdmxException
+ {
+ return (buildDSDQuery(flow, agency, version, false));
}
-
@Override
- protected URL buildDSDQuery(String dsd, String agency, String version, boolean full) throws SdmxException{
- if( endpoint!=null && dsd!=null && !dsd.isEmpty()){
- try {
- return new RestQueryBuilder(endpoint).addPath("GetDataStructure").addPath(dsd).build();
- } catch (MalformedURLException e) {
+ protected URL buildDSDQuery(String dsd, String agency, String version, boolean full) throws SdmxException
+ {
+ if (provider.getEndpoint() != null && dsd != null && !dsd.isEmpty())
+ {
+ try
+ {
+ return new RestQueryBuilder(provider.getEndpoint()).addPath("GetDataStructure").addPath(dsd).build();
+ }
+ catch (MalformedURLException e)
+ {
throw SdmxExceptionFactory.wrap(e);
}
}
- else{
- throw new RuntimeException("Invalid query parameters: dsd=" + dsd + " endpoint=" + endpoint);
- }
+ else
+ throw new SdmxInvalidParameterException("Invalid query parameters: dsd=" + dsd + " endpoint=" + provider.getEndpoint());
}
@Override
- protected URL buildDataQuery(Dataflow dataflow, String resource,
- String startTime, String endTime,
- boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException{
- if( endpoint!=null &&
- dataflow!=null &&
- resource!=null && !resource.isEmpty()){
-
+ protected URL buildDataQuery(Dataflow dataflow, String resource, String startTime, String endTime, boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException
+ {
+ if (provider.getEndpoint() != null && dataflow != null && resource != null && !resource.isEmpty())
+ {
+
// for OECD use the simple DF id
- Sdmx21Queries query = (Sdmx21Queries) new Sdmx21Queries(endpoint).addPath("GetData").addPath(dataflow.getId()).addPath(resource);
-
- //query=query+"?";
- //query += "&format=compact_v2";
- return query.addParams(startTime, endTime,
- serieskeysonly, updatedAfter, includeHistory, format).buildSdmx21Query();
- }
- else{
- throw new RuntimeException("Invalid query parameters: dataflow=" + dataflow + " resource=" + resource + " endpoint=" + endpoint);
+ Sdmx21Queries query = (Sdmx21Queries) new Sdmx21Queries(provider.getEndpoint()).addPath("GetData").addPath(dataflow.getId()).addPath(resource);
+
+ // query=query+"?";
+ // query += "&format=compact_v2";
+ return query.addParams(startTime, endTime, serieskeysonly, updatedAfter, includeHistory, format).buildSdmx21Query();
}
+ else
+ throw new SdmxInvalidParameterException("Invalid query parameters: dataflow=" + dataflow + " resource=" + resource + " endpoint=" + provider.getEndpoint());
}
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT.java
deleted file mode 100644
index 66162758..00000000
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Copyright 2010,2014 Bank Of Italy
-*
-* 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 it.bancaditalia.oss.sdmx.client.custom;
-
-import static java.net.HttpURLConnection.HTTP_ENTITY_TOO_LARGE;
-
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.List;
-
-import it.bancaditalia.oss.sdmx.api.DataFlowStructure;
-import it.bancaditalia.oss.sdmx.api.Dataflow;
-import it.bancaditalia.oss.sdmx.api.Message;
-import it.bancaditalia.oss.sdmx.api.PortableTimeSeries;
-import it.bancaditalia.oss.sdmx.client.Parser;
-import it.bancaditalia.oss.sdmx.client.RestSdmxClient;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxResponseException;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxXmlContentException;
-import it.bancaditalia.oss.sdmx.parser.v21.CompactDataParser;
-import it.bancaditalia.oss.sdmx.parser.v21.DataParsingResult;
-import it.bancaditalia.oss.sdmx.util.Configuration;
-
-/**
- * @author Attilio Mattiocco
- *
- */
-public class EUROSTAT extends RestSdmxClient
-{
- private static final String EUROSTAT_PROVIDER = "https://ec.europa.eu/eurostat/api/dissemination/sdmx/2.1";
- private static final String ASYNC_DELIVERY_CODE = String.valueOf(HTTP_ENTITY_TOO_LARGE);
-
- private int sleepTime = 6000;
- private int retries = Integer.parseInt(Configuration.getLateResponseRetries(10));
-
-
- public EUROSTAT() throws URISyntaxException
- {
- super("Eurostat", new URI(EUROSTAT_PROVIDER), false, false, false);
- }
-
- @Override
- public List> getTimeSeries(Dataflow dataflow, DataFlowStructure dsd, String resource, String startTime,
- String endTime, boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException
- {
- DataParsingResult ts = getData(dataflow, dsd, resource, startTime, endTime, serieskeysonly, updatedAfter, includeHistory);
- if(ts == null || ts.size() == 0)
- {
- Message msg = ts.getMessage();
-
- if(isAsyncDelivery(msg))
- {
- String url = msg.getUrl();
- Parser parser = new CompactDataParser(dsd, dataflow, !serieskeysonly);
-
- for(int i = 1; i <= retries; i++)
- {
- LOGGER.info("Trying late retrieval with URL: " + url + ". Attempt n: " + i);
- try
- {
- Thread.sleep(sleepTime);
- }
- catch (InterruptedException e1)
- {
- Thread.currentThread().interrupt();
- }
-
- try
- {
- String dumpName = "data_" + dataflow.getId() + "_" + resource; //.replaceAll("\\p{Punct}", "_");
- return postProcess(runQuery(parser, new URL(msg.getUrl()), null, dumpName));
- }
- catch (MalformedURLException | SdmxResponseException e)
- {
- LOGGER.info("Late retrieval attempt " + i + " failed with exception " + e.getClass().getSimpleName() + ": " + e.getMessage());
- }
- }
- }
- }
- else
- return postProcess(ts);
-
- throw new SdmxXmlContentException("Late retrieval failed.");
- }
-
- // http://ec.europa.eu/eurostat/en/web/sdmx-web-services/a-few-useful-points
- private static boolean isAsyncDelivery(Message msg)
- {
- return msg != null && ASYNC_DELIVERY_CODE.equals(msg.getCode()) && msg.getUrl() != null;
- }
-}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT_COMEXT.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT_COMEXT.java
deleted file mode 100644
index 4836f25b..00000000
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT_COMEXT.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright 2010,2014 Bank Of Italy
-*
-* 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 it.bancaditalia.oss.sdmx.client.custom;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-
-import it.bancaditalia.oss.sdmx.client.RestSdmxClient;
-
-/**
- * @author Attilio Mattiocco
- *
- */
-public class EUROSTAT_COMEXT extends RestSdmxClient{
- private static final String EUROSTAT_COMEXT_PROVIDER = "https://ec.europa.eu/eurostat/api/comext/dissemination/sdmx/2.1";
-
- public EUROSTAT_COMEXT() throws URISyntaxException {
- super("Eurostat", new URI(EUROSTAT_COMEXT_PROVIDER), false, false, false);
- }
-}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT_COMP.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT_COMP.java
deleted file mode 100644
index fbd7ac5b..00000000
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT_COMP.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright 2010,2014 Bank Of Italy
-*
-* 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 it.bancaditalia.oss.sdmx.client.custom;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-
-import it.bancaditalia.oss.sdmx.client.RestSdmxClient;
-
-/**
- * @author Attilio Mattiocco
- *
- */
-public class EUROSTAT_COMP extends RestSdmxClient{
- private static final String EUROSTAT_COMP_PROVIDER = "https://webgate.ec.europa.eu/comp/redisstat/api/dissemination/sdmx/2.1";
-
- public EUROSTAT_COMP() throws URISyntaxException {
- super("Eurostat", new URI(EUROSTAT_COMP_PROVIDER), false, false, false);
- }
-}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT_EMPL.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT_EMPL.java
deleted file mode 100644
index 434849cf..00000000
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT_EMPL.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright 2010,2014 Bank Of Italy
-*
-* 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 it.bancaditalia.oss.sdmx.client.custom;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-
-import it.bancaditalia.oss.sdmx.client.RestSdmxClient;
-
-/**
- * @author Attilio Mattiocco
- *
- */
-public class EUROSTAT_EMPL extends RestSdmxClient{
- private static final String EUROSTAT_EMPL_PROVIDER = "https://webgate.ec.europa.eu/empl/redisstat/api/dissemination/sdmx/2.1";
-
- public EUROSTAT_EMPL() throws URISyntaxException {
- super("Eurostat", new URI(EUROSTAT_EMPL_PROVIDER), false, false, false);
- }
-}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/IMF2.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/IMF2.java
index aeb8e459..6a5c490f 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/IMF2.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/IMF2.java
@@ -21,14 +21,15 @@
package it.bancaditalia.oss.sdmx.client.custom;
import java.net.MalformedURLException;
-import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.logging.Logger;
import it.bancaditalia.oss.sdmx.api.Dataflow;
+import it.bancaditalia.oss.sdmx.client.Provider;
import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
import it.bancaditalia.oss.sdmx.exceptions.SdmxExceptionFactory;
+import it.bancaditalia.oss.sdmx.exceptions.SdmxInvalidParameterException;
import it.bancaditalia.oss.sdmx.parser.v21.Sdmx21Queries;
import it.bancaditalia.oss.sdmx.util.Configuration;
import it.bancaditalia.oss.sdmx.util.RestQueryBuilder;
@@ -37,59 +38,72 @@
* @author Attilio Mattiocco
*
*/
-public class IMF2 extends RestSdmx20Client{
-
+public class IMF2 extends RestSdmx20Client
+{
+
protected static Logger logger = Configuration.getSdmxLogger();
-
- public IMF2() throws URISyntaxException {
- super("IMF2", new URI("http://dataservices.imf.org/REST/SDMX_XML.svc"), false, "", null);
+
+ public IMF2(Provider p) throws URISyntaxException
+ {
+ super(p, "", null);
}
-
+
@Override
- protected URL buildFlowQuery(String flow, String agency, String version) throws SdmxException{
- if( endpoint!=null){
- try {
- return new RestQueryBuilder(endpoint).addPath("Dataflow").build();
- } catch (MalformedURLException e) {
+ protected URL buildFlowQuery(String flow, String agency, String version) throws SdmxException
+ {
+ if (provider.getEndpoint() != null)
+ {
+ try
+ {
+ return new RestQueryBuilder(provider.getEndpoint()).addPath("Dataflow").build();
+ }
+ catch (MalformedURLException e)
+ {
throw SdmxExceptionFactory.wrap(e);
}
// if(flow != null && !flow.isEmpty() && !flow.equalsIgnoreCase("ALL")){
// query += "/" + flow;
// }
}
- else{
- throw new RuntimeException("Invalid query parameters: endpoint=" + endpoint);
+ else
+ {
+ throw new SdmxInvalidParameterException("Invalid query parameters: endpoint=" + provider.getEndpoint());
}
}
-
+
@Override
- protected URL buildDSDQuery(String dsd, String agency, String version, boolean full) throws SdmxException{
- if( endpoint!=null && dsd!=null && !dsd.isEmpty()){
-
- try {
- return new RestQueryBuilder(endpoint).addPath("DataStructure").addPath(dsd).build();
- } catch (MalformedURLException e) {
+ protected URL buildDSDQuery(String dsd, String agency, String version, boolean full) throws SdmxException
+ {
+ if (provider.getEndpoint() != null && dsd != null && !dsd.isEmpty())
+ {
+
+ try
+ {
+ return new RestQueryBuilder(provider.getEndpoint()).addPath("DataStructure").addPath(dsd).build();
+ }
+ catch (MalformedURLException e)
+ {
throw SdmxExceptionFactory.wrap(e);
}
}
- else{
- throw new RuntimeException("Invalid query parameters: dsd=" + dsd + " endpoint=" + endpoint);
+ else
+ {
+ throw new SdmxInvalidParameterException("Invalid query parameters: dsd=" + dsd + " endpoint=" + provider.getEndpoint());
}
}
-
+
@Override
- protected URL buildDataQuery(Dataflow dataflow, String resource,
- String startTime, String endTime,
- boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException{
- if( endpoint!=null &&
- dataflow!=null &&
- resource!=null && !resource.isEmpty()){
-
- return ((Sdmx21Queries) new Sdmx21Queries(endpoint).addPath("CompactData").addPath(dataflow.getDsdIdentifier().getId()).addPath(resource)).addParams(startTime, endTime,
- serieskeysonly, updatedAfter, includeHistory, format).buildSdmx21Query();
+ protected URL buildDataQuery(Dataflow dataflow, String resource, String startTime, String endTime, boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException
+ {
+ if (provider.getEndpoint() != null && dataflow != null && resource != null && !resource.isEmpty())
+ {
+
+ return ((Sdmx21Queries) new Sdmx21Queries(provider.getEndpoint()).addPath("CompactData").addPath(dataflow.getDsdIdentifier().getId()).addPath(resource))
+ .addParams(startTime, endTime, serieskeysonly, updatedAfter, includeHistory, format).buildSdmx21Query();
}
- else{
- throw new RuntimeException("Invalid query parameters: dataflow=" + dataflow + " resource=" + resource + " endpoint=" + endpoint);
+ else
+ {
+ throw new RuntimeException("Invalid query parameters: dataflow=" + dataflow + " resource=" + resource + " endpoint=" + provider.getEndpoint());
}
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/INEGI.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/INEGI.java
index aa92c6c4..6d8246e6 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/INEGI.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/INEGI.java
@@ -20,27 +20,51 @@
*/
package it.bancaditalia.oss.sdmx.client.custom;
-import java.net.URI;
+import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import it.bancaditalia.oss.sdmx.api.Dataflow;
+import it.bancaditalia.oss.sdmx.client.Provider;
import it.bancaditalia.oss.sdmx.client.RestSdmxClient;
import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
+import it.bancaditalia.oss.sdmx.exceptions.SdmxExceptionFactory;
+import it.bancaditalia.oss.sdmx.exceptions.SdmxInvalidParameterException;
+import it.bancaditalia.oss.sdmx.util.RestQueryBuilder;
/**
* @author Attilio Mattiocco
*
*/
-public class INEGI extends RestSdmxClient{
- public INEGI() throws URISyntaxException {
- super("INEGI", new URI("http://sdmx.snieg.mx/service/Rest"), false, false, true);
+public class INEGI extends RestSdmxClient
+{
+ public INEGI(Provider p) throws URISyntaxException
+ {
+ super(p);
}
@Override
- protected URL buildDataQuery(Dataflow dataflow, String resource, String startTime, String endTime,
- boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException {
+ protected URL buildDataQuery(Dataflow dataflow, String resource, String startTime, String endTime, boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException
+ {
// TODO Auto-generated method stub
return super.buildDataQuery(dataflow, resource + "/", startTime, endTime, serieskeysonly, updatedAfter, includeHistory);
}
+
+ @Override
+ protected URL buildDSDQuery(String dsd, String agency, String version, boolean full) throws SdmxException
+ {
+ if (provider.getEndpoint() != null && dsd != null && !dsd.isEmpty())
+ {
+ try
+ {
+ return new RestQueryBuilder(provider.getEndpoint()).addPath("DataStructure").addPath(agency).addPath(dsd).addPath(version).build();
+ }
+ catch (MalformedURLException e)
+ {
+ throw SdmxExceptionFactory.wrap(e);
+ }
+ }
+ else
+ throw new SdmxInvalidParameterException("Invalid query parameters: dsd=" + dsd + " endpoint=" + provider.getEndpoint());
+ }
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/ISTAT.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/ISTAT.java
index 69ff7122..ba0b273f 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/ISTAT.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/ISTAT.java
@@ -1,28 +1,27 @@
package it.bancaditalia.oss.sdmx.client.custom;
-import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.List;
import it.bancaditalia.oss.sdmx.api.PortableTimeSeries;
+import it.bancaditalia.oss.sdmx.client.Provider;
import it.bancaditalia.oss.sdmx.client.RestSdmxClient;
import it.bancaditalia.oss.sdmx.parser.v21.DataParsingResult;
public class ISTAT extends RestSdmxClient
{
-
- public ISTAT() throws URISyntaxException
+ public ISTAT(Provider p) throws URISyntaxException
{
- super("ISTAT", new URI("http://sdmx.istat.it/SDMXWS/rest"), false, false, false);
+ super(p);
}
@Override
protected List> postProcess(DataParsingResult result)
{
- for (PortableTimeSeries ts: result)
+ for (PortableTimeSeries ts : result)
Collections.sort(ts);
-
+
return result;
}
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/NBB.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/NBB.java
index fd1712f6..d54fda24 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/NBB.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/NBB.java
@@ -20,27 +20,28 @@
*/
package it.bancaditalia.oss.sdmx.client.custom;
-import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import it.bancaditalia.oss.sdmx.api.Dataflow;
+import it.bancaditalia.oss.sdmx.client.Provider;
import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
/**
* @author Attilio Mattiocco
*
*/
-public class NBB extends DotStat{
-
- public NBB() throws URISyntaxException {
- super("NBB", new URI("https://stat.nbb.be/RestSDMX/sdmx.ashx"), false);
+public class NBB extends DotStat
+{
+
+ public NBB(Provider p) throws URISyntaxException
+ {
+ super(p);
}
-
+
@Override
- protected URL buildDataQuery(Dataflow dataflow, String resource,
- String startTime, String endTime, boolean serieskeysonly,
- String updatedAfter, boolean includeHistory) throws SdmxException{
+ protected URL buildDataQuery(Dataflow dataflow, String resource, String startTime, String endTime, boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException
+ {
return super.buildDataQuery(dataflow, resource + "/all", startTime, endTime, serieskeysonly, null, false);
}
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/OECD.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/OECD.java
index 5b285196..228f57aa 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/OECD.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/OECD.java
@@ -20,16 +20,19 @@
*/
package it.bancaditalia.oss.sdmx.client.custom;
-import java.net.URI;
import java.net.URISyntaxException;
+import it.bancaditalia.oss.sdmx.client.Provider;
+
/**
* @author Attilio Mattiocco
*
*/
-public class OECD extends DotStat{
-
- public OECD() throws URISyntaxException {
- super("OECD", new URI("https://stats.oecd.org/restsdmx/sdmx.ashx"), false);
+public class OECD extends DotStat
+{
+
+ public OECD(Provider p) throws URISyntaxException
+ {
+ super(p);
}
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/OECD_RESTR.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/OECD_RESTR.java
index 484ddf14..b866e656 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/OECD_RESTR.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/OECD_RESTR.java
@@ -20,16 +20,18 @@
*/
package it.bancaditalia.oss.sdmx.client.custom;
-import java.net.URI;
import java.net.URISyntaxException;
+import it.bancaditalia.oss.sdmx.client.Provider;
+
/**
* @author Attilio Mattiocco
*
*/
-public class OECD_RESTR extends DotStat{
-
- public OECD_RESTR() throws URISyntaxException {
- super("OECD_RESTR", new URI("https://stats.oecd.org/restsdmx/sdmx.ashx/"), true);
+public class OECD_RESTR extends DotStat
+{
+ public OECD_RESTR(Provider p) throws URISyntaxException
+ {
+ super(p);
}
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/RestSdmx20Client.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/RestSdmx20Client.java
index 4dda097e..36dcdcd3 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/RestSdmx20Client.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/RestSdmx20Client.java
@@ -20,9 +20,9 @@
*/
package it.bancaditalia.oss.sdmx.client.custom;
-import java.net.URI;
+import static it.bancaditalia.oss.sdmx.util.QueryRunner.runQuery;
+
import java.net.URL;
-import java.security.InvalidParameterException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -32,6 +32,7 @@
import it.bancaditalia.oss.sdmx.api.DataFlowStructure;
import it.bancaditalia.oss.sdmx.api.Dataflow;
import it.bancaditalia.oss.sdmx.api.SDMXReference;
+import it.bancaditalia.oss.sdmx.client.Provider;
import it.bancaditalia.oss.sdmx.client.RestSdmxClient;
import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
import it.bancaditalia.oss.sdmx.exceptions.SdmxInvalidParameterException;
@@ -48,9 +49,9 @@ public abstract class RestSdmx20Client extends RestSdmxClient
private String acceptHdr = null;
protected String format = "compact_v2";
- public RestSdmx20Client(String name, URI endpoint, boolean needsCredentials, String acceptHdr, String format)
+ public RestSdmx20Client(Provider p, String acceptHdr, String format)
{
- super(name, endpoint, needsCredentials, false, false);
+ super(p);
this.acceptHdr = acceptHdr;
this.format = format;
}
@@ -60,7 +61,7 @@ public Map getDataflows() throws SdmxException
{
URL query = buildFlowQuery("ALL", null, null);
- List dfs = runQuery(new DataflowParser(), query, null, null);
+ List dfs = runQuery(new DataflowParser(), query, null);
if (dfs.size() > 0)
{
Map result = new HashMap<>();
@@ -79,7 +80,7 @@ public Map getDataflows() throws SdmxException
public Dataflow getDataflow(String dataflow, String agency, String version) throws SdmxException
{
URL query = buildFlowQuery(dataflow, agency, version);
- List flows = runQuery(new DataflowParser(), query, null, null);
+ List flows = runQuery(new DataflowParser(), query, null);
if (flows.size() >= 1)
for (Dataflow item : flows)
if (item.getId().equalsIgnoreCase(dataflow))
@@ -94,10 +95,10 @@ public DataFlowStructure getDataFlowStructure(SDMXReference dsd, boolean full) t
if (dsd != null)
{
URL query = buildDSDQuery(dsd.getId(), dsd.getAgency(), dsd.getVersion(), full);
- return runQuery(new DataStructureParser(), query, null, null).get(0);
+ return runQuery(new DataStructureParser(), query, null).get(0);
}
else
- throw new InvalidParameterException("Null dsd in input");
+ throw new SdmxInvalidParameterException("Null dsd in input");
}
@Override
@@ -113,23 +114,23 @@ protected DataParsingResult getData(Dataflow dataflow, DataFlowStructure dsd, St
URL query = buildDataQuery(dataflow, resource, startTime, endTime, serieskeysonly, updatedAfter, includeHistory);
// 20/09/2017: GenericDataParser deleted
return runQuery(/* format != null ? */new CompactDataParser(dsd, dataflow, !serieskeysonly)
- /* : new GenericDataParser(dsd, dataflow, !serieskeysonly) */, query, acceptHdr, null);
+ /* : new GenericDataParser(dsd, dataflow, !serieskeysonly) */, query, handleHttpHeaders(acceptHdr));
}
@Override
protected URL buildDataQuery(Dataflow dataflow, String resource, String startTime, String endTime, boolean serieskeysonly, String updatedAfter,
boolean includeHistory) throws SdmxException
{
- if (endpoint != null && dataflow != null && resource != null && !resource.isEmpty())
+ if (provider.getEndpoint() != null && dataflow != null && resource != null && !resource.isEmpty())
{
return Sdmx21Queries
- .createDataQuery(endpoint, dataflow.getFullIdentifier(), resource, startTime, endTime, serieskeysonly, updatedAfter, includeHistory, format)
+ .createDataQuery(provider.getEndpoint(), dataflow.getFullIdentifier(), resource, startTime, endTime, serieskeysonly, updatedAfter, includeHistory, format)
.buildSdmx21Query();
}
else
{
- throw new RuntimeException("Invalid query parameters: dataflow=" + dataflow + " resource=" + resource + " endpoint=" + endpoint);
+ throw new SdmxInvalidParameterException("Invalid query parameters: dataflow=" + dataflow + " resource=" + resource + " endpoint=" + provider.getEndpoint());
}
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/StatsEE.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/StatsEE.java
deleted file mode 100644
index c2d223c1..00000000
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/StatsEE.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright 2010,2014 Bank Of Italy
-*
-* 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 it.bancaditalia.oss.sdmx.client.custom;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-
-/**
- * @author Attilio Mattiocco
- *
- */
-public class StatsEE extends DotStat{
-
- public StatsEE() throws URISyntaxException {
- super("StatsEE", new URI("http://andmebaas.stat.ee/restsdmx/sdmx.ashx"), false);
- }
-}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT_GROW.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/UIS.java
similarity index 57%
rename from JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT_GROW.java
rename to JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/UIS.java
index 7b3ce16c..2ab348bc 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/EUROSTAT_GROW.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/UIS.java
@@ -20,20 +20,28 @@
*/
package it.bancaditalia.oss.sdmx.client.custom;
-import java.net.URI;
import java.net.URISyntaxException;
+import java.net.URL;
-import it.bancaditalia.oss.sdmx.client.RestSdmxClient;
+import it.bancaditalia.oss.sdmx.api.Dataflow;
+import it.bancaditalia.oss.sdmx.client.Provider;
+import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
/**
* @author Attilio Mattiocco
*
*/
-public class EUROSTAT_GROW extends RestSdmxClient{
- private static final String EUROSTAT_GROW_PROVIDER = "https://webgate.ec.europa.eu/grow/redisstat/api/dissemination/sdmx/2.1";
+public class UIS extends DotStat
+{
+ public UIS(Provider p) throws URISyntaxException
+ {
+ super(p);
+ }
- public EUROSTAT_GROW() throws URISyntaxException {
- super("Eurostat", new URI(EUROSTAT_GROW_PROVIDER), false, false, false);
+ @Override
+ protected URL buildDataQuery(Dataflow dataflow, String resource, String startTime, String endTime, boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException
+ {
+ return super.buildDataQuery(dataflow, resource + "/all", startTime, endTime, serieskeysonly, null, false);
}
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/WB.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/WB.java
index ec7e9afe..08e2ad31 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/WB.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/client/custom/WB.java
@@ -21,11 +21,11 @@
package it.bancaditalia.oss.sdmx.client.custom;
import java.net.MalformedURLException;
-import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import it.bancaditalia.oss.sdmx.api.Dataflow;
+import it.bancaditalia.oss.sdmx.client.Provider;
import it.bancaditalia.oss.sdmx.client.RestSdmxClient;
import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
import it.bancaditalia.oss.sdmx.exceptions.SdmxExceptionFactory;
@@ -35,35 +35,44 @@
* @author Attilio Mattiocco
*
*/
-public class WB extends RestSdmxClient{
- public WB() throws URISyntaxException {
- super("WB", new URI("https://api.worldbank.org/v2/sdmx/rest"), false, false, true);
+public class WB extends RestSdmxClient
+{
+ public WB(Provider p) throws URISyntaxException
+ {
+ super(p);
}
@Override
- protected URL buildDataQuery(Dataflow dataflow, String resource, String startTime, String endTime,
- boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException {
- // TODO Auto-generated method stub
+ protected URL buildDataQuery(Dataflow dataflow, String resource, String startTime, String endTime, boolean serieskeysonly, String updatedAfter, boolean includeHistory) throws SdmxException
+ {
return super.buildDataQuery(dataflow, resource + "/", startTime, endTime, serieskeysonly, updatedAfter, includeHistory);
}
-
+
@Override
- protected URL buildFlowQuery(String flow, String agency, String version) throws SdmxException{
- try {
- return Sdmx21Queries.createDataflowQuery(endpoint, flow, agency, version+"/").build();
- } catch (MalformedURLException e) {
+ protected URL buildFlowQuery(String flow, String agency, String version) throws SdmxException
+ {
+ try
+ {
+ return Sdmx21Queries.createDataflowQuery(provider.getEndpoint(), flow, agency, version + "/").build();
+ }
+ catch (MalformedURLException e)
+ {
throw SdmxExceptionFactory.wrap(e);
}
-
+
}
-
+
@Override
- protected URL buildDSDQuery(String dsd, String agency, String version, boolean full) throws SdmxException {
- try {
- return Sdmx21Queries.createStructureQuery(endpoint, dsd, agency, version+"/", true).build();
- } catch (MalformedURLException e) {
+ protected URL buildDSDQuery(String dsd, String agency, String version, boolean full) throws SdmxException
+ {
+ try
+ {
+ return Sdmx21Queries.createStructureQuery(provider.getEndpoint(), dsd, agency, version + "/", true).build();
+ }
+ catch (MalformedURLException e)
+ {
throw SdmxExceptionFactory.wrap(e);
}
}
-
+
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/CheckboxListTableModel.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/CheckboxListTableModel.java
index 0a0c0847..919b2f8a 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/CheckboxListTableModel.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/CheckboxListTableModel.java
@@ -1,5 +1,6 @@
package it.bancaditalia.oss.sdmx.helper;
+import javax.swing.table.AbstractTableModel;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
@@ -7,15 +8,13 @@
import java.util.Map.Entry;
import java.util.logging.Logger;
-import javax.swing.table.AbstractTableModel;
-
public final class CheckboxListTableModel extends AbstractTableModel
{
private static final long serialVersionUID = 1L;
@SuppressWarnings("unused")
private static final Logger LOGGER = Logger.getLogger(CheckboxListTableModel.class.getName());
- private Object items[][] = new Object[0][];
+ private Object[][] items = new Object[0][];
public void setItems(Map itemMap)
{
@@ -53,6 +52,15 @@ public Collection getCheckedCodes()
return codes;
}
+ public void updateCheckedCodes(Collection codes)
+ {
+ for (int i = 0; i < items.length; i++)
+ // 1 => key column
+ if (codes.contains(((String) items[i][1])))
+ // 0 => checkbox column
+ items[i][0] = new Boolean(true);
+ }
+
public int getCheckedCodesCount()
{
int c = 0;
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/NewProviderDialog.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/NewProviderDialog.java
index a48e7b77..2b221c92 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/NewProviderDialog.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/NewProviderDialog.java
@@ -1,7 +1,5 @@
package it.bancaditalia.oss.sdmx.helper;
-import static it.bancaditalia.oss.sdmx.client.SDMXClientFactory.SDMX_V2;
-import static it.bancaditalia.oss.sdmx.client.SDMXClientFactory.SDMX_V3;
import static java.awt.Dialog.ModalityType.APPLICATION_MODAL;
import static java.awt.GridBagConstraints.HORIZONTAL;
import static javax.swing.JOptionPane.CANCEL_OPTION;
@@ -30,6 +28,8 @@
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
+import it.bancaditalia.oss.sdmx.api.SDMXVersion;
+
public class NewProviderDialog extends JDialog {
/**
@@ -37,36 +37,11 @@ public class NewProviderDialog extends JDialog {
*/
private static final long serialVersionUID = 1L;
- private enum SdmxVersion
- {
- V2(SDMX_V2, "SDMX Version 2.x"), V3(SDMX_V3, "SDMX Version 3.x");
-
- private final String val;
- private final String desc;
-
- SdmxVersion(String val, String desc)
- {
- this.val = val;
- this.desc = desc;
- }
-
- public String getVal()
- {
- return val;
- }
-
- @Override
- public String toString()
- {
- return desc;
- }
- }
-
private int result = CANCEL_OPTION;
private String name = null;
private String description = null;
private String URL = null;
- private SdmxVersion sdmxVersion;
+ private SDMXVersion sdmxVersion;
public NewProviderDialog()
{
@@ -154,8 +129,8 @@ public NewProviderDialog()
gbc_lblVersion.gridy = 3;
contentPanel.add(lblVersion, gbc_lblVersion);
- final JComboBox cmbVersion = new JComboBox<>();
- cmbVersion.setModel(new DefaultComboBoxModel<>(SdmxVersion.values()));
+ final JComboBox cmbVersion = new JComboBox<>();
+ cmbVersion.setModel(new DefaultComboBoxModel<>(SDMXVersion.values()));
lblURL.setLabelFor(cmbVersion);
GridBagConstraints gbc_cmbVersion = new GridBagConstraints();
gbc_cmbVersion.fill = GridBagConstraints.HORIZONTAL;
@@ -190,7 +165,7 @@ public NewProviderDialog()
name = txtName.getText();
description = txtDescription.getText();
URL = txtURL.getText();
- sdmxVersion = (SdmxVersion) cmbVersion.getSelectedItem();
+ sdmxVersion = (SDMXVersion) cmbVersion.getSelectedItem();
result = JOptionPane.OK_OPTION;
dispose();
});
@@ -222,7 +197,8 @@ public String getDescription() {
public String getURL() {
return URL;
}
- public String getSdmxVersion() {
- return sdmxVersion.getVal();
+ public SDMXVersion getSdmxVersion()
+ {
+ return sdmxVersion;
}
}
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/ResultsFrame.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/ResultsFrame.java
index f6b0c0cd..72ea44d3 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/ResultsFrame.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/ResultsFrame.java
@@ -33,7 +33,7 @@ class ResultsFrame extends JFrame
private final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
- public ResultsFrame(final String provider, final List> result) throws HeadlessException
+ public ResultsFrame(final String provider, String dataflow, final List> result) throws HeadlessException
{
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setSize(800, 600);
@@ -77,11 +77,11 @@ public void mouseClicked(MouseEvent event)
{
if (SwingUtilities.isRightMouseButton(event))
{
- JPopupMenu popupMenu = createPopupMenu(provider, tsTable, row);
+ JPopupMenu popupMenu = createPopupMenu(provider, dataflow, tsTable, row);
popupMenu.show(tsTable, event.getX(), event.getY());
}
else if (column == 0 && SwingUtilities.isLeftMouseButton(event) && event.getClickCount() >= 2)
- new SeriesViewer(provider, tsTable.getValueAt(row, 0).toString()).setVisible(true);
+ new SeriesViewer(provider, tsTable.getValueAt(row, 0).toString()).setVisible(true);
}
catch (SdmxException e)
{
@@ -121,7 +121,7 @@ private boolean isSameFreqSelectedSeries(JTable tsTable, int defRow)
}
- private JPopupMenu createPopupMenu(final String provider, final JTable tsTable, int defRow)
+ private JPopupMenu createPopupMenu(final String provider, String dataflow, final JTable tsTable, int defRow)
{
final String names[] = getSelectedSeries(tsTable, defRow);
boolean sameFreq = isSameFreqSelectedSeries(tsTable, defRow);
@@ -175,7 +175,7 @@ public void run()
{
try
{
- new SeriesViewer(provider, names).setVisible(true);
+ new SeriesViewer(provider, dataflow, names).setVisible(true);
}
catch (Exception e1)
{
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/SDMXHelper.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/SDMXHelper.java
index 9e9983bc..44765a41 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/SDMXHelper.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/SDMXHelper.java
@@ -1,30 +1,30 @@
package it.bancaditalia.oss.sdmx.helper;
-import static it.bancaditalia.oss.sdmx.client.SdmxClientHandler.getCodes;
-import static it.bancaditalia.oss.sdmx.client.SdmxClientHandler.getFlow;
-import static it.bancaditalia.oss.sdmx.client.SdmxClientHandler.getTimeSeries;
-import static java.lang.Integer.MAX_VALUE;
-import static java.lang.String.format;
-import static java.lang.String.join;
-import static java.util.Collections.singletonList;
-import static java.util.Locale.forLanguageTag;
-import static java.util.ResourceBundle.getBundle;
-import static java.util.logging.Level.FINE;
-import static java.util.logging.Level.FINEST;
-import static java.util.logging.Level.INFO;
-import static java.util.logging.Level.SEVERE;
-import static java.util.logging.Level.WARNING;
-import static java.util.stream.Collectors.joining;
-import static javax.swing.JOptionPane.ERROR_MESSAGE;
-import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER;
-import static javax.swing.SortOrder.ASCENDING;
+import it.bancaditalia.oss.sdmx.api.Dataflow;
+import it.bancaditalia.oss.sdmx.api.Dimension;
+import it.bancaditalia.oss.sdmx.api.PortableTimeSeries;
+import it.bancaditalia.oss.sdmx.api.SDMXVersion;
+import it.bancaditalia.oss.sdmx.client.Provider;
+import it.bancaditalia.oss.sdmx.client.SDMXClientFactory;
+import it.bancaditalia.oss.sdmx.client.SdmxClientHandler;
+import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
+import it.bancaditalia.oss.sdmx.exceptions.SdmxResponseException;
+import it.bancaditalia.oss.sdmx.util.Configuration;
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Desktop;
-import java.awt.Font;
-import java.awt.Image;
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import javax.swing.RowSorter.SortKey;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.EtchedBorder;
+import javax.swing.border.TitledBorder;
+import javax.swing.event.*;
+import javax.swing.table.DefaultTableColumnModel;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableRowSorter;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.DefaultEditorKit;
+import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
@@ -32,77 +32,29 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.util.AbstractMap.SimpleEntry;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
-import java.util.Locale;
+import java.util.*;
import java.util.Locale.LanguageRange;
import java.util.Map.Entry;
-import java.util.ResourceBundle;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
-import javax.imageio.ImageIO;
-import javax.swing.AbstractButton;
-import javax.swing.Action;
-import javax.swing.Box;
-import javax.swing.BoxLayout;
-import javax.swing.ButtonGroup;
-import javax.swing.ButtonModel;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JRadioButton;
-import javax.swing.JRadioButtonMenuItem;
-import javax.swing.JScrollPane;
-import javax.swing.JSeparator;
-import javax.swing.JSplitPane;
-import javax.swing.JTable;
-import javax.swing.JTextField;
-import javax.swing.JTextPane;
-import javax.swing.ListSelectionModel;
-import javax.swing.RowFilter;
-import javax.swing.RowSorter;
-import javax.swing.RowSorter.SortKey;
-import javax.swing.SortOrder;
-import javax.swing.SwingConstants;
-import javax.swing.SwingUtilities;
-import javax.swing.ToolTipManager;
-import javax.swing.UIManager;
-import javax.swing.UnsupportedLookAndFeelException;
-import javax.swing.border.CompoundBorder;
-import javax.swing.border.EmptyBorder;
-import javax.swing.border.EtchedBorder;
-import javax.swing.border.TitledBorder;
-import javax.swing.event.CellEditorListener;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.table.DefaultTableColumnModel;
-import javax.swing.table.TableColumn;
-import javax.swing.table.TableRowSorter;
-import javax.swing.text.AttributeSet;
-import javax.swing.text.DefaultEditorKit;
-
-import it.bancaditalia.oss.sdmx.api.Dataflow;
-import it.bancaditalia.oss.sdmx.api.Dimension;
-import it.bancaditalia.oss.sdmx.api.PortableTimeSeries;
-import it.bancaditalia.oss.sdmx.client.Provider;
-import it.bancaditalia.oss.sdmx.client.SDMXClientFactory;
-import it.bancaditalia.oss.sdmx.client.SdmxClientHandler;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxResponseException;
-import it.bancaditalia.oss.sdmx.util.Configuration;
+import static it.bancaditalia.oss.sdmx.api.SDMXVersion.V3;
+import static it.bancaditalia.oss.sdmx.client.SdmxClientHandler.*;
+import static java.lang.Integer.MAX_VALUE;
+import static java.lang.String.format;
+import static java.lang.String.join;
+import static java.util.Collections.singletonList;
+import static java.util.Locale.forLanguageTag;
+import static java.util.ResourceBundle.getBundle;
+import static java.util.logging.Level.*;
+import static java.util.stream.Collectors.joining;
+import static javax.swing.JOptionPane.ERROR_MESSAGE;
+import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER;
+import static javax.swing.SortOrder.ASCENDING;
public class SDMXHelper extends JFrame
{
@@ -217,7 +169,104 @@ public class SDMXHelper extends JFrame
};
private String noResultsMessage;
private String resultsCountMessage;
-
+
+ /**
+ if this variable is false, the updateSeriesCounts() does nothing, it must be set to false when clearing the tlbCodes
+ to avoid uneccessary newtork call by the listener function.
+ Apparently Swing doesn't allow to disable listener call temporarily unless you save the Listener Object somewhere
+ and disable it by passing the Listener object by reference, which is incompatible to the current way we organize our table.
+ setting a global kill switch is the only way to achieve this behaviour, the listener function must be aware of this
+ variable and if set to false not execute the code.
+ so everytime we modify and/or clear tlbCodes in a V3 provider we need to disable the listener so that updateSeriesCounts()
+ does not call the webservice to update the seriesCount and the ObsCount for each code that we are clearing.
+ */
+ private boolean isCodelistSortersMapTablesListenerActive;
+
+ class SeriesCountPanel extends JPanel {
+
+ private JLabel seriesCountLabel;
+ private JTextField seriesCount;
+ private JLabel obsCountLabel;
+ private JTextField obsCount;
+
+ public SeriesCountPanel(int seriesCount, int obsCount) {
+ this.seriesCountLabel = new JLabel();
+ this.seriesCount = new JTextField(Integer.toString(seriesCount));
+ this.seriesCount.setEditable(false);
+ this.seriesCount.setMinimumSize(new java.awt.Dimension(100, 33));
+ this.obsCountLabel = new JLabel();
+ this.obsCount = new JTextField(Integer.toString(obsCount));
+ this.obsCount.setEditable(false);
+ this.obsCount.setMinimumSize(new java.awt.Dimension(100, 33));
+ add(seriesCountLabel);
+ add(this.seriesCount);
+ add(obsCountLabel);
+ add(this.obsCount);
+
+ }
+
+ public void updateCounts(int seriesCount, int obsCount) {
+ this.seriesCount.setText(Integer.toString(seriesCount));
+ this.seriesCount.setCaretPosition(0);
+ this.obsCount.setText(Integer.toString(obsCount));
+ this.obsCount.setCaretPosition(0);
+ if (seriesCount <= 0) {
+ hideSeriesCount();
+ } else {
+ showSeriesCount();
+ }
+ if (obsCount <= 0) {
+ hideObsCount();
+ } else {
+ showObsCount();
+ }
+
+ }
+
+ public void updateBundle(ResourceBundle b) {
+ this.seriesCountLabel.setText(b.getString("SDMXHelper.105"));
+ this.obsCountLabel.setText(b.getString("SDMXHelper.106"));
+ }
+
+ public void hidePanel() {
+ this.seriesCount.setVisible(false);
+ this.seriesCountLabel.setVisible(false);
+ this.obsCount.setVisible(false);
+ this.obsCountLabel.setVisible(false);
+ this.setVisible(false);
+ }
+
+ public void showPanel() {
+ this.seriesCount.setVisible(true);
+ this.seriesCountLabel.setVisible(true);
+ this.obsCount.setVisible(true);
+ this.obsCountLabel.setVisible(true);
+ this.setVisible(true);
+ }
+
+ public void hideSeriesCount() {
+ this.seriesCountLabel.setVisible(false);
+ this.seriesCount.setVisible(false);
+ }
+
+ public void showSeriesCount() {
+ this.seriesCountLabel.setVisible(true);
+ this.seriesCount.setVisible(true);
+ }
+
+ public void hideObsCount() {
+ this.obsCountLabel.setVisible(false);
+ this.obsCount.setVisible(false);
+ }
+
+ public void showObsCount() {
+ this.obsCountLabel.setVisible(true);
+ this.obsCount.setVisible(true);
+ }
+
+ }
+
+ private SeriesCountPanel seriesCountPanel;
/**
* Launch the application.
*/
@@ -261,11 +310,6 @@ public static void start(final boolean exitOnClose, String lockedProvider)
new SDMXHelper(exitOnClose, lockedProvider);
}
- public String getCurrentProvider()
- {
- return selectedProviderGroup.getSelection().getActionCommand();
- }
-
/**
* Create the frame.
*/
@@ -299,7 +343,7 @@ public SDMXHelper(boolean exitOnClose, String lockedProvider)
try
{
if (selectedProviderGroup.getSelection() != null)
- new ToolCommandsFrame(tfSdmxQuery.getText(),
+ new ToolCommandsFrame(getSelectedDataflow(), tfSdmxQuery.getText(),
selectedProviderGroup.getSelection().getActionCommand());
}
catch (SdmxException ex)
@@ -316,9 +360,9 @@ public SDMXHelper(boolean exitOnClose, String lockedProvider)
{
String name = newProviderDialog.getName();
String description = newProviderDialog.getDescription();
- String sdmxVersion = newProviderDialog.getSdmxVersion();
+ SDMXVersion sdmxVersion = newProviderDialog.getSdmxVersion();
URI endpoint = new URI(newProviderDialog.getURL());
- SDMXClientFactory.addProvider(name, endpoint, false, false, true, description, false, sdmxVersion);
+ SDMXClientFactory.addProvider(name, endpoint, false, false, true, description, sdmxVersion);
mnProviders.removeAll();
providersSetup(mnProviders);
}
@@ -493,6 +537,18 @@ else if (rdSearchDescFlow.isSelected())
tfDataflowFilter.getDocument().addDocumentListener(flowListener);
dataflowFilterPanel.add(tfDataflowFilter);
+ Box myDimensionBox = Box.createHorizontalBox();
+ myDimensionBox.setPreferredSize(new java.awt.Dimension(100, 200));
+ myDimensionBox.setMinimumSize(new java.awt.Dimension(100, 200));
+ myDimensionBox.setMaximumSize(new java.awt.Dimension(100, 200));
+
+ this.seriesCountPanel = new SeriesCountPanel(0,0);
+ seriesCountPanel.setMinimumSize(new java.awt.Dimension(100, 25));
+ seriesCountPanel.setMaximumSize(new java.awt.Dimension(MAX_VALUE, 25));
+ seriesCountPanel.setPreferredSize(new java.awt.Dimension(400, 25));
+ seriesCountPanel.hidePanel();
+
+
JSplitPane horizontalSplitPane = new JSplitPane();
horizontalSplitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
controlsPane.setRightComponent(horizontalSplitPane);
@@ -505,6 +561,7 @@ else if (rdSearchDescFlow.isSelected())
new CompoundBorder(brdDimensionsPanel, new EmptyBorder(10, 10, 10, 10))));
dimensionsPanel.setLayout(new BoxLayout(dimensionsPanel, BoxLayout.Y_AXIS));
+
Box dimensionFilterBox = Box.createHorizontalBox();
dimensionFilterBox.setPreferredSize(new java.awt.Dimension(10, 25));
dimensionFilterBox.setMinimumSize(new java.awt.Dimension(10, 25));
@@ -524,6 +581,14 @@ else if (rdSearchDescFlow.isSelected())
dimensionsScrollPane.setMinimumSize(new java.awt.Dimension(200, 23));
dimensionsPanel.add(dimensionsScrollPane);
+ Box obsCountBox = Box.createHorizontalBox();
+ dimensionFilterBox.setPreferredSize(new java.awt.Dimension(10, 25));
+ dimensionFilterBox.setMinimumSize(new java.awt.Dimension(10, 25));
+ dimensionFilterBox.setMaximumSize(new java.awt.Dimension(32768, 25));
+ obsCountBox.add(seriesCountPanel);
+ dimensionsPanel.add(obsCountBox);
+
+
JPanel codesPanel = new JPanel();
codesPanel.setSize(new java.awt.Dimension(10, 150));
horizontalSplitPane.setRightComponent(codesPanel);
@@ -719,7 +784,7 @@ public void editingCanceled(ChangeEvent e)
flowOptionsPane.setMinimumSize(new java.awt.Dimension(10, 25));
flowOptionsPane.setMaximumSize(new java.awt.Dimension(32768, 25));
dataflowsPanel.add(flowOptionsPane);
-
+
cbRegexSearchFlow.addActionListener(e -> {
cbCaseSearchFlow.setEnabled(false);
flowListener.filter();
@@ -779,8 +844,13 @@ public void editingCanceled(ChangeEvent e)
btnClearSelectedDimension.addActionListener(e -> {
if (getSelectedDataflow() != null)
{
+ isCodelistSortersMapTablesListenerActive = false;
((CheckboxListTableModel>) tblCodes.getModel()).uncheckAll();
updateCodelistCount();
+ isCodelistSortersMapTablesListenerActive = true;
+ if (V3 == SDMXClientFactory.getProviders().get(getSelectedProvider()).getSdmxVersion()) {
+ updateSeriesCounts(getSelectedDataflow(), new ArrayList<>());
+ }
}
});
btnClearSelectedDimension.setMaximumSize(new java.awt.Dimension(151, 32768));
@@ -837,6 +907,7 @@ public void mouseClicked(MouseEvent e)
JScrollPane loggingPane = new JScrollPane(noWrapPanel);
loggingPane.setBorder(new EmptyBorder(0, 0, 0, 0));
+
final JSplitPane mainSplitPane = new JSplitPane();
mainSplitPane.setBorder(null);
mainSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
@@ -929,6 +1000,7 @@ private void updateBundle(ResourceBundle b)
tblDimensions.getColumnModel().getColumn(2).setHeaderValue(b.getString("SDMXHelper.12")); //$NON-NLS-1$
noResultsMessage = b.getString("SDMXHelper.89"); //$NON-NLS-1$
resultsCountMessage = b.getString("SDMXHelper.91"); //$NON-NLS-1$
+ seriesCountPanel.updateBundle(b);
}
private void flowSelListener(ListSelectionEvent e)
@@ -958,26 +1030,35 @@ private void dimSelListener(ListSelectionEvent e)
AtomicBoolean interrupted = new AtomicBoolean(false);
new ProgressViewer<>(this, interrupted, () ->
- SDMXClientFactory.getProviders().get(provider).getSdmxVersion().equals(SDMXClientFactory.SDMX_V3) ?
+ V3 == SDMXClientFactory.getProviders().get(provider).getSdmxVersion() ?
SdmxClientHandler.filterCodes(provider, selectedDataflow, createAvailabilityFilter()).get(selectedDimension)
:
getCodes(provider, selectedDataflow, selectedDimension)
,
codes -> {
- CheckboxListTableModel model = null;
- if(!codelistSortersMap.containsKey(selectedDimension)){
- model = new CheckboxListTableModel();
- model.addTableModelListener(event -> tfSdmxQuery.setText(createQuery(selectedDataflow, dimsTableModel.getSource())));
- if (SDMXClientFactory.SDMX_V3.equals(SDMXClientFactory.getProviders().get(provider).getSdmxVersion()))
- model.addTableModelListener(event -> formatQueryButton(selectedDataflow, dimsTableModel.getSource()));
- }
- else
- model = codelistSortersMap.get(selectedDimension).getModel();
-
+ // Create new checkbox for codes given the selectedDimension
+ // the new checkbox is stored in codelistSorterMap using the String selectedDimension as key.
+ // If the checkbox is already present, the selected codes are updated and set to true
+ CheckboxListTableModel model = new CheckboxListTableModel();
+ model.addTableModelListener(event -> {
+ tfSdmxQuery.setText(createQuery(dimsTableModel.getSource()));
+ });
model.setItems(codes);
-
+ if (codelistSortersMap.get(selectedDimension) != null) {
+ Collection checkedCodes = codelistSortersMap.get(selectedDimension).getModel().getCheckedCodes();
+ model.updateCheckedCodes(checkedCodes);
+ }
TableRowSorter> sorter = new TableRowSorter<>(model);
codelistSortersMap.put(selectedDimension, sorter);
+ if (V3 == SDMXClientFactory.getProviders().get(provider).getSdmxVersion()) {
+ TableModelListener listener = new TableModelListener() {
+ @Override
+ public void tableChanged(TableModelEvent e) {
+ updateSeriesCounts(selectedDataflow, dimsTableModel.getSource());
+ }
+ };
+ model.addTableModelListener(listener);
+ }
},
ex -> {
interrupted.set(true);
@@ -987,6 +1068,8 @@ private void dimSelListener(ListSelectionEvent e)
).start();
SwingUtilities.invokeLater(() -> {
+ // Here the codelist checkbox get switched, it detects when the selectedDimension get changed
+ // and from codelistSorterMap get the previously instantiated checkbox and display it.
if (!interrupted.get())
{
TableRowSorter> sorter = codelistSortersMap.get(selectedDimension);
@@ -1018,16 +1101,20 @@ private void updateCodelistCount()
private void updateDataflow(final String dataflowID)
{
// reset clean state for tblCodes before
+ isCodelistSortersMapTablesListenerActive = false;
codelistSortersMap.clear();
((CheckboxListTableModel>) tblCodes.getModel()).clear();
+ seriesCountPanel.updateCounts(0, 0);
dimsTableModel.clear();
-
+ String formatted = (String) btnCheckQuery.getClientProperty("FORMAT"); //$NON-NLS-1$
+ btnCheckQuery.setText(String.format(formatted, "")); //$NON-NLS-1$ //$NON-NLS-2$
// if this is not a provider switch
+ isCodelistSortersMapTablesListenerActive = true;
new ProgressViewer<>(this, new AtomicBoolean(false),
() -> SdmxClientHandler.getDimensions(selectedProviderGroup.getSelection().getActionCommand(), dataflowID),
dims -> {
dimsTableModel.setItems(dims, item -> new String[] { item.getId(), item.getName() });
- tfSdmxQuery.setText(createQuery(dataflowID, dims));
+ tfSdmxQuery.setText(createQuery(dims));
},
ex -> {
LOGGER.severe("Exception. Class: " + ex.getClass().getName() + " .Message: " + ex.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
@@ -1038,9 +1125,8 @@ private void updateDataflow(final String dataflowID)
private void displayQueryResults()
{
String query = tfSdmxQuery.getText();
- ButtonModel providerMenu = selectedProviderGroup.getSelection();
String selectedDataflow = getSelectedDataflow();
- String selectedProvider = providerMenu.getActionCommand();
+ String selectedProvider = getSelectedProvider();
AtomicBoolean isCancelled = new AtomicBoolean(false);
if (selectedDataflow != null && query != null && !query.isEmpty())
@@ -1049,7 +1135,13 @@ private void displayQueryResults()
try
{
Dataflow dataflow = getFlow(selectedProvider, selectedDataflow);
- List> names = getTimeSeries(selectedProvider, null, query, null, null, null, true, null, false);
+ List> names = null;
+ if (V3 == SDMXClientFactory.getProviders().get(selectedProvider).getSdmxVersion()) {
+ names = getTimeSeries2(selectedProvider, dataflow.getId(), null, query, null, null, "none", "none", null, false);
+ }
+ else{
+ names = getTimeSeries(selectedProvider, dataflow.getId() + "/" + query, null, null, true, null, false);
+ }
return new SimpleEntry<>(dataflow, names);
}
catch (SdmxResponseException e)
@@ -1069,7 +1161,7 @@ private void displayQueryResults()
List> result = entry.getValue();
// Open a new window to browse query results
- final JFrame wnd = new ResultsFrame(getCurrentProvider(), result);
+ final JFrame wnd = new ResultsFrame(getSelectedProvider(), df.getId(), result);
wnd.setTitle(String.format(resultsCountMessage, result.size(), df.getDescription())); //$NON-NLS-1$ //$NON-NLS-2$
wnd.setVisible(true);
@@ -1087,7 +1179,7 @@ private void providersSetup(final JMenu providersMenu)
for (final Entry providerEntry : SDMXClientFactory.getProviders().entrySet())
{
final String provider = providerEntry.getKey();
- final String sdmxVersion = providerEntry.getValue().getSdmxVersion();
+ final SDMXVersion sdmxVersion = providerEntry.getValue().getSdmxVersion();
final JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(
"[" + sdmxVersion + "] " + provider + ": " + providerEntry.getValue().getDescription()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
menuItem.setActionCommand(provider);
@@ -1099,10 +1191,18 @@ private void providersSetup(final JMenu providersMenu)
updateSource(provider);
btnCheckQuery.setEnabled(false);
btnPrintQuery.setEnabled(false);
+ String formatted = (String) btnCheckQuery.getClientProperty("FORMAT"); //$NON-NLS-1$
+ btnCheckQuery.setText(String.format(formatted, "")); //$NON-NLS-1$ //$NON-NLS-2$
tfSdmxQuery.setText(""); //$NON-NLS-1$
tfDataflowFilter.setText(""); //$NON-NLS-1$
lblQuery.setText(lblQuery.getText().split(":")[0] + ": " + provider); //$NON-NLS-1$ //$NON-NLS-2$
- }
+ if (V3 == SDMXClientFactory.getProviders().get(provider).getSdmxVersion()) {
+ seriesCountPanel.showPanel();
+ } else {
+ seriesCountPanel.hidePanel();
+ }
+
+ }
catch (Exception ex)
{
ex.printStackTrace();
@@ -1125,13 +1225,17 @@ private void updateSource(final String provider)
flows -> {
if (!isCancelled.get())
{
+ isCodelistSortersMapTablesListenerActive = false;
codelistSortersMap.clear();
- tblCodes.setModel(new CheckboxListTableModel()); //$NON-NLS-1$ //$NON-NLS-2$
+ tblCodes.setRowSorter(null);
+ tblCodes.setModel(new CheckboxListTableModel());//$NON-NLS-1$ //$NON-NLS-2$
dimsTableModel.clear();
dataflowsTableModel.setItems(flows);
TableRowSorter rowSorter = new TableRowSorter<>(dataflowsTableModel);
rowSorter.setSortKeys(singletonList(new RowSorter.SortKey(0, SortOrder.ASCENDING)));
- tblDataflows.setRowSorter(rowSorter);
+ tblDataflows.setRowSorter(rowSorter);
+ seriesCountPanel.updateCounts(0, 0);
+ isCodelistSortersMapTablesListenerActive = true;
}
},
ex -> {
@@ -1140,26 +1244,38 @@ private void updateSource(final String provider)
}).start();
}
- private String createQuery(String dataflow, List dims)
- {
- return dataflow + "/" + createFilter(dims);
- }
-
- private String createFilter(List dims)
+ private String createQuery(List dims)
{
- return dims.stream()
- .map(Dimension::getId)
- .map(id -> codelistSortersMap.containsKey(id) ? join("+", codelistSortersMap.get(id).getModel().getCheckedCodes()) : "")
- .collect(joining("."));
+ String result = "";
+ try {
+ if (V3 == SDMXClientFactory.getProviders().get(getSelectedProvider()).getSdmxVersion()) {
+ result = createAvailabilityFilter();
+ }
+ else{
+ result = dims.stream()
+ .map(Dimension::getId)
+ .map(id -> codelistSortersMap.containsKey(id) ? join("+", codelistSortersMap.get(id).getModel().getCheckedCodes()) : "")
+ .collect(joining("."));
+ }
+ } catch (SdmxException ex) {
+ LOGGER.severe("Exception. Class: " + ex.getClass().getName() + " .Message: " + ex.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
+ LOGGER.log(Level.FINER, "", ex); //$NON-NLS-1$
+ }
+ return result;
}
- private void formatQueryButton(String dataflow, List dims)
+ private void updateSeriesCounts(String dataflow, List dims)
{
+ if (!isCodelistSortersMapTablesListenerActive) {
+ return;
+ }
try
{
- int count = SdmxClientHandler.getSeriesCount(selectedProviderGroup.getSelection().getActionCommand(), dataflow, createFilter(dims));
- String formatted = (String) btnCheckQuery.getClientProperty("FORMAT"); //$NON-NLS-1$
- btnCheckQuery.setText(String.format(formatted, count <= 0 ? "" : ": " + count)); //$NON-NLS-1$ //$NON-NLS-2$
+ Map countMap = SdmxClientHandler.getSeriesCount(getSelectedProvider(), dataflow, createQuery(dims));
+ int series_count = countMap.getOrDefault("series_count", 0);
+ int obs_count = countMap.getOrDefault("obs_count", 0);
+ seriesCountPanel.updateCounts(series_count, obs_count);
+
}
catch (SdmxException e)
{
@@ -1169,7 +1285,7 @@ private void formatQueryButton(String dataflow, List dims)
private String createAvailabilityFilter() throws SdmxException
{
- List dims = SdmxClientHandler.getDimensions(getCurrentProvider(), getSelectedDataflow());
+ List dims = SdmxClientHandler.getDimensions(getSelectedProvider(), getSelectedDataflow());
return dims.stream()
.map(Dimension::getId)
.filter(codelistSortersMap::containsKey)
@@ -1186,6 +1302,12 @@ private String getSelectedDataflow()
: null;
}
+ private String getSelectedProvider()
+ {
+ ButtonModel providerMenu = selectedProviderGroup.getSelection();
+ return(providerMenu.getActionCommand());
+ }
+
private String getSelectedDimension()
{
int rowSelected = tblDimensions.getSelectedRow();
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/SeriesViewer.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/SeriesViewer.java
index 695df6ab..6d8fabab 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/SeriesViewer.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/SeriesViewer.java
@@ -1,5 +1,6 @@
package it.bancaditalia.oss.sdmx.helper;
+import static it.bancaditalia.oss.sdmx.api.SDMXVersion.V3;
import static it.bancaditalia.oss.sdmx.helper.SDMXHelper.ICON_MAX;
import static it.bancaditalia.oss.sdmx.helper.SDMXHelper.ICON_MIN;
import static java.awt.Image.SCALE_SMOOTH;
@@ -42,6 +43,7 @@
import it.bancaditalia.oss.sdmx.api.BaseObservation;
import it.bancaditalia.oss.sdmx.api.PortableTimeSeries;
+import it.bancaditalia.oss.sdmx.client.SDMXClientFactory;
import it.bancaditalia.oss.sdmx.client.SdmxClientHandler;
import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
@@ -123,7 +125,7 @@ else if (value.equals(maxes.get(time)))
/**
* @wbp.parser.constructor
*/
- public SeriesViewer(String provider, String[] nameArray) throws SdmxException, IOException
+ public SeriesViewer(String provider, String dataflow, String[] nameArray) throws SdmxException, IOException
{
super("Tabulate series");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
@@ -157,7 +159,12 @@ public void stateChanged(ChangeEvent e) {
Set names = new HashSet<>(Arrays.asList(nameArray));
List> series = new ArrayList<>();
for (String name: names)
- series.addAll(SdmxClientHandler.getTimeSeries(provider, null, name, null, null, null, false, null, false));
+ if (V3 == SDMXClientFactory.getProviders().get(provider).getSdmxVersion()) {
+ series.addAll(SdmxClientHandler.getTimeSeries2(provider, dataflow, name, null, null, null, "all", "none", null, false));
+ }
+ else{
+ series.addAll(SdmxClientHandler.getTimeSeries(provider, dataflow + "/" + name, null, null, false, null, false));
+ }
if (series.size() < names.size())
throw new IllegalStateException("Couldn't download all series");
@@ -212,8 +219,8 @@ public void stateChanged(ChangeEvent e) {
public SeriesViewer(String provider, String singleSeriesName) throws SdmxException
{
super(singleSeriesName);
-
- List> list = SdmxClientHandler.getTimeSeries(provider, null, singleSeriesName, null, null, null, false, null, false);
+ List> list = null;
+ list = SdmxClientHandler.getTimeSeries(provider, singleSeriesName, null, null, false, null, false);
if (list.size() != 1)
throw new IllegalStateException("Query must return exactly one time series");
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/ToolCommandsFrame.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/ToolCommandsFrame.java
index abe21130..3735ed6f 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/ToolCommandsFrame.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/helper/ToolCommandsFrame.java
@@ -5,6 +5,7 @@
import java.awt.BorderLayout;
import java.awt.Color;
+import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
@@ -21,6 +22,7 @@
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
+import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
@@ -35,11 +37,11 @@
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
+import it.bancaditalia.oss.sdmx.api.SDMXVersion;
+import it.bancaditalia.oss.sdmx.client.SDMXClientFactory;
import it.bancaditalia.oss.sdmx.client.SdmxClientHandler;
import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
import it.bancaditalia.oss.sdmx.exceptions.SdmxInvalidParameterException;
-import java.awt.Component;
-import javax.swing.Box;
class ToolCommandsFrame extends JFrame {
/**
@@ -54,12 +56,14 @@ class ToolCommandsFrame extends JFrame {
private final JTextField urlText;
private final JLabel lblNewLabel;
- public ToolCommandsFrame(String query, String provider) throws SdmxException
+ public ToolCommandsFrame(String dataflow, String queryString, String provider) throws SdmxException
{
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setExtendedState(Frame.MAXIMIZED_HORIZ);
- if (query == null || query.isEmpty())
- throw new SdmxInvalidParameterException("The sdmx query is not valid yet: '" + query + "'");
+ if (queryString == null || queryString.isEmpty())
+ throw new SdmxInvalidParameterException("The sdmx query is not valid yet: '" + queryString + "'");
+ if (dataflow == null || dataflow.isEmpty())
+ throw new SdmxInvalidParameterException("The dataflow is not selected yet");
setResizable(false);
setSize(800, 340);
@@ -101,7 +105,10 @@ public ToolCommandsFrame(String query, String provider) throws SdmxException
gbc_rCommandLabel.gridx = 0;
panel.add(rCommandLabel, gbc_rCommandLabel);
- rCommandText = new JTextField("result <- getTimeSeries('" + provider + "', '" + query + "');");
+ if(SDMXVersion.V2 == SDMXClientFactory.getProviders().get(provider).getSdmxVersion())
+ rCommandText = new JTextField("result <- getTimeSeries(provider='" + provider + "', id='" + queryString + "');");
+ else
+ rCommandText = new JTextField("result <- getTimeSeries2(provider='" + provider + "', dataflow='" + dataflow + "', filter='" + queryString + "');");
rCommandLabel.setLabelFor(rCommandText);
GridBagConstraints gbc_rCommandText = new GridBagConstraints();
gbc_rCommandText.fill = GridBagConstraints.BOTH;
@@ -121,7 +128,10 @@ public ToolCommandsFrame(String query, String provider) throws SdmxException
gbc_matlabCommandLabel.gridy = 1;
panel.add(matlabCommandLabel, gbc_matlabCommandLabel);
- matlabCommandText = new JTextField("result = getTimeSeries('" + provider + "', '" + query + "');");
+ if(SDMXVersion.V2 == SDMXClientFactory.getProviders().get(provider).getSdmxVersion())
+ matlabCommandText = new JTextField("result = getTimeSeries('" + provider + "', '" + queryString + "');");
+ else
+ matlabCommandText = new JTextField("result = getTimeSeriesTable2('" + provider + "', '" + dataflow + "', '', '" + queryString + "');");
matlabCommandLabel.setLabelFor(matlabCommandText);
GridBagConstraints gbc_matlabCommandText = new GridBagConstraints();
gbc_matlabCommandText.fill = GridBagConstraints.BOTH;
@@ -141,7 +151,10 @@ public ToolCommandsFrame(String query, String provider) throws SdmxException
gbc_sasCommandLabel.gridy = 2;
panel.add(sasCommandLabel, gbc_sasCommandLabel);
- sasCommandText = new JTextField("%gettimeseries(provider=\"" + provider + "\", tsKey=\"" + query + "\", metadata=1);");
+ if(SDMXVersion.V2 == SDMXClientFactory.getProviders().get(provider).getSdmxVersion())
+ sasCommandText = new JTextField("%gettimeseries(provider=\"" + provider + "\", tsKey=\"" + queryString + "\", metadata=1);");
+ else
+ sasCommandText = new JTextField("NOT AVAILABLE");
sasCommandLabel.setLabelFor(sasCommandText);
GridBagConstraints gbc_sasCommandText = new GridBagConstraints();
gbc_sasCommandText.fill = GridBagConstraints.BOTH;
@@ -161,7 +174,10 @@ public ToolCommandsFrame(String query, String provider) throws SdmxException
gbc_stataCommandLabel.gridy = 3;
panel.add(stataCommandLabel, gbc_stataCommandLabel);
- stataCommandText = new JTextField("getTimeSeries " + provider + " " + query + " \"\" \"\" 0 0");
+ if(SDMXVersion.V2 == SDMXClientFactory.getProviders().get(provider).getSdmxVersion())
+ stataCommandText = new JTextField("getTimeSeries " + provider + " " + queryString + " \"\" \"\" 0 0");
+ else
+ stataCommandText = new JTextField("NOT AVAILABLE");
stataCommandLabel.setLabelFor(stataCommandText);
GridBagConstraints gbc_stataCommandText = new GridBagConstraints();
gbc_stataCommandText.insets = new Insets(0, 0, 5, 0);
@@ -181,7 +197,10 @@ public ToolCommandsFrame(String query, String provider) throws SdmxException
gbc_urlLabel.gridy = 4;
panel.add(urlLabel, gbc_urlLabel);
- urlText = new JTextField(SdmxClientHandler.getDataURL(provider, query, null, null, false, null, false));
+ if(SDMXVersion.V2 == SDMXClientFactory.getProviders().get(provider).getSdmxVersion())
+ urlText = new JTextField(SdmxClientHandler.getDataURL(provider, dataflow, queryString, null, null, false, null, false));
+ else
+ urlText = new JTextField(SdmxClientHandler.getDataURL(provider, dataflow, queryString, null, null, false, null, false));
urlLabel.setLabelFor(urlText);
GridBagConstraints gbc_urlText = new GridBagConstraints();
gbc_urlText.fill = GridBagConstraints.BOTH;
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v20/DataflowParser.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v20/DataflowParser.java
index e7ac267b..6ff7d01f 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v20/DataflowParser.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v20/DataflowParser.java
@@ -29,7 +29,6 @@
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
-import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v21/CodelistParser.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v21/CodelistParser.java
index 0c063315..0edcb22a 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v21/CodelistParser.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v21/CodelistParser.java
@@ -48,7 +48,6 @@
*/
public class CodelistParser implements Parser
{
- private static final String sourceClass = CodelistParser.class.getSimpleName();
protected static Logger logger = Configuration.getSdmxLogger();
// valid in V.2.1
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v21/DataflowParser.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v21/DataflowParser.java
index a19ad3c5..5d246c65 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v21/DataflowParser.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v21/DataflowParser.java
@@ -29,7 +29,6 @@
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
-import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
@@ -50,6 +49,7 @@ public class DataflowParser implements Parser> {
private static final String ID = "id";
private static final String AGENCY = "agencyID";
private static final String VERSION = "version";
+ private static final String EXTERNAL = "isExternalReference";
private static final String NAME = "Name";
private static final String REF = "Ref";
@@ -63,7 +63,7 @@ public List parse(XMLEventReader eventReader, List lang
while (eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent();
logger.finest(event.toString());
-
+
if (event.isStartElement()) {
StartElement startElement = event.asStartElement();
@@ -71,15 +71,21 @@ public List parse(XMLEventReader eventReader, List lang
{
currentName = new LocalizedText(languages);
String id = null, agency = null, version = null;
+ boolean isExternalReference = false;
for (Attribute attr: (Iterable) startElement::getAttributes)
switch (attr.getName().toString())
{
case ID: id = attr.getValue(); break;
case AGENCY: agency = attr.getValue(); break;
case VERSION: version = attr.getValue(); break;
+ case EXTERNAL: isExternalReference = attr.getValue().equalsIgnoreCase("true"); break;
}
-
- df = new Dataflow(id, agency, version, currentName);
+ //TODO: check what to do with these cases
+ if(isExternalReference){
+ logger.fine("Dataflow: " + agency + "," + id + "," + version + " has an externa reference");
+ continue;
+ }
+ df = new Dataflow(id, agency, version, currentName);
}
if (startElement.getName().getLocalPart() == (NAME))
currentName.setText(startElement, eventReader);
@@ -97,8 +103,9 @@ public List parse(XMLEventReader eventReader, List lang
df.setDsdIdentifier(new SDMXReference(id, agency, version));
}
}
- else if (event.isEndElement() && DATAFLOW.equals(event.asEndElement().getName().getLocalPart()))
+ else if (event.isEndElement() && DATAFLOW.equals(event.asEndElement().getName().getLocalPart())){
dfList.add(df);
+ }
}
return dfList;
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v30/AvailabilityParser.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v30/AvailabilityParser.java
index 9b80794a..ce6a91e9 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v30/AvailabilityParser.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v30/AvailabilityParser.java
@@ -99,14 +99,15 @@ else if (value.equals(startElement.getName().getLocalPart()))
{
String eventName = event.asEndElement().getName().getLocalPart();
if (keyval.equals(eventName))
- if (dimension != null)
- {
- if(codes.size() > 0){
- logger.finer("Got dimension " + dimension);
- dimensions.put(dimension, codes);
- }
- else{
- throw new SdmxInvalidParameterException("The selection identifies an empty cube region");
+ if (dimension != null) {
+ if(!dimension.equals("TIME_PERIOD")){ //TODO handle time period when available
+ if(codes.size() > 0){
+ logger.finer("Got dimension " + dimension);
+ dimensions.put(dimension, codes);
+ }
+ else{
+ throw new SdmxInvalidParameterException("The selection identifies an empty cube region");
+ }
}
}
else
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v30/Sdmx30Queries.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v30/Sdmx30Queries.java
index ae4eb027..35c1ad26 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v30/Sdmx30Queries.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v30/Sdmx30Queries.java
@@ -39,11 +39,11 @@ public Sdmx30Queries(URI entryPoint) {
super(entryPoint);
}
- public static Sdmx30Queries createDataQuery(URI endpoint, String dataflow, String tskey, String filter, String start, String end, boolean serieskeysonly,
+ public static Sdmx30Queries createDataQuery(URI endpoint, String dataflow, String tskey, String filter, String start, String end, String attributes, String measures,
String updatedAfter, boolean includeHistory) throws SdmxInvalidParameterException {
if (endpoint != null && dataflow != null && !dataflow.isEmpty()){
- Sdmx30Queries query = (Sdmx30Queries) new Sdmx30Queries(endpoint).addParams(filter, start, end, serieskeysonly, updatedAfter, includeHistory, null).addPath("data")
+ Sdmx30Queries query = (Sdmx30Queries) new Sdmx30Queries(endpoint).addParams(filter, start, end, attributes, measures, updatedAfter, includeHistory, null).addPath("data")
.addPath("dataflow").addPath(dataflow.replace(",", "/"));
if(tskey != null && !tskey.isEmpty()) query.addPath(tskey);
return query;
@@ -55,7 +55,7 @@ public static Sdmx30Queries createDataQuery(URI endpoint, String dataflow, Strin
public static Sdmx30Queries createAvailabilityQuery(URI endpoint, String dataflow, String filter,
String mode) throws SdmxInvalidParameterException {
if (endpoint != null && dataflow != null && !dataflow.isEmpty())
- return (Sdmx30Queries) new Sdmx30Queries(endpoint).addParams(filter, null, null, false, null, false, mode).addPath("availability")
+ return (Sdmx30Queries) new Sdmx30Queries(endpoint).addParams(filter, null, null, null, null, null, false, mode).addPath("availability")
.addPath("dataflow").addPath(dataflow.replace(",", "/"));
else
throw new SdmxInvalidParameterException("Invalid query parameters: dataflow=" + dataflow + " filter=" + filter + " endpoint=" + endpoint);
@@ -64,7 +64,7 @@ public static Sdmx30Queries createAvailabilityQuery(URI endpoint, String dataflo
public static Sdmx30Queries createAvailabilityQueryByKey(URI endpoint, String dataflow, String key,
String mode) throws SdmxInvalidParameterException {
if (endpoint != null && dataflow != null && !dataflow.isEmpty())
- return (Sdmx30Queries) new Sdmx30Queries(endpoint).addParams(null, null, null, false, null, false, mode).addPath("availability")
+ return (Sdmx30Queries) new Sdmx30Queries(endpoint).addParams(null, null, null, null, null, null, false, mode).addPath("availability")
.addPath("dataflow").addPath(dataflow.replace(",", "/")).addPath(key);
else
throw new SdmxInvalidParameterException("Invalid query parameters: dataflow=" + dataflow + " filter=" + key + " endpoint=" + endpoint);
@@ -77,7 +77,9 @@ public static Sdmx30Queries createStructureQuery(URI endpoint, String dsd, Strin
public static Sdmx30Queries createStructureQuery(URI endpoint, String dsd, String agency, String version, boolean full)
throws SdmxInvalidParameterException {
if (endpoint != null && agency != null && !agency.isEmpty() && dsd != null && !dsd.isEmpty()) {
- Sdmx30Queries query = (Sdmx30Queries) new Sdmx30Queries(endpoint).addPath("structure").addPath("datastructure").addPath(agency).addPath(dsd).addParam("format", "sdmx-2.1");
+ Sdmx30Queries query = (Sdmx30Queries) new Sdmx30Queries(endpoint).addPath("structure").addPath("datastructure").addPath(agency).addPath(dsd)
+ //.addParam("format", "sdmx-2.1")
+ ;
if (version != null && !version.isEmpty()) {
query.addPath(version);
}
@@ -92,7 +94,9 @@ public static Sdmx30Queries createStructureQuery(URI endpoint, String dsd, Strin
public static Sdmx30Queries createDataflowQuery(URI endpoint, String dataflow, String agency, String version) throws SdmxInvalidParameterException {
if (endpoint != null || dataflow != null)
- return ((Sdmx30Queries) new Sdmx30Queries(endpoint).addPath("structure").addPath("dataflow").addParam("format", "sdmx-2.1")).addResourceId(agency, dataflow, version);
+ return ((Sdmx30Queries) new Sdmx30Queries(endpoint).addPath("structure").addPath("dataflow")
+ //.addParam("format", "sdmx-2.1")
+ ).addResourceId(agency, dataflow, version);
else
throw new SdmxInvalidParameterException("Invalid query parameters: dataflow: " + dataflow + ", endpoint=" + endpoint);
}
@@ -118,16 +122,25 @@ public Sdmx30Queries addResourceId(String agencyId, String resourceId, String ve
return this;
}
- public Sdmx30Queries addParams(String filter, String start, String end, boolean serieskeysonly,
+ public Sdmx30Queries addParams(String filter, String start, String end, String attributes, String measures,
String updatedAfter, boolean includeHistory, String mode) {
if (filter != null && !filter.isEmpty())
addFilter(filter);
- if (start != null && !start.isEmpty())
- addParam("startPeriod", start);
- if (end != null && !end.isEmpty())
- addParam("endPeriod", end);
- if (serieskeysonly)
- addParam("detail", "serieskeysonly");
+// if (start != null && !start.isEmpty())
+// addParam("startPeriod", start);
+// if (end != null && !end.isEmpty())
+// addParam("endPeriod", end);
+ if((start != null && !start.isEmpty()) || (end != null && !end.isEmpty())){
+ String startFilter = (start != null && !start.isEmpty()) ? "ge:" + start : "";
+ String endFilter = (end != null && !end.isEmpty()) ? "le:" + end : "";
+ String sep = (!startFilter.isEmpty() && !endFilter.isEmpty()) ? "+" : "";
+ String timeFilter = startFilter + sep + endFilter;
+ addParam("c[TIME_PERIOD]=", timeFilter);
+ }
+ if (attributes != null)
+ addParam("attributes", attributes);
+ if (measures != null)
+ addParam("measures", measures);
if (includeHistory)
addParam("includeHistory", "true");
if (updatedAfter != null && !updatedAfter.isEmpty())
diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v30/SeriesCountParser.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v30/SeriesCountParser.java
index d7ead55f..88d48378 100644
--- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v30/SeriesCountParser.java
+++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/parser/v30/SeriesCountParser.java
@@ -20,44 +20,48 @@
*/
package it.bancaditalia.oss.sdmx.parser.v30;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale.LanguageRange;
-import java.util.logging.Logger;
+import it.bancaditalia.oss.sdmx.client.Parser;
+import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
+import it.bancaditalia.oss.sdmx.util.Configuration;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
-
-import it.bancaditalia.oss.sdmx.client.Parser;
-import it.bancaditalia.oss.sdmx.exceptions.SdmxException;
-import it.bancaditalia.oss.sdmx.util.Configuration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale.LanguageRange;
+import java.util.Map;
+import java.util.logging.Logger;
/**
* @author Attilio Mattiocco
*
*/
-public class SeriesCountParser implements Parser
+public class SeriesCountParser implements Parser