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.0 it.bancaditalia.oss - sdmx - 3.0.6 + SDMX + 3.1.0 SDMX Sdmx 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-8 1.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 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> { private static final String sourceClass = SeriesCountParser.class.getSimpleName(); protected static Logger logger = Configuration.getSdmxLogger(); // valid in V.3.0 static final String ANNOTATION = "Annotation"; + + static final String ANNOTATIONS = "Annotations"; static final String ID = "id"; static final String ANNOTATION_TITLE = "AnnotationTitle"; - static final String SERIES_COUNT = "series_count"; + static final String SERIES_COUNT = "series_count"; // TODO, change output to differentiate + static final String OBS_COUNT = "obs_count"; @Override - public Integer parse(XMLEventReader eventReader, List languages) + public Map parse(XMLEventReader eventReader, List languages) throws XMLStreamException, SdmxException { final String sourceMethod = "parse"; logger.entering(sourceClass, sourceMethod); - - boolean isTSNumber = false; + Map result = new HashMap<>(); + String currentKey = null; while (eventReader.hasNext()) { XMLEvent event = eventReader.nextEvent(); @@ -67,21 +71,23 @@ public Integer parse(XMLEventReader eventReader, List languages) StartElement startElement = event.asStartElement(); if (ANNOTATION.equals(startElement.getName().getLocalPart())) { + @SuppressWarnings("unchecked") Iterator attributes = startElement.getAttributes(); while (attributes.hasNext()) { Attribute attr = attributes.next(); - if (ID.equals(attr.getName().getLocalPart()) && attr.getValue().equals(SERIES_COUNT)) - isTSNumber=true; + if (ID.equals(attr.getName().getLocalPart()) && + (attr.getValue().equals(SERIES_COUNT) || attr.getValue().equals(OBS_COUNT))) + currentKey = attr.getValue(); } + } else if (ANNOTATION_TITLE.equals(startElement.getName().getLocalPart()) && currentKey != null) { + result.put(currentKey, Integer.parseInt(eventReader.getElementText())); } - else if (ANNOTATION_TITLE.equals(startElement.getName().getLocalPart()) && isTSNumber) - return Integer.parseInt(eventReader.getElementText()); - + } else if (event.isEndElement() && event.asEndElement().getName().getLocalPart().equals(ANNOTATIONS)) { + return result; } } - - return null; + return result; } } diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/Configuration.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/Configuration.java index f902557f..f4c25322 100644 --- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/Configuration.java +++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/Configuration.java @@ -20,17 +20,25 @@ */ package it.bancaditalia.oss.sdmx.util; +import static java.lang.Boolean.parseBoolean; +import static java.util.Collections.list; +import static java.util.stream.Collectors.toMap; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; +import java.io.UncheckedIOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.Authenticator; import java.net.PasswordAuthentication; import java.net.ProxySelector; -import java.nio.charset.Charset; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; @@ -38,75 +46,74 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale.LanguageRange; +import java.util.Map; import java.util.Properties; -import java.util.logging.ConsoleHandler; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.Logger; -import java.util.logging.SimpleFormatter; -import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; -import javax.security.auth.Subject; import javax.swing.JFrame; +import it.bancaditalia.oss.sdmx.api.SDMXVersion; +import it.bancaditalia.oss.sdmx.client.SDMXClientFactory; +import it.bancaditalia.oss.sdmx.exceptions.SdmxException; + /** * @author Attilio Mattiocco * */ public class Configuration { - - // TODO: will be replaced by StandardCharsets#UTF_8 in Java 7 - public static final Charset UTF_8 = Charset.forName("UTF-8"); public static final String SDMX_CODES_POLICY_ID = "code"; public static final String SDMX_CODES_POLICY_DESC = "description"; public static final String SDMX_CODES_POLICY_BOTH = "both"; public static final String SDMX_CODES_POLICY_ATTRIBUTES = "attributes"; - protected static final String PROXY_AUTH_KERBEROS = "Kerberos"; - protected static final String PROXY_AUTH_DIGEST = "digest"; protected static final String PROXY_AUTH_BASIC = "basic"; + protected static final String PROXY_AUTH_KERBEROS = "Kerberos"; protected static final String JAVA_SECURITY_KERBEROS_PROP = "java.security.krb5.conf"; protected static final String JAVA_SECURITY_AUTH_LOGIN_CONFIG_PROP = "java.security.auth.login.config"; protected static final String HTTP_AUTH_PREF_PROP = "http.auth.preference"; protected static final String SSL_DISABLE_CERT_CHECK_PROP = "ssl.disable.cert.check"; protected static final String SSL_TRUSTSTORE_PROP = "javax.net.ssl.trustStore"; - - protected static final String GLOBAL_CONFIGURATION_FILE_PROP = "SDMX_CONF"; - protected static final String EXTERNAL_PROVIDERS_PROP = "external.providers"; - protected static final String PROXY_NAME_PROP = "http.proxy.name"; - protected static final String PROXY_DEFAULT_PROP = "http.proxy.default"; - protected static final String HTTP_AUTH_USER_PROP = "http.auth.user"; - protected static final String PROXY_AUTH_PW_PROP = "http.auth.pw"; - protected static final String REVERSE_DUMP_PROP = "reverse.dump"; - protected static final String SDMX_LANG_PROP = "sdmx.lang"; - protected static final String LATE_RESP_RETRIES_PROP = "late.response.retries"; - protected static final String TABLE_DUMP_PROP = "table.dump"; - protected static final String READ_TIMEOUT_PROP = "read.timeout"; - protected static final String CONNECT_TIMEOUT_PROP = "connect.timeout"; - protected static final Logger SDMX_LOGGER = Logger.getLogger("SDMX"); - protected static List SDMX_LANG = LanguageRange.parse("en"); - + protected static final String PROVIDERS_FILE_PROP = "sdmx.providers.properties"; + protected static final String PROVIDERS_FILE = "providers.properties"; + + private static final Logger SDMX_LOGGER = Logger.getLogger("SDMX"); + + private static final String SDMX_MAX_REDIRECTS = "max.redirects"; + private static final String GLOBAL_CONFIGURATION_FILE_PROP = "SDMX_CONF"; + private static final String EXTERNAL_PROVIDERS_PROP = "external.providers"; + private static final String PROXY_NAME_PROP = "http.proxy.name"; + private static final String PROXY_DEFAULT_PROP = "http.proxy.default"; + private static final String HTTP_AUTH_USER_PROP = "http.auth.user"; + private static final String PROXY_AUTH_PW_PROP = "http.auth.pw"; + private static final String REVERSE_DUMP_PROP = "reverse.dump"; + private static final String SDMX_LANG_PROP = "sdmx.lang"; + private static final String LATE_RESP_RETRIES_PROP = "late.response.retries"; + private static final String TABLE_DUMP_PROP = "table.dump"; + private static final String READ_TIMEOUT_PROP = "read.timeout"; + private static final String CONNECT_TIMEOUT_PROP = "connect.timeout"; private static final String UIS_API_KEY_PROP = "uis.api.key"; private static final String SDMX_CODES_POLICY = "handle.sdmx.codes"; - private static final String REVERSE_DUMP_DEFAULT = "FALSE"; private static final String TABLE_DUMP_DEFAULT = "FALSE"; private static final String SDMX_DEFAULT_LANG = "en"; - private static final String SDMX_DEFAULT_TIMEOUT = "0"; private static final String DUMP_XML_PREFIX = "xml.dump.prefix"; private static final String sourceClass = Configuration.class.getSimpleName(); + private static final int SDMX_DEFAULT_TIMEOUT_CONNECT = 30000; + private static final int SDMX_DEFAULT_TIMEOUT = 0; //some queries can take a very long time to initialize private static final String CONFIGURATION_FILE_NAME = "configuration.properties"; - private static Properties props = new Properties(); + private static final Properties props = new Properties(); + private static boolean inited = false; - private static Subject subject; + protected static List SDMX_LANG = LanguageRange.parse("en"); static { @@ -133,24 +140,7 @@ protected static void setSdmxLogger() handler.setLevel(Level.INFO); SDMX_LOGGER.addHandler(handler); } - else if (handlers.size() == 1 && handlers.get(0) instanceof ConsoleHandler && handlers.get(0).getFormatter() instanceof SimpleFormatter) - { - // Replace the default consolehandler with a custom handler - current = SDMX_LOGGER; - while (current != null) - if (current.getHandlers().length == 1) - { - Handler handler = current.getHandlers()[0]; - Level level = handler.getLevel(); - current.removeHandler(handler); - handler = new SdmxLogHandler(); - handler.setLevel(level); - current.addHandler(handler); - break; - } - else - current = current.getUseParentHandlers() ? current.getParent() : null; - } + } public static Logger getSdmxLogger() @@ -158,6 +148,7 @@ public static Logger getSdmxLogger() return SDMX_LOGGER; } + @Deprecated public static Properties getConfiguration() { return props; @@ -175,27 +166,17 @@ public static boolean isTable() public static String getExternalProviders() { - return props.getProperty(Configuration.EXTERNAL_PROVIDERS_PROP); + return props.getProperty(EXTERNAL_PROVIDERS_PROP); } - public static int getReadTimeout(String provider) + public static int getReadTimeout() { - String timeout = props.getProperty(provider + "." + Configuration.READ_TIMEOUT_PROP, null); - if (timeout == null) - { - timeout = props.getProperty(Configuration.READ_TIMEOUT_PROP, Configuration.SDMX_DEFAULT_TIMEOUT); - } - return Integer.parseInt(timeout); + return getProperty(READ_TIMEOUT_PROP, SDMX_DEFAULT_TIMEOUT); } - public static int getConnectTimeout(String provider) + public static int getConnectTimeout() { - String timeout = props.getProperty(provider + "." + Configuration.CONNECT_TIMEOUT_PROP, null); - if (timeout == null) - { - timeout = props.getProperty(Configuration.CONNECT_TIMEOUT_PROP, Configuration.SDMX_DEFAULT_TIMEOUT); - } - return Integer.parseInt(timeout); + return getProperty(CONNECT_TIMEOUT_PROP, SDMX_DEFAULT_TIMEOUT_CONNECT); } public static String getCodesPolicy() @@ -237,11 +218,15 @@ private static void init() // normal configuration steps: // 1 init LOGGER + // Init internal providers // 2 search configuration in this order: system property, local, global, // Configuration class // 3 if none is found, apply defaults: no proxy and INFO Logger setSdmxLogger(); + // workaround for MATLAB 23+ + System.setProperty("javax.xml.stream.XMLInputFactory", "com.sun.xml.internal.stream.XMLInputFactoryImpl"); + String confType = null; String confFileName = System.getProperty("SDMX_CONF"); @@ -262,7 +247,6 @@ private static void init() // try local configuration. if ((confFile = new File(confFileName)).exists()) - { try { // If found apply and exit @@ -275,7 +259,6 @@ private static void init() e.printStackTrace(); SDMX_LOGGER.finer(logException(e)); } - } // try global configuration else if (globalConfEnvVar != null && !globalConfEnvVar.isEmpty() && (confFile = new File(globalConfEnvVar)).exists()) try @@ -291,7 +274,6 @@ else if (globalConfEnvVar != null && !globalConfEnvVar.isEmpty() && (confFile = } // try configuration class. else if (confType == null) - { try { Class clazz = Class.forName("it.bancaditalia.oss.sdmx.util.SdmxConfiguration"); @@ -315,9 +297,51 @@ else if (confType == null) // impossible e.printStackTrace(); } + + try + { + List resources = list(Configuration.class.getClassLoader().getResources(PROVIDERS_FILE)); + resources.add(0, Configuration.class.getResource(PROVIDERS_FILE)); + resources.add(new File(getProperty(PROVIDERS_FILE_PROP, System.getProperty("user.dir") + File.separator + PROVIDERS_FILE)).toURI().toURL()); + + for (URL resource: resources) + // Init internal providers + try (InputStream is = resource.openStream()) + { + Properties props = new Properties(); + props.load(is); + Map providers = props.entrySet().stream().collect(toMap(e -> (String) e.getKey(), e -> (String) e.getValue())); + providers.forEach((name, provider) -> { + try + { + String[] params = provider.split(","); + String providerName = getProperty("providers." + name + ".name", name); + boolean needsCredentials = getProperty("providers." + name + ".needsCredentials", parseBoolean(params[0].trim())); + boolean supportsCompression = getProperty("providers." + name + ".supportsCompression", parseBoolean(params[1].trim())); + SDMXVersion version = getProperty("providers." + name + ".sdmxversion", SDMXVersion.valueOf(params[2].trim())); + String description = getProperty("providers." + name + ".description", params[3].trim()); + URI endpoint = params.length != 5 ? null : new URI(getProperty("providers." + name + ".endpoint", params[4].trim())); + SDMXClientFactory.addProvider(providerName, endpoint, needsCredentials, false, supportsCompression, description, version); + } + catch (URISyntaxException | SdmxException e) + { + getSdmxLogger().log(Level.SEVERE, "Exception. Class: {0} .Message: {1}", new Object[] { e.getClass().getName(), e.getMessage() }); + getSdmxLogger().log(Level.FINER, "", e); + } + }); + } + catch (IOException | NullPointerException e) + { + // ignore and continue + } } - - System.setProperty("https.protocols", "TLSv1.1,TLSv1.2"); // fix for WB + catch (IOException e) + { + throw new UncheckedIOException(e); + } + + if (SDMXClientFactory.getProviders().isEmpty()) + throw new IllegalStateException("Cannot find any provider list."); } private static void init(File file) throws SecurityException, IOException @@ -336,7 +360,7 @@ private static void init(File file) throws SecurityException, IOException String tStore = props.getProperty(SSL_TRUSTSTORE_PROP); if (tStore != null && !tStore.isEmpty()) System.setProperty(SSL_TRUSTSTORE_PROP, tStore); - + setupTrustAllCerts(); // configure default language if not already set explicitly @@ -347,7 +371,7 @@ private static void init(File file) throws SecurityException, IOException private static void setupTrustAllCerts() { - if ("TRUE".equalsIgnoreCase(props.getProperty(SSL_DISABLE_CERT_CHECK_PROP))) + if (getProperty(SSL_DISABLE_CERT_CHECK_PROP, false)) { SDMX_LOGGER.fine("The SSL Certificate checks are disabled..."); TrustManager[] alwaysTrust = new TrustManager[] { new X509TrustManager() { @@ -473,26 +497,40 @@ private static void configureProxy(Properties props) String login = props.getProperty(JAVA_SECURITY_AUTH_LOGIN_CONFIG_PROP); String krbccname = System.getenv().get("KRB5CCNAME"); - if (krbccname != null && login != null && conf != null) + if (krbccname != null) { krbccname = krbccname.trim(); + System.setProperty("user.krb5cc", krbccname); + logger.finer("Environment variable KRB5CCNAME = " + krbccname); + } + else + { + logger.warning("Kerberos KRB5CCNAME not set. Rely on defaults"); + } + + if (login != null) + { login = login.trim(); + System.setProperty(JAVA_SECURITY_AUTH_LOGIN_CONFIG_PROP, login); + logger.finer(JAVA_SECURITY_AUTH_LOGIN_CONFIG_PROP + " = " + login); + } + else + { + logger.warning("Kerberos jaas file not set. Rely on defaults"); + } + + if (conf != null) + { conf = conf.trim(); - System.setProperty("user.krb5cc", krbccname); - // System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); System.setProperty(JAVA_SECURITY_KERBEROS_PROP, conf); - System.setProperty(JAVA_SECURITY_AUTH_LOGIN_CONFIG_PROP, login); logger.finer(JAVA_SECURITY_KERBEROS_PROP + " = " + conf); - logger.finer(JAVA_SECURITY_AUTH_LOGIN_CONFIG_PROP + " = " + login); - logger.finer("Environment variable KRB5CCNAME = " + krbccname); } else { - logger.warning("Kerberos ticket cache not configured because one of the parameters is not set."); + logger.warning("Kerberos configuration file not set. Rely on defaults"); logger.warning(JAVA_SECURITY_KERBEROS_PROP + " = " + conf); - logger.warning(JAVA_SECURITY_AUTH_LOGIN_CONFIG_PROP + " = " + login); - logger.warning("Environment variable KRB5CCNAME = " + krbccname); } + } else if (proxyAuth.equalsIgnoreCase(PROXY_AUTH_BASIC)) { @@ -560,6 +598,11 @@ public static String getUISApiKey() return props.getProperty(Configuration.UIS_API_KEY_PROP, null); } + public static int getMaxRedirects() + { + return getProperty(SDMX_MAX_REDIRECTS, 20); + } + private static String logException(Throwable t) { StringWriter wr = new StringWriter(); @@ -598,13 +641,29 @@ public static boolean isDumpXml() return (props.getProperty(DUMP_XML_PREFIX) != null) && (!props.getProperty(DUMP_XML_PREFIX).isEmpty()); } - public static void setSubject(Subject subject) + public static String getProperty(String name, String def) + { + return props.getProperty(name, def); + } + + protected static void setProperty(String name, String value) + { + props.setProperty(name, value); + } + + public static int getProperty(String name, int def) + { + String v = props.getProperty(name); + return v == null ? def : Integer.parseInt(v); + } + + public static boolean getProperty(String name, boolean def) { - Configuration.subject = subject; + return "true".equalsIgnoreCase(props.getProperty(name, Boolean.toString(def))); } - public static Subject getSubject() + public static SDMXVersion getProperty(String name, SDMXVersion sdmxVersion) { - return subject; + return SDMXVersion.valueOf(props.getProperty(name, sdmxVersion.toString())); } } diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/GetTimeSeries.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/GetTimeSeries.java index 9c0153a1..6e7c2340 100644 --- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/GetTimeSeries.java +++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/GetTimeSeries.java @@ -33,7 +33,6 @@ */ public class GetTimeSeries { - @SuppressWarnings("resource") public static void main(String[] args) throws IOException{ if(args.length < 2 || args.length > 6 || args.length == 5){ System.err.println("usage: GetTimeSeries [start] [end] [username password]"); @@ -66,7 +65,7 @@ public static void main(String[] args) throws IOException{ } } try { - String result = SdmxClientHandler.dumpTimeSeries(provider, null, query, null, start, end); + String result = SdmxClientHandler.dumpTimeSeries(provider, query, start, end); System.out.println(result); } catch (Exception e) { System.err.println(e.toString()); diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/QueryRunner.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/QueryRunner.java new file mode 100644 index 00000000..30f42f88 --- /dev/null +++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/QueryRunner.java @@ -0,0 +1,358 @@ +package it.bancaditalia.oss.sdmx.util; + +import static it.bancaditalia.oss.sdmx.event.RestSdmxEventListener.NO_OP_LISTENER; +import static it.bancaditalia.oss.sdmx.util.Configuration.getLanguages; +import static java.lang.System.lineSeparator; +import static java.util.stream.Collectors.joining; + +import java.io.BufferedReader; +import java.io.File; +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.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.StandardCharsets; +import java.nio.file.Paths; +import java.util.Map; +import java.util.Map.Entry; +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.xml.stream.XMLEventReader; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; + +import it.bancaditalia.oss.sdmx.client.Parser; +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.SdmxRedirectionException; + +public class QueryRunner +{ + private static final String SOURCE_CLASS = QueryRunner.class.getSimpleName(); + private static final Logger LOGGER = Configuration.getSdmxLogger(); + + private static ProxySelector proxySelector = null; + private static HostnameVerifier hostnameVerifier = null; + private static RestSdmxEventListener dataFooterMessageEventListener = NO_OP_LISTENER; + private static RestSdmxEventListener redirectionEventListener = NO_OP_LISTENER; + private static RestSdmxEventListener openEventListener = NO_OP_LISTENER; + + public static T runQuery(Parser parser, URL query, Map headers) throws SdmxException + { + return runQuery(parser, query, null, null, headers); + } + /** + * Returns a reader over the result of an http query. + * + * @param parser a non-null parser used to get the result from the xml file + * @param query a non-null url to query + * @param headers a non-null map containing headers to use in the REST call + * @return The result of the parsing + * + * @throws SdmxException + */ + public static T runQuery(Parser parser, URL query, String provider, String dumpName, Map headers) 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, headers != null ? headers.get("Accept") : "*/*", getLanguages(), proxy)); + + int redirects = 0; + do + { + conn = url.openConnection(proxy); + + if (conn instanceof HttpsURLConnection && hostnameVerifier != null) + { + LOGGER.fine("Using custom HostnameVerifier"); + ((HttpsURLConnection) conn).setHostnameVerifier(hostnameVerifier); + } + + conn.setConnectTimeout(Configuration.getConnectTimeout()); + conn.setReadTimeout(Configuration.getReadTimeout()); + + if (conn instanceof HttpURLConnection) + { + ((HttpURLConnection) conn).setRequestMethod("GET"); + ((HttpURLConnection) conn).setInstanceFollowRedirects(false); + if (headers != null) + for (Entry e: headers.entrySet()) + conn.addRequestProperty(e.getKey(), e.getValue()); + } + + code = conn instanceof HttpURLConnection ? ((HttpURLConnection) conn).getResponseCode() : HttpURLConnection.HTTP_OK; + + // note on PR #227 + // in some cases in https the proxy will not let the connect pass unless a previous call has been done in http. + // this is probably caused by the basic auth being disabled in the java env and it can be fixed + // re-allowing it (-Djdk.http.auth.tunneling.disabledSchemes=) + + 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 + { +// 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 = Paths.get(Configuration.getDumpPrefix(), provider, dumpName + ".xml").toFile(); + if (dumpfilename.getParentFile().exists() || dumpfilename.getParentFile().mkdirs()) + { + LOGGER.info("Dumping xml to file " + dumpfilename.getAbsolutePath()); + stream = new TeeInputStream(stream, dumpfilename); + } + else + LOGGER.warning("Error creating path to dump file: " + dumpfilename); + } + + 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 stream = ((HttpURLConnection) conn).getErrorStream(); + String encoding = conn.getContentEncoding() == null ? "" : conn.getContentEncoding(); + if (encoding.equalsIgnoreCase("gzip")) + stream = new GZIPInputStream(stream); + else if (encoding.equalsIgnoreCase("deflate")) + stream = new InflaterInputStream(stream); + String msg = new BufferedReader(new InputStreamReader(stream)).lines().collect(joining(lineSeparator())); + 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 | URISyntaxException e) + { + LOGGER.severe("Exception caught parsing query results: " + e.getClass().getSimpleName() + ": " + e.getMessage()); + LOGGER.log(Level.FINER, "Exception: ", e); + throw SdmxExceptionFactory.wrap(e); + } + finally + { + if (conn != null && conn instanceof HttpURLConnection) + ((HttpURLConnection) conn).disconnect(); + } + } + + 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); + } + } + + // 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); + } + } + + private static boolean isMaxRedirectionReached(int redirects) + { + return redirects > Configuration.getMaxRedirects(); + } + + /** + * 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()); + } + + // some 2.0 providers are apparently adding a BOM + private static 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; + } + + public static ProxySelector getProxySelector() + { + return proxySelector; + } + + public static void setProxySelector(ProxySelector proxySelector) + { + QueryRunner.proxySelector = proxySelector; + } + + public static HostnameVerifier getHostnameVerifier() + { + return hostnameVerifier; + } + + public static void setHostnameVerifier(HostnameVerifier hostnameVerifier) + { + QueryRunner.hostnameVerifier = hostnameVerifier; + } + + public static RestSdmxEventListener getDataFooterMessageEventListener() + { + return dataFooterMessageEventListener; + } + + public static void setDataFooterMessageEventListener(RestSdmxEventListener dataFooterMessageEventListener) + { + QueryRunner.dataFooterMessageEventListener = dataFooterMessageEventListener; + } + + public static RestSdmxEventListener getRedirectionEventListener() + { + return redirectionEventListener; + } + + public static void setRedirectionEventListener(RestSdmxEventListener redirectionEventListener) + { + QueryRunner.redirectionEventListener = redirectionEventListener; + } + + public static RestSdmxEventListener getOpenEventListener() + { + return openEventListener; + } + + public static void setOpenEventListener(RestSdmxEventListener openEventListener) + { + QueryRunner.openEventListener = openEventListener; + } +} diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/SdmxLogHandler.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/SdmxLogHandler.java index 286d33df..90d03ea1 100644 --- a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/SdmxLogHandler.java +++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/SdmxLogHandler.java @@ -51,6 +51,7 @@ public String format(LogRecord record) return String.format(LOG_FORMAT, new Date(record.getMillis()), record.getLevel().getName(), source, message, throwable); } } + public SdmxLogHandler() { super(); diff --git a/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/TeeInputStream.java b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/TeeInputStream.java new file mode 100644 index 00000000..cf70b112 --- /dev/null +++ b/JAVA/src/main/java/it/bancaditalia/oss/sdmx/util/TeeInputStream.java @@ -0,0 +1,37 @@ +package it.bancaditalia.oss.sdmx.util; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public class TeeInputStream extends InputStream +{ + private final InputStream source; + private final OutputStream teed; + + public TeeInputStream(InputStream source, File tee) throws FileNotFoundException + { + this.source = source; + this.teed = new FileOutputStream(tee); + } + + @Override + public void close() throws IOException + { + source.close(); + } + + @Override + public int read() throws IOException + { + int c = source.read(); + if (c >= 0) + teed.write(c); + if (c == '\n') + teed.flush(); + return c; + } +} diff --git a/JAVA/src/main/resources/it/bancaditalia/oss/sdmx/helper/Thumbs.db b/JAVA/src/main/resources/it/bancaditalia/oss/sdmx/helper/Thumbs.db deleted file mode 100644 index 9af35f13..00000000 Binary files a/JAVA/src/main/resources/it/bancaditalia/oss/sdmx/helper/Thumbs.db and /dev/null differ diff --git a/JAVA/src/main/resources/it/bancaditalia/oss/sdmx/helper/bundles/HelperResources.properties b/JAVA/src/main/resources/it/bancaditalia/oss/sdmx/helper/bundles/HelperResources.properties index 6695653d..fa16ee87 100644 --- a/JAVA/src/main/resources/it/bancaditalia/oss/sdmx/helper/bundles/HelperResources.properties +++ b/JAVA/src/main/resources/it/bancaditalia/oss/sdmx/helper/bundles/HelperResources.properties @@ -59,3 +59,5 @@ SDMXHelper.90=SDMX Helper SDMXHelper.91=%d results - %s SDMXHelper.103=Code ID SDMXHelper.104=Code Description +SDMXHelper.105=Series Count: +SDMXHelper.106=Observation Count: diff --git a/JAVA/src/site/markdown b/JAVA/src/site/markdown deleted file mode 160000 index 682f5f90..00000000 --- a/JAVA/src/site/markdown +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 682f5f90b2484ab88d948cdbaebed821849c6e6c diff --git a/JAVA/src/site/site.xml b/JAVA/src/site/site.xml deleted file mode 100644 index 72e8d8e8..00000000 --- a/JAVA/src/site/site.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - -

- - - - - - - - - - - - - - - - - diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/ABSClientTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/ABSClientTest.java deleted file mode 100644 index 2133821c..00000000 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/ABSClientTest.java +++ /dev/null @@ -1,39 +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; - -import it.bancaditalia.oss.sdmx.client.SdmxClientHandler; -import it.bancaditalia.oss.sdmx.exceptions.SdmxException; - - - -public class ABSClientTest { - public static void main(String[] args) throws SdmxException{ -// System.err.println(SdmxClientHandler.getFlows("ABS", null)); -// System.err.println(SdmxClientHandler.getDSDIdentifier("ABS", "ABS_NRP9_ASGS")); -// System.err.println(SdmxClientHandler.getDimensions("ABS", "ABS_NRP9_ASGS")); -// System.err.println(SdmxClientHandler.getDataFlowStructure("ABS", "ABS_NRP9_ASGS")); -// System.err.println(SdmxClientHandler.getCodes("ABS", "ABS_NRP9_ASGS", "FREQUENCY")); - System.err.println(SdmxClientHandler.getTimeSeries("ABS", "ATSI_BIRTHS_SUMM/1+4...A", "2000", "2010")); - - - } -} diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/BBKClientTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/BBKClientTest.java deleted file mode 100644 index a080a700..00000000 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/BBKClientTest.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; - -import it.bancaditalia.oss.sdmx.exceptions.SdmxException; - - - -public class BBKClientTest { - public static void main(String[] args) throws SdmxException{ -// System.err.println(SdmxClientHandler.getFlows("BBK", null)); - System.err.println(SdmxClientHandler.getFlow("BBK", "BBASV")); -// System.err.println(SdmxClientHandler.getDSDIdentifier("BBK", "BBASV")); -// System.err.println(SdmxClientHandler.getDimensions("BBK", "BBASV")); -// System.err.println(SdmxClientHandler.getDataFlowStructure("BBK", "BBASV")); -// System.err.println(SdmxClientHandler.getCodes("BBK", "BBASV", "BBK_ACS2_REF_AREA")); -// System.err.println(SdmxClientHandler.getTimeSeries("UIS", "DEM_ECO.DEC.LCU_USD._Z._Z.AF", null, null)); - - } -} diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/ECBClientTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/ECBClientTest.java index f26a419a..12dae094 100644 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/ECBClientTest.java +++ b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/ECBClientTest.java @@ -20,20 +20,18 @@ */ package it.bancaditalia.oss.sdmx.client; -import java.util.Map; - -import it.bancaditalia.oss.sdmx.client.SdmxClientHandler; +import it.bancaditalia.oss.sdmx.exceptions.DataStructureException; import it.bancaditalia.oss.sdmx.exceptions.SdmxException; public class ECBClientTest { - public static void main(String[] args) throws SdmxException{ + public static void main(String[] args) throws SdmxException, DataStructureException{ // System.err.println(SdmxClientHandler.getFlows("ECB", "Exchange*")); // // System.err.println(SdmxClientHandler.getDSDIdentifier("ECB", "MOBILE_EXR")); // -// System.err.println(SdmxClientHandler.getDataFlowStructure("ECB", "EXR")); +// System.out.println(SdmxClientHandler.getDataFlowStructure("ECB", "EXR")); // System.err.println(SdmxClientHandler.getDimensions("ECB", "EXR")); // System.err.println(SdmxClientHandler.getTimeSeries("ECB", "EXR.Q|M|W.USD.EUR.SP00.A", null, null)); // System.err.println(SdmxClientHandler.getTimeSeriesRevisions("ECB", "EXR.M.USD.EUR.SP00.A", null, null, "2015-01-01", true)); @@ -41,6 +39,7 @@ public static void main(String[] args) throws SdmxException{ // System.err.println(SdmxClientHandler.getFlows("ECB", "ICPF")); // System.err.println(SdmxClientHandler.getDimensions("ECB", "ICPF")); // System.err.println(SdmxClientHandler.getCodes("ECB", "ICPF", "FREQ")); -// SdmxClientHandler.getTimeSeries("ECB", "EXR.M.USD.EUR.SP00.A", null, null); + System.err.println(SdmxClientHandler.getTimeSeriesTable("ECB", "EXR.M.USD.EUR.SP00.A", null, null, false, null, false)); +// SdmxClientHandler.getTimeSeries2("DEMO_SDMXV3", "EXR", "A..EUR.SP00.A", "c[FREQ]=A&c[CURRENCY]=USD&c[CURRENCY_DENOMINATOR]=EUR&c[EXR_TYPE]=SP00&c[EXR_SUFFIX]=A", null, null, "none", "none", null, false); } } diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/EstatClientTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/EstatClientTest.java deleted file mode 100644 index fcb15680..00000000 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/EstatClientTest.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; - -import it.bancaditalia.oss.sdmx.client.SdmxClientHandler; -import it.bancaditalia.oss.sdmx.exceptions.SdmxException; - - - -public class EstatClientTest { - public static void main(String[] args) throws SdmxException{ - //System.err.println(SdmxClientHandler.getCodes("EUROSTAT", "aact_ali01", "FREQ")); -// System.err.println(SdmxClientHandler.getDataFlowStructure("EUROSTAT", "DS-008573")); - // System.err.println(SdmxClientHandler.getTimeSeries("EUROSTAT","prc_hicp_midx/..CP00.EU", null, null)); -// System.err.println(SdmxClientHandler.getDimensions("EUROSTAT", "DS-016890")); - System.err.println(SdmxClientHandler.getTimeSeries("EUROSTAT","DS-016890/.DE.FR.87019039.2.VALUE_IN_EUROS.", null, null)); -// System.err.println(SdmxClientHandler.getFlows("EUROSTAT", null)); - - } -} diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/FileTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/FileTest.java deleted file mode 100644 index e63ebee0..00000000 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/FileTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package it.bancaditalia.oss.sdmx.client; - -import java.io.File; - -import it.bancaditalia.oss.sdmx.exceptions.SdmxException; -import it.bancaditalia.oss.sdmx.util.Configuration; - -public class FileTest { - public static void main(String[] args) throws SdmxException { - String directory = "FileProviderTestFiles"; - File f = new File(directory); - f.mkdir(); - Configuration.setDumpPrefix(directory); - SdmxClientHandler.getTimeSeries("ECB", "EXR.M.USD.EUR.SP00.A", null, null); - - SdmxClientHandler.addLocalProvider("TEST", "FileProviderTestFiles", "my test"); - System.err.println(SdmxClientHandler.getDimensions("TEST", "EXR")); - System.err.println(SdmxClientHandler.getDataFlowStructure("TEST", "EXR")); - System.err.println(SdmxClientHandler.getTimeSeries("TEST", "EXR.M.USD.EUR.SP00.A", null, null)); - } -} diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/ILOClientTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/ILOClientTest.java deleted file mode 100644 index 9c302d52..00000000 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/ILOClientTest.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; - -import it.bancaditalia.oss.sdmx.client.SdmxClientHandler; -import it.bancaditalia.oss.sdmx.exceptions.SdmxException; - - - -public class ILOClientTest { - public static void main(String[] args) throws SdmxException{ -// System.err.println(SdmxClientHandler.getFlows("ILO", null)); -// System.err.println(SdmxClientHandler.getDSDIdentifier("ILO", "DF_YI_ALL_EMP_TEMP_SEX_AGE_NB")); -// System.err.println(SdmxClientHandler.getDataFlowStructure("ILO", "DF_YI_ALL_EMP_TEMP_SEX_AGE_NB")); -// System.err.println(SdmxClientHandler.getDimensions("ILO", "DF_YI_ALL_EMP_TEMP_SEX_AGE_NB")); -// System.err.println(SdmxClientHandler.getCodes("ILO", "DF_YI_ALL_EMP_TEMP_SEX_AGE_NB", "COUNTRY")); - System.err.println(SdmxClientHandler.getTimeSeries("ILO", "DF_YI_ALL_EMP_TEMP_SEX_AGE_NB/YI.MEX.A....", null, null)); -// System.err.println(SdmxClientHandler.getDimensions("ILO", "DF_YI_ALL_EMP_TEMP_SEX_AGE_NB")); - } -} diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/IMFClientTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/IMFClientTest.java deleted file mode 100644 index 139564b6..00000000 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/IMFClientTest.java +++ /dev/null @@ -1,37 +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; - -import it.bancaditalia.oss.sdmx.client.SdmxClientHandler; -import it.bancaditalia.oss.sdmx.exceptions.SdmxException; - - - -public class IMFClientTest { - public static void main(String[] args) throws SdmxException{ - System.err.println(SdmxClientHandler.getDSDIdentifier("IMF", "PGI")); - System.err.println(SdmxClientHandler.getDimensions("IMF", "PGI")); - System.err.println(SdmxClientHandler.getDataFlowStructure("IMF", "PGI")); - System.err.println(SdmxClientHandler.getCodes("IMF", "PGI", "REF_AREA")); - System.err.println(SdmxClientHandler.getTimeSeries("IMF", "PGI.US....", "1980", "2010")); - - } -} diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/INSEEClientTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/INSEEClientTest.java deleted file mode 100644 index aeabe3c5..00000000 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/INSEEClientTest.java +++ /dev/null @@ -1,32 +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; - -import it.bancaditalia.oss.sdmx.exceptions.SdmxException; - - - -public class INSEEClientTest { - public static void main(String[] args) throws SdmxException{ - //System.err.println(SdmxClientHandler.getTimeSeries("INSEE", "BALANCE-PAIEMENTS/M.BALANCE_DES_PAIEMENTS.CREDITS.205.VALEUR_ABSOLUE.FE.EUROS.BRUT.SO", null, null)); - System.err.println(SdmxClientHandler.getFlow("INSEE", "BALANCE-PAIEMENTS")); - } -} diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/InegiClientTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/InegiClientTest.java deleted file mode 100644 index 9b4d0839..00000000 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/InegiClientTest.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; - -import it.bancaditalia.oss.sdmx.client.SdmxClientHandler; -import it.bancaditalia.oss.sdmx.exceptions.SdmxException; - - - -public class InegiClientTest { - public static void main(String[] args) throws SdmxException{ -// System.err.println(SdmxClientHandler.getFlows("INEGI", null)); -// System.err.println(SdmxClientHandler.getDSDIdentifier("INEGI", "DF_STEI")); -// System.err.println(SdmxClientHandler.getDimensions("INEGI", "DF_STEI")); - System.err.println(SdmxClientHandler.getDataFlowStructure("INEGI", "DF_STEI")); -// System.err.println(SdmxClientHandler.getCodes("INEGI", "DF_STEI", "FREQ")); - System.err.println(SdmxClientHandler.getTimeSeries("INEGI", "DF_STEI/..C1161+C1162+C5004.....", "1980", "2010")); - - } -} diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/IstatClientTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/IstatClientTest.java deleted file mode 100644 index 3cab6cc4..00000000 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/IstatClientTest.java +++ /dev/null @@ -1,37 +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; - -import it.bancaditalia.oss.sdmx.client.SdmxClientHandler; -import it.bancaditalia.oss.sdmx.exceptions.SdmxException; - - - -public class IstatClientTest { - public static void main(String[] args) throws SdmxException{ -// System.err.println(SdmxClientHandler.getFlows("ISTAT", null)); -// System.err.println(SdmxClientHandler.getDSDIdentifier("ISTAT", "144_125")); -// System.err.println(SdmxClientHandler.getDataFlowStructure("ISTAT", "144_125")); -// System.err.println(SdmxClientHandler.getDimensions("ISTAT", "144_125")); - System.err.println(SdmxClientHandler.getTimeSeries("ISTAT", "169_745/M.00ST.IT.4.55", null, null)); - - } -} diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/NBBClientTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/NBBClientTest.java deleted file mode 100644 index 39ef86c7..00000000 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/NBBClientTest.java +++ /dev/null @@ -1,33 +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; - -import it.bancaditalia.oss.sdmx.exceptions.SdmxException; - - - -public class NBBClientTest { - public static void main(String[] args) throws SdmxException{ - SdmxClientHandler.setPreferredLanguage("fr"); - System.err.println(SdmxClientHandler.getFlows("NBB", null)); - - } -} diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/OecdClientTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/OecdClientTest.java deleted file mode 100644 index 3e242c60..00000000 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/OecdClientTest.java +++ /dev/null @@ -1,39 +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; - -import it.bancaditalia.oss.sdmx.exceptions.SdmxException; - - - -public class OecdClientTest { - public static void main(String[] args) throws SdmxException{ -// System.err.println(SdmxClientHandler.getFlows("OECD", null)); -// System.err.println(SdmxClientHandler.getDSDIdentifier("OECD", "QNA")); -// System.err.println(SdmxClientHandler.getDimensions("OECD", "QNA")); - System.err.println(SdmxClientHandler.getDataFlowStructure("OECD", "QNA")); -// System.err.println(SdmxClientHandler.getTimeSeries("OECD", "QNA.ITA.B1_GE.CARSA.Q", "2000", "2010")); - //System.err.println(SdmxClientHandler.getTimeSeries("OECD", "KEI.*.*.*.*", "2000", "2010")); - System.err.println(SdmxClientHandler.getTimeSeries("OECD", "G20_PRICES.CAN.CPALTT01.IXOB.M", "2000", "2010")); - -// System.err.println(SdmxClientHandler.getCodes("OECD", "QNA", "SUBJECT")); - } -} diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/SASHandlerTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/SASHandlerTest.java index cefa0cbe..accb6ad4 100644 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/SASHandlerTest.java +++ b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/SASHandlerTest.java @@ -21,7 +21,6 @@ package it.bancaditalia.oss.sdmx.client; -import it.bancaditalia.oss.sdmx.client.SASClientHandler; import it.bancaditalia.oss.sdmx.exceptions.SdmxException; public class SASHandlerTest { diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/UNDATAClientTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/UNDATAClientTest.java deleted file mode 100644 index 8f948b84..00000000 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/UNDATAClientTest.java +++ /dev/null @@ -1,39 +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; - -import it.bancaditalia.oss.sdmx.client.SdmxClientHandler; -import it.bancaditalia.oss.sdmx.exceptions.SdmxException; - - - -public class UNDATAClientTest { - public static void main(String[] args) throws SdmxException{ - System.err.println(SdmxClientHandler.getFlows("UNDATA", null)); - System.err.println(SdmxClientHandler.getFlow("UNDATA", "DF_UNDATA_COUNTRYDATA")); - System.err.println(SdmxClientHandler.getDSDIdentifier("UNDATA", "DF_UNData_UNFCC")); - System.err.println(SdmxClientHandler.getDimensions("UNDATA", "DF_UNData_UNFCC")); - System.err.println(SdmxClientHandler.getDataFlowStructure("UNDATA", "DF_UNData_UNFCC")); - System.err.println(SdmxClientHandler.getCodes("UNDATA", "DF_UNDATA_COUNTRYDATA", "LOCATION")); - System.err.println(SdmxClientHandler.getTimeSeries("UNDATA", "DF_UNDATA_COUNTRYDATA/...U....", "2010", "2015")); - - } -} diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/WBClientTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/WBClientTest.java deleted file mode 100644 index b3eae66d..00000000 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/WBClientTest.java +++ /dev/null @@ -1,39 +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; - -import it.bancaditalia.oss.sdmx.client.SdmxClientHandler; -import it.bancaditalia.oss.sdmx.exceptions.SdmxException; - - - -public class WBClientTest { - public static void main(String[] args) throws SdmxException{ -// System.err.println(SdmxClientHandler.getFlows("WB", null)); -// System.err.println(SdmxClientHandler.getFlow("WB", "WDI")); -// System.err.println(SdmxClientHandler.getDSDIdentifier("WB", "WDI")); -// System.err.println(SdmxClientHandler.getDimensions("WB", "WDI")); -// System.err.println(SdmxClientHandler.getDataFlowStructure("WB", "WDI")); -// System.err.println(SdmxClientHandler.getCodes("WB", "WDI", "REF_AREA")); - System.err.println(SdmxClientHandler.getTimeSeries("WB", "WDI.usa.sp_pop_totl", "2003", "2005")); - - } -} diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/WITSClientTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/WITSClientTest.java deleted file mode 100644 index 5c058e7b..00000000 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/client/WITSClientTest.java +++ /dev/null @@ -1,37 +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; - -import it.bancaditalia.oss.sdmx.client.SdmxClientHandler; -import it.bancaditalia.oss.sdmx.exceptions.SdmxException; - - - -public class WITSClientTest { - public static void main(String[] args) throws SdmxException{ -// System.err.println(SdmxClientHandler.getFlows("WITS", null)); -// System.err.println(SdmxClientHandler.getDimensions("WITS", "DF_WITS_Tariff_TRAINS")); - System.err.println(SdmxClientHandler.getDSDIdentifier("WITS", "DF_WITS_Tariff_TRAINS")); - System.err.println(SdmxClientHandler.getDataFlowStructure("WITS", "DF_WITS_Tariff_TRAINS")); -// System.err.println(SdmxClientHandler.getTimeSeries("WITS", "EXR.Q|M|W.USD.EUR.SP00.A", null, null)); - - } -} diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/CodesIT.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/CodesIT.java index 3e815a29..fee559a3 100644 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/CodesIT.java +++ b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/CodesIT.java @@ -28,15 +28,18 @@ public static Collection data() { "ABS", "ATSI_BIRTHS_SUMM", 0, new String[][] { { "19", "Births where only mother Aboriginal or Torres Strait Islander" } } }, { "ECB", "EXR", 0, new String[][] { { "D", "Daily" } } }, + { "DEMO_SDMXV3", "EXR", 0, new String[][] { { "D", "Daily" } } }, { "WITS", "DF_WITS_Tariff_TRAINS", 0, new String[][] {} }, { "UNDATA", "DF_UNDATA_COUNTRYDATA", 0, new String[][] { { "3A", "Three-year average" } } }, - { "ISTAT", "144_125", 0, new String[][] { { "D", "giornaliero" } } }, - { "ISTAT_RI", "163_24", 0, new String[][] { { "D", "giornaliero" } } }, + { "ISTAT", "144_125", 0, new String[][] { { "D", "daily" } } }, + { "ISTAT_RI", "163_24", 0, new String[][] { { "D", "daily" } } }, { "INSEE", "CNA-2010-CONSO-SI", 0, new String[][] { { "T", "Quarterly" } } }, { "ILO", "DF_EMP_TEMP_SEX_AGE_NB", 0, new String[][] { { "ABW", "Aruba" } } }, { "EUROSTAT", "prc_hicp_midx", 0, new String[][] { { "D", "Daily" } } }, { "IMF2", "DS-WHDREO", 0, new String[][] { { "D", "Daily" } } }, { "OECD", "QNA", 0, new String[][] { { "G-7", "G7" } } }, + { "OECD_NEW", "DSD_NAMAIN1@DF_QNA_EXPENDITURE_CAPITA", 0, new String[][] { { "Q", "Quarterly" } } }, + { "OECD_SDMXV3", "DSD_NAMAIN1@DF_QNA_EXPENDITURE_CAPITA", 0, new String[][] { { "Q", "Quarterly" } } }, { "BBK", "BBASV", 0, new String[][] { { "A", "Annual" } } }, { "WB", "WDI", 1, new String[][] { { "SM_POP_NETM", "Net migration" } } } }; diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/DataflowsIT.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/DataflowsIT.java index 570c59d0..e103e91f 100644 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/DataflowsIT.java +++ b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/DataflowsIT.java @@ -26,6 +26,7 @@ public static Collection data() { { { "ABS", null, "ATSI_BIRTHS_SUMM", "Aboriginal and Torres Strait Islander births and confinements, summary, by state" }, { "ECB", "*Exchange*", "EXR", "Exchange Rates" }, + { "DEMO_SDMXV3", "*Exchange*", "EXR", "Exchange Rates" }, { "EUROSTAT", "PRC_HICP_MIDX", "PRC_HICP_MIDX", "HICP - monthly data (index)" }, { "ILO", "*DF_EMP_TEMP_SEX_AGE_NB*", "DF_EMP_TEMP_SEX_AGE_NB", "Employment by sex and age" }, { "IMF2", "DS-WHDREO", "DS-WHDREO", "Western Hemisphere Regional Economic Outlook (WHDREO)" }, @@ -34,8 +35,10 @@ public static Collection data() { { "WB", "WDI", "WDI", "World Development Indicators" }, { "UNDATA", null, "DF_UNDATA_COUNTRYDATA", "SDMX-CountryData" }, { "OECD", "AEO", "AEO", "African Economic Outlook" }, - { "ISTAT_RI", null, "163_24", "Principali aggregati trimestrali di Contabilità Nazionale" }, - { "ISTAT", null, "144_125", "Nic - annuali sino al 2010" }, + { "OECD_NEW", "*DF_QNA_EXPENDITURE_CAPITA","DSD_NAMAIN1@DF_QNA_EXPENDITURE_CAPITA","Quarterly GDP per capita" }, + { "OECD_SDMXV3", "*DF_QNA_EXPENDITURE_CAPITA","DSD_NAMAIN1@DF_QNA_EXPENDITURE_CAPITA","Quarterly GDP per capita" }, + { "ISTAT_RI", null, "163_24", "National Accounts quarterly main aggregates" }, + { "ISTAT", null, "144_125", "Nic - annual data until 2010" }, { "BBK", null, "BBASV", "Deutsche Bundesbank, Statistics on Insurance Corporations (Solvency I + II)" } }, 0); } diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/DimensionsIT.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/DimensionsIT.java index 865ff5f6..5b4ddcb1 100644 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/DimensionsIT.java +++ b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/DimensionsIT.java @@ -25,18 +25,21 @@ public class DimensionsIT public static Collection data() { return FilterProvidersToTest.filter(new Object[][] { - { "ABS", "ATSI_BIRTHS_SUMM", 0, "MEASURE", "ABS/CL_BIRTHS_MEASURE/1.0.0" }, + { "ABS", "ATSI_BIRTHS_SUMM", 0, "MEASURE", "ABS/CL_BIRTHS_MEASURE/1.0.0" }, { "ECB", "EXR", 0, "FREQ", "ECB/CL_FREQ/1.0", }, + { "DEMO_SDMXV3", "EXR", 0, "FREQ", "ECB/CL_FREQ/1.0", }, { "WITS", "DF_WITS_Tariff_TRAINS", 0, "FREQ", "WBG_WITS/CL_FREQ_WITS/1.0", }, { "UNDATA", "DF_UNDATA_COUNTRYDATA", 0, "FREQ", "IAEG/CL_FREQ_MDG/1.0", }, { "ISTAT", "144_125", 0, "FREQ", "IT1/CL_FREQ/1.0", }, - { "ISTAT_RI", "144_125", 0, "FREQ", "IT1/CL_FREQ/1.0", }, + { "ISTAT_RI", "101_1015", 0, "FREQ", "IT1/CL_FREQ/1.0", }, { "INSEE", "CNA-2010-CONSO-SI", 0, "FREQ", "FR1/CL_PERIODICITE/1.0", }, { "INEGI", "DF_STEI", 0, "REF_AREA", "SDMX/CL_AREA/1.0", }, { "ILO", "DF_EMP_TEMP_SEX_AGE_NB", 0, "REF_AREA", "ILO/CL_AREA/1.0", }, - { "EUROSTAT", "prc_hicp_midx", 0, "FREQ", "ESTAT/CL_FREQ/1.0", }, + { "EUROSTAT", "prc_hicp_midx", 0, "freq", "ESTAT/FREQ/3.2", }, { "IMF2", "DS-WHDREO", 0, "FREQ", "IMF/CL_FREQ", }, { "OECD", "QNA", 0, "LOCATION", "OECD/CL_QNA_LOCATION", }, + { "OECD_NEW", "DSD_NAMAIN1@DF_QNA_EXPENDITURE_CAPITA",0, "FREQ", "SDMX/CL_FREQ/2.1", }, + { "OECD_SDMXV3", "DSD_NAMAIN1@DF_QNA_EXPENDITURE_CAPITA",0, "FREQ", "SDMX/CL_FREQ/2.1", }, { "WB", "WDI", 1, "SERIES", "WB/CL_SERIES_WDI/1.0", }, { "BBK", "BBASV", 0, "BBK_STD_FREQ", "BBK/CL_BBK_STD_FREQ/1.0", } }, 0); diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/FilterProvidersToTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/FilterProvidersToTest.java index 07cb1bc6..d8c33eee 100644 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/FilterProvidersToTest.java +++ b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/FilterProvidersToTest.java @@ -11,15 +11,18 @@ public class FilterProvidersToTest { private static final Set keepProviders = new HashSet<>(Arrays.asList(new String[] { -// "ABS", +// "ABS", //glitching "ECB", + "DEMO_SDMXV3", "EUROSTAT", "ILO", "INSEE", - "IMF2", +// "IMF2", // has rate limit "ISTAT", "ISTAT_RI", "OECD", + "OECD_NEW", + "OECD_SDMXV3", "UNDATA", "WITS", "BBK" diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/SDMXReferenceIT.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/SDMXReferenceIT.java index a39403de..4afa22a1 100644 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/SDMXReferenceIT.java +++ b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/SDMXReferenceIT.java @@ -24,13 +24,16 @@ public static Collection data() { { { "ABS", "QBIS", "ABS", "QBIS" }, { "ECB", "EXR", "ECB", "ECB_EXR1" }, + { "DEMO_SDMXV3", "EXR", "ECB", "ECB_EXR1" }, { "WITS", "DF_WITS_Tariff_TRAINS", "WBG_WITS", "TARIFF_TRAINS" }, { "WB", "WDI", null, "WDI" }, { "UNDATA", "DF_UNDATA_COUNTRYDATA", "UNSD", "CountryData" }, { "OECD", "QNA", null, "QNA" }, + { "OECD_NEW", "DSD_NAMAIN1@DF_QNA_EXPENDITURE_CAPITA","OECD.SDD.NAD", "DSD_NAMAIN1" }, + { "OECD_SDMXV3", "DSD_NAMAIN1@DF_QNA_EXPENDITURE_CAPITA","OECD.SDD.NAD", "DSD_NAMAIN1" }, { "NBB", "AFCSURV", null, "AFCSURV" }, { "ISTAT", "144_125", null, "DCSP_NICDUE" }, - { "ISTAT_RI", "163_24", null, "DCCN_QNA" }, + { "ISTAT_RI", "163_24", null, "DCCN_QNA" }, { "INSEE", "CNA-2010-CONSO-SI", "FR1", "CNA-2010-CONSO-SI" }, { "IMF2", "DS-WHDREO", null, "WHDREO" }, { "ILO", "DF_EMP_TEMP_SEX_AGE_NB", "ILO", "EMP_TEMP_SEX_AGE_NB" }, diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/TimeSeriesFromIDsIT.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/TimeSeriesFromIDsIT.java index faf2d8f6..27208b19 100644 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/TimeSeriesFromIDsIT.java +++ b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/it/TimeSeriesFromIDsIT.java @@ -28,6 +28,7 @@ public static Collection data() { { "WB", "WDI.A.SP_POP_TOTL.USA", "2000", "2010", 0, null, "WDI.A.SP_POP_TOTL.USA" }, { "UNDATA", "DF_UNDATA_COUNTRYDATA/A...U....", "2010", "2015", 172, null, null }, { "ABS", "ATSI_BIRTHS_SUMM/1...A", "2000", "2010", 16, null, null }, + { "DEMO_SDMXV3", "EXR/.GBP...", null, null, 8, null, null }, { "ECB", "EXR/.GBP+USD...", null, null, 16, null, null }, { "ECB", "EXR.*.USD|GBP.EUR.SP00.A", "2000", "2010", 10, null, null }, { "ECB", "EXR.A.USD.EUR.SP00.A;EXR.M.USD.EUR.SP00.A", "2000", "2010", 2, null, null }, @@ -37,6 +38,8 @@ public static Collection data() { { "ISTAT_RI", "163_24/Q.........2022M11", null, null, 0, null, "163_24.Q.IT.B1G_B_W2_S1._T.Z.Z.L_2015.N.B.2022M11" }, { "ISTAT", "115_362/M....", null, null, 0, null, "115_362.M.F.N.IT.CONS_PROD" }, { "OECD", "QNA.ITA.B1_GE.CARSA.Q", "2000", "2010", 0, "2000-Q1", "QNA.ITA.B1_GE.CARSA.Q" }, + { "OECD_NEW", "DSD_NAMAIN1@DF_QNA_EXPENDITURE_CAPITA.Q.Y.ISR.S1.S1.B1GQ_POP._Z._Z._Z.USD_PPP_PS.V.LA.T0102", "2000", "2010", 0, "2000-Q1", "DSD_NAMAIN1@DF_QNA_EXPENDITURE_CAPITA.Q.Y.ISR.S1.S1.B1GQ_POP._Z._Z._Z.USD_PPP_PS.V.LA.T0102" }, + { "OECD_SDMXV3","DSD_NAMAIN1@DF_QNA_EXPENDITURE_CAPITA.Q.Y.ISR.S1.S1.B1GQ_POP._Z._Z._Z.USD_PPP_PS.V.LA.T0102", "2000", "2010", 0, "2000-Q1", "DSD_NAMAIN1@DF_QNA_EXPENDITURE_CAPITA.Q.Y.ISR.S1.S1.B1GQ_POP._Z._Z._Z.USD_PPP_PS.V.LA.T0102" }, { "EUROSTAT", "PRC_HICP_MIDX/..CP00.EU+DE+FR", "2000", "2013-08", 0, "2000-01", "PRC_HICP_MIDX.M.I05.CP00.DE" }, { "BBK", "BBASV/Q.DE.M.KV.A10.T.1.AT.S1._T.EUR", "2017-Q1", "2017-Q4", 0, "2017-Q1", "BBASV.Q.DE.M.KV.A10.T.1.AT.S1._T.EUR" } }, 0); @@ -52,7 +55,7 @@ public static Collection data() { @Test public void timeSeriesFromID() throws SdmxException { - List> res = SdmxClientHandler.getTimeSeries(provider, query, start, end); + List> res = SdmxClientHandler.getTimeSeries(provider, query, start, end, false, null, false); assertNotNull("Null time series result", res); if (expectedCount == 0) assertTrue("No time series returned", res.size() > 0); diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/ut/AllTests.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/ut/AllTests.java index bffd3565..03fd97d7 100644 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/ut/AllTests.java +++ b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/ut/AllTests.java @@ -24,17 +24,20 @@ import it.bancaditalia.oss.sdmx.it.SDMXReferenceIT; import it.bancaditalia.oss.sdmx.it.DataflowsIT; +import it.bancaditalia.oss.sdmx.it.DimensionsIT; import it.bancaditalia.oss.sdmx.it.CodesIT; import it.bancaditalia.oss.sdmx.it.TimeSeriesFromIDsIT; @RunWith(Suite.class) @Suite.SuiteClasses( { SdmxInterfaceTest.class, + DimensionsIT.class, CodesIT.class, SDMXReferenceIT.class, ProxyTest.class, RestQueryBuilderTest.class, DataflowsIT.class, - TimeSeriesFromIDsIT.class + TimeSeriesFromIDsIT.class, + TimeSeriesFromFiltersTest.class }) public class AllTests { } diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/ut/SdmxInterfaceTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/ut/SdmxInterfaceTest.java index f8671b53..e24ee23c 100644 --- a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/ut/SdmxInterfaceTest.java +++ b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/ut/SdmxInterfaceTest.java @@ -21,6 +21,7 @@ package it.bancaditalia.oss.sdmx.ut; +import static it.bancaditalia.oss.sdmx.api.SDMXVersion.V2; import static org.junit.Assert.assertNotNull; import java.net.MalformedURLException; @@ -38,8 +39,7 @@ public class SdmxInterfaceTest @Test public void testGetAddProvider() throws SdmxException, MalformedURLException { - SdmxClientHandler.addProvider("TEST", "http://sdw-wsrest.ecb.europa.eu/service", false, false, false, - "test provider"); + SdmxClientHandler.addProvider("TEST", "http://sdw-wsrest.ecb.europa.eu/service", false, false, false, "test provider", V2); GenericSDMXClient a = SDMXClientFactory.createClient("TEST"); assertNotNull("Add Provider failed", a); } @@ -206,40 +206,40 @@ public void testGetCodesFail8() throws SdmxException @Test(expected = SdmxException.class) public void testGetTimeSeriesFail1() throws SdmxException { - SdmxClientHandler.getTimeSeries(null, "EXR.A.GBP+USD.EUR.SP00.A", null, null); + SdmxClientHandler.getTimeSeries(null, "EXR.A.GBP+USD.EUR.SP00.A", null, null, false, null, false); } @Test(expected = SdmxException.class) public void testGetTimeSeriesFail2() throws SdmxException { - SdmxClientHandler.getTimeSeries("", "EXR.A.GBP+USD.EUR.SP00.A", null, null); + SdmxClientHandler.getTimeSeries("", "EXR.A.GBP+USD.EUR.SP00.A", null, null, false, null, false); } @Test(expected = SdmxException.class) public void testGetTimeSeriesFail3() throws SdmxException { - SdmxClientHandler.getTimeSeries("DUMMY", "EXR.A.USD.EUR.SP00.A", null, null); + SdmxClientHandler.getTimeSeries("DUMMY", "EXR.A.USD.EUR.SP00.A", null, null, false, null, false); } @Test(expected = SdmxException.class) public void testGetTimeSeriesFail4() throws SdmxException { - //dataflow cannot be in series key and in dataflo argument - SdmxClientHandler.getTimeSeries("ECB", "EXR", "EXR.A.USD.EUR.SP00.A", null, null, null, false, null, false); + //dataflow cannot be in series key and in dataflow argument + SdmxClientHandler.getTimeSeries2("ECB", "EXR", "EXR.A.USD.EUR.SP00.A", null, null, null, "all", "all", null, false); } @Test(expected = SdmxException.class) public void testGetTimeSeriesFail5() throws SdmxException { //dataflow must be present if series key is not specified at all - SdmxClientHandler.getTimeSeries("ECB", null, null, "c[FREQ]=A", null, null, false, null, false); + SdmxClientHandler.getTimeSeries2("ECB", null, null, "c[FREQ]=A", null, null, "all", "all", null, false); } @Test(expected = SdmxException.class) public void testGetTimeSeriesFail6() throws SdmxException { //dataflow must be present as argument or in series key - no results here - SdmxClientHandler.getTimeSeries("ECB", null, "A.USD.EUR.SP00.A", "c[FREQ]=A", null, null, false, null, false); + SdmxClientHandler.getTimeSeries2("ECB", null, "A.USD.EUR.SP00.A", "c[FREQ]=A", null, null, "all", "all", null, false); } /* TODO: Move to IT tests diff --git a/JAVA/src/test/java/it/bancaditalia/oss/sdmx/ut/TimeSeriesFromFiltersTest.java b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/ut/TimeSeriesFromFiltersTest.java new file mode 100644 index 00000000..96936542 --- /dev/null +++ b/JAVA/src/test/java/it/bancaditalia/oss/sdmx/ut/TimeSeriesFromFiltersTest.java @@ -0,0 +1,61 @@ +/* Copyright 2023,2023 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.ut; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +import it.bancaditalia.oss.sdmx.api.PortableTimeSeries; +import it.bancaditalia.oss.sdmx.client.SdmxClientHandler; +import it.bancaditalia.oss.sdmx.exceptions.SdmxException; + +public class TimeSeriesFromFiltersTest +{ + @Test + public void testKeysAndFilters() throws SdmxException + { + //A.GBP+USD.EUR.SP00.A and A.USD.EUR.SP00.A + List> result = SdmxClientHandler.getTimeSeries2("DEMO_SDMXV3", "EXR", "A.GBP+USD.EUR.SP00.A", null, null, null, "all", "all", null, false); + assertEquals(2, result.size()); + //A.GBP+USD.EUR.SP00.A and A.USD.EUR.SP00.A with filter + result = SdmxClientHandler.getTimeSeries2("DEMO_SDMXV3", "EXR", null, "c[FREQ]=A&c[CURRENCY]=USD,GBP&c[EXR_SUFFIX]=A", null, null, "all", "all", null, false); + assertEquals(2, result.size()); + //.USD.EUR.SP00.A + result = SdmxClientHandler.getTimeSeries2("DEMO_SDMXV3", "EXR", ".USD.EUR.SP00.A", null, null, null, "all", "all", null, false); + assertEquals(5, result.size()); + //.USD.EUR.SP00.A with filter + result = SdmxClientHandler.getTimeSeries2("DEMO_SDMXV3", "EXR", null, "c[CURRENCY]=USD&c[CURRENCY_DENOMINATOR]=EUR&c[EXR_TYPE]=SP00&c[EXR_SUFFIX]=A", null, null, "all", "all", null, false); + assertEquals(5, result.size()); + //mix key and filter + result = SdmxClientHandler.getTimeSeries2("DEMO_SDMXV3", "EXR", "A..EUR.SP00.A", "c[FREQ]=A&c[CURRENCY]=USD&c[CURRENCY_DENOMINATOR]=EUR&c[EXR_TYPE]=SP00&c[EXR_SUFFIX]=A", null, null, "all", "all", null, false); + assertEquals(1, result.size()); + //mix key and filter + time + result = SdmxClientHandler.getTimeSeries2("DEMO_SDMXV3", "EXR", "A..EUR.SP00.A", "c[FREQ]=A&c[CURRENCY]=USD&c[CURRENCY_DENOMINATOR]=EUR&c[EXR_TYPE]=SP00&c[EXR_SUFFIX]=A", "2001", "2010", "all", "all", null, false); + assertEquals(1, result.size()); + assertEquals(10, result.get(0).size()); + //mix key and filter + serieskeysonly + result = SdmxClientHandler.getTimeSeries2("DEMO_SDMXV3", "EXR", "A..EUR.SP00.A", "c[FREQ]=A&c[CURRENCY]=USD&c[CURRENCY_DENOMINATOR]=EUR&c[EXR_TYPE]=SP00&c[EXR_SUFFIX]=A", null, null, "none", "none", null, false); + assertEquals(1, result.size()); + } +} \ No newline at end of file diff --git a/JAVA/stata_src/it/bancaditalia/oss/sdmx/client/StataClientHandler.java b/JAVA/stata_src/it/bancaditalia/oss/sdmx/client/StataClientHandler.java index 2a6aa530..a2f6c3d9 100644 --- a/JAVA/stata_src/it/bancaditalia/oss/sdmx/client/StataClientHandler.java +++ b/JAVA/stata_src/it/bancaditalia/oss/sdmx/client/StataClientHandler.java @@ -21,6 +21,9 @@ package it.bancaditalia.oss.sdmx.client; +import static it.bancaditalia.oss.sdmx.api.SDMXVersion.V2; +import static it.bancaditalia.oss.sdmx.api.SDMXVersion.V3; + import java.util.List; import java.util.Map.Entry; import java.util.logging.Level; @@ -31,6 +34,7 @@ import it.bancaditalia.oss.sdmx.api.BaseObservation; import it.bancaditalia.oss.sdmx.api.PortableTimeSeries; +import it.bancaditalia.oss.sdmx.api.SDMXVersion; import it.bancaditalia.oss.sdmx.helper.SDMXHelper; import it.bancaditalia.oss.sdmx.util.Configuration; @@ -111,7 +115,7 @@ else if (meta.equalsIgnoreCase("2")) try { int dataLength = 0; - tslist = SdmxClientHandler.getTimeSeries(provider, null, tsKey, null, start, end, false, null, false); + tslist = SdmxClientHandler.getTimeSeries(provider, tsKey, start, end, false, null, false); if (tslist == null) { SFIToolkit.displayln("The query did not complete correctly. Check java traces for details."); @@ -292,6 +296,7 @@ public static int addProvider(String[] args) boolean needsURLEncoding = false; boolean supportsCompression = false; String description = ""; + SDMXVersion sdmxVersion = V2; if (args.length >= 3 && !args[2].isEmpty()) { @@ -309,11 +314,14 @@ public static int addProvider(String[] args) { description = args[5]; } + if (args.length >= 7 && !args[6].isEmpty()) + { + sdmxVersion = args[5] == "V2" ? V2 : V3; + } try { - SdmxClientHandler.addProvider(name, endpoint, needsCredentials, needsURLEncoding, supportsCompression, - description); + SdmxClientHandler.addProvider(name, endpoint, needsCredentials, needsURLEncoding, supportsCompression, description, sdmxVersion); } catch (Exception e) { diff --git a/MATLAB/SDMX.prj b/MATLAB/SDMX.prj new file mode 100644 index 00000000..92c66969 --- /dev/null +++ b/MATLAB/SDMX.prj @@ -0,0 +1,2 @@ + + diff --git a/MATLAB/buildfile.m b/MATLAB/buildfile.m new file mode 100644 index 00000000..a7e354ee --- /dev/null +++ b/MATLAB/buildfile.m @@ -0,0 +1,65 @@ +function plan = buildfile + +% Create a plan from task functions +plan = buildplan(localfunctions); + +% Make the "archive" task the default task in the plan +plan.DefaultTasks = "archive"; + +% Make the "archive" task dependent on the "check" and "test" tasks +plan("archive").Dependencies = ["check" "test"]; +end + +function checkTask(~) +% Identify code issues +issues = codeIssues; +assert(isempty(issues.Issues),formattedDisplayText( ... + issues.Issues(:,["Location" "Severity" "Description"]))) +end + +function testTask(~) + +% Run unit tests +import matlab.unittest.TestRunner; +import matlab.unittest.TestSuite; +import matlab.unittest.plugins.TestReportPlugin; +import matlab.unittest.plugins.CodeCoveragePlugin +import matlab.unittest.plugins.codecoverage.CoverageReport +import matlab.unittest.plugins.codecoverage.CoverageResult + +suite = TestSuite.fromProject(currentProject); + +runner = TestRunner.withTextOutput; +htmlFolder = 'tests/reports/results'; +plugin = TestReportPlugin.producingHTML(htmlFolder); +runner.addPlugin(plugin); + +sourceCodeFolder = "tbx/sdmx"; +reportFolder = "tests/reports/coverageReport"; +reportFormat = CoverageReport(reportFolder); +format = CoverageResult; +plugin = CodeCoveragePlugin.forFolder(sourceCodeFolder,"Producing",[reportFormat,format], ... + IncludingSubfolders = true); +runner.addPlugin(plugin) + +results = runner.run(suite); + +assertSuccess(results); + +end + +function archiveTask(~) +description = sprintf('The SDMX Connectors project has been developed with the aim of covering the ''last mile'' in SDMX implementations.\n\nIn particular, the focus of the project is to provide the end user a set of plugins that can be easily installed in the most popular data analysis tools (e.g. R, MATLAB, SAS, STATA, Excel, etc.) allowing a direct access to SDMX data from the tool.\nProject site: \n\nhttps://github.com/amattioc/SDMX'); +% Create ZIP file +opts = matlab.addons.toolbox.ToolboxOptions('tbx', "50de8506-6d87-47ee-aa8a-2c7f2e56d761", ... + ToolboxName = 'MatSDMX', ... + ToolboxVersion = '4.0.0', ... + AuthorName = 'Attilio Mattiocco', ... + Summary = 'Provides functions to retrieve data and metadata from providers that disseminate data by means of SDMX web services.', ... + Description = description, ... + ToolboxJavaPath = "tbx/lib/SDMX-3.1.0.jar", ... + ToolboxGettingStartedGuide = 'tbx/doc/GettingStarted.mlx', ... + OutputFile = 'releases/SDMX.mltbx', ... + MinimumMatlabRelease = 'R2023a'); +matlab.addons.toolbox.packageToolbox(opts) +end \ No newline at end of file diff --git a/MATLAB/demo.m b/MATLAB/demo.m deleted file mode 100644 index dc8e26dd..00000000 --- a/MATLAB/demo.m +++ /dev/null @@ -1,49 +0,0 @@ - -% Simple script for DEMO/TEST purposes -% -% ############################################################################################# -% Copyright 2010,2014 Bank Of Italy -% -% Licensed under the EUPL, Version 1.1 or as soon as 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. -% -getProviders - -flows = getFlows('ECB') -flows.keys -flows.values -flows('EXR') - -getDimensions('ECB', 'EXR') - -tts = getTimeSeries('ECB', 'EXR.M.USD|GBP.EUR.SP00.A') -tts{1}.UserData -tts{1}.UserData('TITLE_COMPL') -plot(tts{1}) - -flows = getFlows('EUROSTAT') -flows.keys -flows.values - -getDimensions('EUROSTAT', 'prc_hicp_midx') - -tts = getTimeSeries('EUROSTAT', 'prc_hicp_midx/..CP00.EU+DE+FR') -plot(tts{1}) - -sdmxHelp - diff --git a/MATLAB/resources/project/DgUGwJOjC5wX0zfM0vb348VTsKs/Z2gQ5he-eOzZR2jQ1JLLC4LXSlcd.xml b/MATLAB/resources/project/DgUGwJOjC5wX0zfM0vb348VTsKs/Z2gQ5he-eOzZR2jQ1JLLC4LXSlcd.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/DgUGwJOjC5wX0zfM0vb348VTsKs/Z2gQ5he-eOzZR2jQ1JLLC4LXSlcd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/DgUGwJOjC5wX0zfM0vb348VTsKs/Z2gQ5he-eOzZR2jQ1JLLC4LXSlcp.xml b/MATLAB/resources/project/DgUGwJOjC5wX0zfM0vb348VTsKs/Z2gQ5he-eOzZR2jQ1JLLC4LXSlcp.xml new file mode 100644 index 00000000..842de6ab --- /dev/null +++ b/MATLAB/resources/project/DgUGwJOjC5wX0zfM0vb348VTsKs/Z2gQ5he-eOzZR2jQ1JLLC4LXSlcp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/Ch430yJIsZDBUwjDly5EsAEAETUd.xml b/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/Ch430yJIsZDBUwjDly5EsAEAETUd.xml new file mode 100644 index 00000000..aee0cde3 --- /dev/null +++ b/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/Ch430yJIsZDBUwjDly5EsAEAETUd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/Ch430yJIsZDBUwjDly5EsAEAETUp.xml b/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/Ch430yJIsZDBUwjDly5EsAEAETUp.xml new file mode 100644 index 00000000..3e258f00 --- /dev/null +++ b/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/Ch430yJIsZDBUwjDly5EsAEAETUp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/_6_yMkSjSMN4rq8VEZzkAx2DBh4d.xml b/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/_6_yMkSjSMN4rq8VEZzkAx2DBh4d.xml new file mode 100644 index 00000000..fff32262 --- /dev/null +++ b/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/_6_yMkSjSMN4rq8VEZzkAx2DBh4d.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/_6_yMkSjSMN4rq8VEZzkAx2DBh4p.xml b/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/_6_yMkSjSMN4rq8VEZzkAx2DBh4p.xml new file mode 100644 index 00000000..f55941ad --- /dev/null +++ b/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/_6_yMkSjSMN4rq8VEZzkAx2DBh4p.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/ikHv63hpmqk2RzSaO85_bPgFbT0d.xml b/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/ikHv63hpmqk2RzSaO85_bPgFbT0d.xml new file mode 100644 index 00000000..170d0b7d --- /dev/null +++ b/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/ikHv63hpmqk2RzSaO85_bPgFbT0d.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/ikHv63hpmqk2RzSaO85_bPgFbT0p.xml b/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/ikHv63hpmqk2RzSaO85_bPgFbT0p.xml new file mode 100644 index 00000000..c2e186e6 --- /dev/null +++ b/MATLAB/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/ikHv63hpmqk2RzSaO85_bPgFbT0p.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/0B1KspbUt-241FI7We1N5-9R-rId.xml b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/0B1KspbUt-241FI7We1N5-9R-rId.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/0B1KspbUt-241FI7We1N5-9R-rId.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/0B1KspbUt-241FI7We1N5-9R-rIp.xml b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/0B1KspbUt-241FI7We1N5-9R-rIp.xml new file mode 100644 index 00000000..e6a72c77 --- /dev/null +++ b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/0B1KspbUt-241FI7We1N5-9R-rIp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/6DdEMMcGeFK0a-8m7nwliEThbfQd.xml b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/6DdEMMcGeFK0a-8m7nwliEThbfQd.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/6DdEMMcGeFK0a-8m7nwliEThbfQd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/6DdEMMcGeFK0a-8m7nwliEThbfQp.xml b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/6DdEMMcGeFK0a-8m7nwliEThbfQp.xml new file mode 100644 index 00000000..842de6ab --- /dev/null +++ b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/6DdEMMcGeFK0a-8m7nwliEThbfQp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/KNmT8r4RH_qr5q378jmjVxPDRMUd.xml b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/KNmT8r4RH_qr5q378jmjVxPDRMUd.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/KNmT8r4RH_qr5q378jmjVxPDRMUd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/KNmT8r4RH_qr5q378jmjVxPDRMUp.xml b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/KNmT8r4RH_qr5q378jmjVxPDRMUp.xml new file mode 100644 index 00000000..4f7668fb --- /dev/null +++ b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/KNmT8r4RH_qr5q378jmjVxPDRMUp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/Q8mhuPw_Tv7RuH9j3jiPsyPukWod.xml b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/Q8mhuPw_Tv7RuH9j3jiPsyPukWod.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/Q8mhuPw_Tv7RuH9j3jiPsyPukWod.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/Q8mhuPw_Tv7RuH9j3jiPsyPukWop.xml b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/Q8mhuPw_Tv7RuH9j3jiPsyPukWop.xml new file mode 100644 index 00000000..3656b7a0 --- /dev/null +++ b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/Q8mhuPw_Tv7RuH9j3jiPsyPukWop.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/RAmtYgVqCJmHDF8W1keZNcWXr4Ad.xml b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/RAmtYgVqCJmHDF8W1keZNcWXr4Ad.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/RAmtYgVqCJmHDF8W1keZNcWXr4Ad.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/RAmtYgVqCJmHDF8W1keZNcWXr4Ap.xml b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/RAmtYgVqCJmHDF8W1keZNcWXr4Ap.xml new file mode 100644 index 00000000..cd43341f --- /dev/null +++ b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/RAmtYgVqCJmHDF8W1keZNcWXr4Ap.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/tyfeE7DbJimZcSYGqqZamn_KGXQd.xml b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/tyfeE7DbJimZcSYGqqZamn_KGXQd.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/tyfeE7DbJimZcSYGqqZamn_KGXQd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/tyfeE7DbJimZcSYGqqZamn_KGXQp.xml b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/tyfeE7DbJimZcSYGqqZamn_KGXQp.xml new file mode 100644 index 00000000..2160c650 --- /dev/null +++ b/MATLAB/resources/project/K-M49kMK9kyHCEDqQhcRRdI7xS0/tyfeE7DbJimZcSYGqqZamn_KGXQp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/5uLoVhgKSMxekrqkNICN1R0WL68d.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/5uLoVhgKSMxekrqkNICN1R0WL68d.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/5uLoVhgKSMxekrqkNICN1R0WL68d.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/5uLoVhgKSMxekrqkNICN1R0WL68p.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/5uLoVhgKSMxekrqkNICN1R0WL68p.xml new file mode 100644 index 00000000..db0f8cb2 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/5uLoVhgKSMxekrqkNICN1R0WL68p.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/HMzi1SjT051J99V7MztUw9bamCAd.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/HMzi1SjT051J99V7MztUw9bamCAd.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/HMzi1SjT051J99V7MztUw9bamCAd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/HMzi1SjT051J99V7MztUw9bamCAp.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/HMzi1SjT051J99V7MztUw9bamCAp.xml new file mode 100644 index 00000000..180e0209 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/HMzi1SjT051J99V7MztUw9bamCAp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/KHU6PkkQT_DUjGU7mYvQpowEyqUd.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/KHU6PkkQT_DUjGU7mYvQpowEyqUd.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/KHU6PkkQT_DUjGU7mYvQpowEyqUd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/KHU6PkkQT_DUjGU7mYvQpowEyqUp.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/KHU6PkkQT_DUjGU7mYvQpowEyqUp.xml new file mode 100644 index 00000000..6125c725 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/KHU6PkkQT_DUjGU7mYvQpowEyqUp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/L770E7DimF-RzKpWtgO7Z9SkrS8d.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/L770E7DimF-RzKpWtgO7Z9SkrS8d.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/L770E7DimF-RzKpWtgO7Z9SkrS8d.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/L770E7DimF-RzKpWtgO7Z9SkrS8p.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/L770E7DimF-RzKpWtgO7Z9SkrS8p.xml new file mode 100644 index 00000000..d9ce7958 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/L770E7DimF-RzKpWtgO7Z9SkrS8p.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/PGcOmU52yoRRa8teSsBWs-uLgRwd.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/PGcOmU52yoRRa8teSsBWs-uLgRwd.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/PGcOmU52yoRRa8teSsBWs-uLgRwd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/PGcOmU52yoRRa8teSsBWs-uLgRwp.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/PGcOmU52yoRRa8teSsBWs-uLgRwp.xml new file mode 100644 index 00000000..81d4be24 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/PGcOmU52yoRRa8teSsBWs-uLgRwp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/PIzut2jQU7AMhC-x8vXTBBb8jGEd.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/PIzut2jQU7AMhC-x8vXTBBb8jGEd.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/PIzut2jQU7AMhC-x8vXTBBb8jGEd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/PIzut2jQU7AMhC-x8vXTBBb8jGEp.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/PIzut2jQU7AMhC-x8vXTBBb8jGEp.xml new file mode 100644 index 00000000..c7b91a91 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/PIzut2jQU7AMhC-x8vXTBBb8jGEp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/VDAuUCs6Wvcrm89RH-eUwFizHNQd.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/VDAuUCs6Wvcrm89RH-eUwFizHNQd.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/VDAuUCs6Wvcrm89RH-eUwFizHNQd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/VDAuUCs6Wvcrm89RH-eUwFizHNQp.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/VDAuUCs6Wvcrm89RH-eUwFizHNQp.xml new file mode 100644 index 00000000..15190d18 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/VDAuUCs6Wvcrm89RH-eUwFizHNQp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/Ye_GeJ0XCMq2HiU9BwytwhQvpYkd.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/Ye_GeJ0XCMq2HiU9BwytwhQvpYkd.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/Ye_GeJ0XCMq2HiU9BwytwhQvpYkd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/Ye_GeJ0XCMq2HiU9BwytwhQvpYkp.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/Ye_GeJ0XCMq2HiU9BwytwhQvpYkp.xml new file mode 100644 index 00000000..842de6ab --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/Ye_GeJ0XCMq2HiU9BwytwhQvpYkp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/YjEFtWznPEXVmHNBgiRCdQQI5XQd.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/YjEFtWznPEXVmHNBgiRCdQQI5XQd.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/YjEFtWznPEXVmHNBgiRCdQQI5XQd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/YjEFtWznPEXVmHNBgiRCdQQI5XQp.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/YjEFtWznPEXVmHNBgiRCdQQI5XQp.xml new file mode 100644 index 00000000..eeaa59c7 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/YjEFtWznPEXVmHNBgiRCdQQI5XQp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/hG9Ew1je-8cGZ6LSHlZuyAif-VQd.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/hG9Ew1je-8cGZ6LSHlZuyAif-VQd.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/hG9Ew1je-8cGZ6LSHlZuyAif-VQd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/hG9Ew1je-8cGZ6LSHlZuyAif-VQp.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/hG9Ew1je-8cGZ6LSHlZuyAif-VQp.xml new file mode 100644 index 00000000..b5012ff5 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/hG9Ew1je-8cGZ6LSHlZuyAif-VQp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/hg2ns5sqM66imK0-O9IbJFpaMnQd.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/hg2ns5sqM66imK0-O9IbJFpaMnQd.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/hg2ns5sqM66imK0-O9IbJFpaMnQd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/hg2ns5sqM66imK0-O9IbJFpaMnQp.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/hg2ns5sqM66imK0-O9IbJFpaMnQp.xml new file mode 100644 index 00000000..d33ce1c9 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/hg2ns5sqM66imK0-O9IbJFpaMnQp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/oZAxUFQ91_ZuU61SrexlMXTgXHYd.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/oZAxUFQ91_ZuU61SrexlMXTgXHYd.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/oZAxUFQ91_ZuU61SrexlMXTgXHYd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/oZAxUFQ91_ZuU61SrexlMXTgXHYp.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/oZAxUFQ91_ZuU61SrexlMXTgXHYp.xml new file mode 100644 index 00000000..0f8cba01 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/oZAxUFQ91_ZuU61SrexlMXTgXHYp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/slsk9MXhWORuaqzeARvh8naIRCId.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/slsk9MXhWORuaqzeARvh8naIRCId.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/slsk9MXhWORuaqzeARvh8naIRCId.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/slsk9MXhWORuaqzeARvh8naIRCIp.xml b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/slsk9MXhWORuaqzeARvh8naIRCIp.xml new file mode 100644 index 00000000..5a2660f9 --- /dev/null +++ b/MATLAB/resources/project/KNmT8r4RH_qr5q378jmjVxPDRMU/slsk9MXhWORuaqzeARvh8naIRCIp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/K-M49kMK9kyHCEDqQhcRRdI7xS0d.xml b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/K-M49kMK9kyHCEDqQhcRRdI7xS0d.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/K-M49kMK9kyHCEDqQhcRRdI7xS0d.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/K-M49kMK9kyHCEDqQhcRRdI7xS0p.xml b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/K-M49kMK9kyHCEDqQhcRRdI7xS0p.xml new file mode 100644 index 00000000..ad7819f7 --- /dev/null +++ b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/K-M49kMK9kyHCEDqQhcRRdI7xS0p.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/QZShZjci1QuiMc-CQm0gdbuwyIMd.xml b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/QZShZjci1QuiMc-CQm0gdbuwyIMd.xml new file mode 100644 index 00000000..0675ae34 --- /dev/null +++ b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/QZShZjci1QuiMc-CQm0gdbuwyIMd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/QZShZjci1QuiMc-CQm0gdbuwyIMp.xml b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/QZShZjci1QuiMc-CQm0gdbuwyIMp.xml new file mode 100644 index 00000000..e0d35076 --- /dev/null +++ b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/QZShZjci1QuiMc-CQm0gdbuwyIMp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/agxR7FUzCbenMOuGmnOZCKnzhHEd.xml b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/agxR7FUzCbenMOuGmnOZCKnzhHEd.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/agxR7FUzCbenMOuGmnOZCKnzhHEd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/agxR7FUzCbenMOuGmnOZCKnzhHEp.xml b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/agxR7FUzCbenMOuGmnOZCKnzhHEp.xml new file mode 100644 index 00000000..842de6ab --- /dev/null +++ b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/agxR7FUzCbenMOuGmnOZCKnzhHEp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/z1WpNcC741vkTKd8uJQQCkdFUWsd.xml b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/z1WpNcC741vkTKd8uJQQCkdFUWsd.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/z1WpNcC741vkTKd8uJQQCkdFUWsd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/z1WpNcC741vkTKd8uJQQCkdFUWsp.xml b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/z1WpNcC741vkTKd8uJQQCkdFUWsp.xml new file mode 100644 index 00000000..0c8db8a4 --- /dev/null +++ b/MATLAB/resources/project/L-idrZRjZXZ8jYd7-E8teU8ewW4/z1WpNcC741vkTKd8uJQQCkdFUWsp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml new file mode 100644 index 00000000..7c095251 --- /dev/null +++ b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml new file mode 100644 index 00000000..14fcc348 --- /dev/null +++ b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml new file mode 100644 index 00000000..fbb2a47f --- /dev/null +++ b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml new file mode 100644 index 00000000..9916b1e9 --- /dev/null +++ b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml new file mode 100644 index 00000000..61bc2663 --- /dev/null +++ b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml new file mode 100644 index 00000000..23b0eab3 --- /dev/null +++ b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml new file mode 100644 index 00000000..96226df7 --- /dev/null +++ b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml new file mode 100644 index 00000000..70b5b070 --- /dev/null +++ b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml new file mode 100644 index 00000000..5b30f4e8 --- /dev/null +++ b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml new file mode 100644 index 00000000..817277da --- /dev/null +++ b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml new file mode 100644 index 00000000..e47ab1f1 --- /dev/null +++ b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml new file mode 100644 index 00000000..15f4e1e7 --- /dev/null +++ b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml new file mode 100644 index 00000000..f9f98e8f --- /dev/null +++ b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml new file mode 100644 index 00000000..1aed36c3 --- /dev/null +++ b/MATLAB/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/Project.xml b/MATLAB/resources/project/Project.xml new file mode 100644 index 00000000..0232696f --- /dev/null +++ b/MATLAB/resources/project/Project.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml b/MATLAB/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml new file mode 100644 index 00000000..310a18c3 --- /dev/null +++ b/MATLAB/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml b/MATLAB/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml new file mode 100644 index 00000000..d6808df7 --- /dev/null +++ b/MATLAB/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/gLNRpyfniAp0pH9O-Iamc-C4xCI/e15jxRadjxYuJsCAUkUtS1x_l08d.xml b/MATLAB/resources/project/gLNRpyfniAp0pH9O-Iamc-C4xCI/e15jxRadjxYuJsCAUkUtS1x_l08d.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/gLNRpyfniAp0pH9O-Iamc-C4xCI/e15jxRadjxYuJsCAUkUtS1x_l08d.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/gLNRpyfniAp0pH9O-Iamc-C4xCI/e15jxRadjxYuJsCAUkUtS1x_l08p.xml b/MATLAB/resources/project/gLNRpyfniAp0pH9O-Iamc-C4xCI/e15jxRadjxYuJsCAUkUtS1x_l08p.xml new file mode 100644 index 00000000..842de6ab --- /dev/null +++ b/MATLAB/resources/project/gLNRpyfniAp0pH9O-Iamc-C4xCI/e15jxRadjxYuJsCAUkUtS1x_l08p.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/--ojuT5M97pkSl92JbfMXmStcwQd.xml b/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/--ojuT5M97pkSl92JbfMXmStcwQd.xml new file mode 100644 index 00000000..30f473b5 --- /dev/null +++ b/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/--ojuT5M97pkSl92JbfMXmStcwQd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/--ojuT5M97pkSl92JbfMXmStcwQp.xml b/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/--ojuT5M97pkSl92JbfMXmStcwQp.xml new file mode 100644 index 00000000..7c111a27 --- /dev/null +++ b/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/--ojuT5M97pkSl92JbfMXmStcwQp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/8Qdz0iiiuHlFJjxB6c5reQ4NAkQd.xml b/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/8Qdz0iiiuHlFJjxB6c5reQ4NAkQd.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/8Qdz0iiiuHlFJjxB6c5reQ4NAkQd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/8Qdz0iiiuHlFJjxB6c5reQ4NAkQp.xml b/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/8Qdz0iiiuHlFJjxB6c5reQ4NAkQp.xml new file mode 100644 index 00000000..842de6ab --- /dev/null +++ b/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/8Qdz0iiiuHlFJjxB6c5reQ4NAkQp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/DgUGwJOjC5wX0zfM0vb348VTsKsd.xml b/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/DgUGwJOjC5wX0zfM0vb348VTsKsd.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/DgUGwJOjC5wX0zfM0vb348VTsKsd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/DgUGwJOjC5wX0zfM0vb348VTsKsp.xml b/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/DgUGwJOjC5wX0zfM0vb348VTsKsp.xml new file mode 100644 index 00000000..ffbec60e --- /dev/null +++ b/MATLAB/resources/project/hLMKfvmMZYFbdoE4Xco7ryXas6s/DgUGwJOjC5wX0zfM0vb348VTsKsp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/L-idrZRjZXZ8jYd7-E8teU8ewW4d.xml b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/L-idrZRjZXZ8jYd7-E8teU8ewW4d.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/L-idrZRjZXZ8jYd7-E8teU8ewW4d.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/L-idrZRjZXZ8jYd7-E8teU8ewW4p.xml b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/L-idrZRjZXZ8jYd7-E8teU8ewW4p.xml new file mode 100644 index 00000000..c74525ef --- /dev/null +++ b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/L-idrZRjZXZ8jYd7-E8teU8ewW4p.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/dbaDl4AUhYvN4Xb6qgAQ2WDPaAgd.xml b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/dbaDl4AUhYvN4Xb6qgAQ2WDPaAgd.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/dbaDl4AUhYvN4Xb6qgAQ2WDPaAgd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/dbaDl4AUhYvN4Xb6qgAQ2WDPaAgp.xml b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/dbaDl4AUhYvN4Xb6qgAQ2WDPaAgp.xml new file mode 100644 index 00000000..8d960b8e --- /dev/null +++ b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/dbaDl4AUhYvN4Xb6qgAQ2WDPaAgp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/gLNRpyfniAp0pH9O-Iamc-C4xCId.xml b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/gLNRpyfniAp0pH9O-Iamc-C4xCId.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/gLNRpyfniAp0pH9O-Iamc-C4xCId.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/gLNRpyfniAp0pH9O-Iamc-C4xCIp.xml b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/gLNRpyfniAp0pH9O-Iamc-C4xCIp.xml new file mode 100644 index 00000000..6f283988 --- /dev/null +++ b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/gLNRpyfniAp0pH9O-Iamc-C4xCIp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/hLMKfvmMZYFbdoE4Xco7ryXas6sd.xml b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/hLMKfvmMZYFbdoE4Xco7ryXas6sd.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/hLMKfvmMZYFbdoE4Xco7ryXas6sd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/hLMKfvmMZYFbdoE4Xco7ryXas6sp.xml b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/hLMKfvmMZYFbdoE4Xco7ryXas6sp.xml new file mode 100644 index 00000000..d4df5b9c --- /dev/null +++ b/MATLAB/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/hLMKfvmMZYFbdoE4Xco7ryXas6sp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/root/EEtUlUb-dLAdf0KpMVivaUlztwAp.xml b/MATLAB/resources/project/root/EEtUlUb-dLAdf0KpMVivaUlztwAp.xml new file mode 100644 index 00000000..c9d8bed8 --- /dev/null +++ b/MATLAB/resources/project/root/EEtUlUb-dLAdf0KpMVivaUlztwAp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml b/MATLAB/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml new file mode 100644 index 00000000..5c3993f4 --- /dev/null +++ b/MATLAB/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml b/MATLAB/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml new file mode 100644 index 00000000..2516b91f --- /dev/null +++ b/MATLAB/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml b/MATLAB/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml new file mode 100644 index 00000000..f12944ef --- /dev/null +++ b/MATLAB/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml b/MATLAB/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml new file mode 100644 index 00000000..67c6ed67 --- /dev/null +++ b/MATLAB/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/rootp.xml b/MATLAB/resources/project/rootp.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/rootp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/uuid-3fc8ea3b-824c-4dcb-9c98-20001c12bf4c.xml b/MATLAB/resources/project/uuid-3fc8ea3b-824c-4dcb-9c98-20001c12bf4c.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/uuid-3fc8ea3b-824c-4dcb-9c98-20001c12bf4c.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/z1WpNcC741vkTKd8uJQQCkdFUWs/GyxYKHEDf7WsdBgs2uwYLalp6hcd.xml b/MATLAB/resources/project/z1WpNcC741vkTKd8uJQQCkdFUWs/GyxYKHEDf7WsdBgs2uwYLalp6hcd.xml new file mode 100644 index 00000000..a75f7a81 --- /dev/null +++ b/MATLAB/resources/project/z1WpNcC741vkTKd8uJQQCkdFUWs/GyxYKHEDf7WsdBgs2uwYLalp6hcd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/z1WpNcC741vkTKd8uJQQCkdFUWs/GyxYKHEDf7WsdBgs2uwYLalp6hcp.xml b/MATLAB/resources/project/z1WpNcC741vkTKd8uJQQCkdFUWs/GyxYKHEDf7WsdBgs2uwYLalp6hcp.xml new file mode 100644 index 00000000..842de6ab --- /dev/null +++ b/MATLAB/resources/project/z1WpNcC741vkTKd8uJQQCkdFUWs/GyxYKHEDf7WsdBgs2uwYLalp6hcp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/resources/project/z1WpNcC741vkTKd8uJQQCkdFUWs/u4W93b5BV505tESL4rEisOMyHjQd.xml b/MATLAB/resources/project/z1WpNcC741vkTKd8uJQQCkdFUWs/u4W93b5BV505tESL4rEisOMyHjQd.xml new file mode 100644 index 00000000..7a6326b9 --- /dev/null +++ b/MATLAB/resources/project/z1WpNcC741vkTKd8uJQQCkdFUWs/u4W93b5BV505tESL4rEisOMyHjQd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/MATLAB/resources/project/z1WpNcC741vkTKd8uJQQCkdFUWs/u4W93b5BV505tESL4rEisOMyHjQp.xml b/MATLAB/resources/project/z1WpNcC741vkTKd8uJQQCkdFUWs/u4W93b5BV505tESL4rEisOMyHjQp.xml new file mode 100644 index 00000000..04b82677 --- /dev/null +++ b/MATLAB/resources/project/z1WpNcC741vkTKd8uJQQCkdFUWs/u4W93b5BV505tESL4rEisOMyHjQp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/MATLAB/Licence.pdf b/MATLAB/tbx/Licence.pdf similarity index 100% rename from MATLAB/Licence.pdf rename to MATLAB/tbx/Licence.pdf diff --git a/MATLAB/tbx/doc/GettingStarted.mlx b/MATLAB/tbx/doc/GettingStarted.mlx new file mode 100644 index 00000000..9f695af7 Binary files /dev/null and b/MATLAB/tbx/doc/GettingStarted.mlx differ diff --git a/MATLAB/addProvider.m b/MATLAB/tbx/sdmx/+sdmx/addProvider.m similarity index 82% rename from MATLAB/addProvider.m rename to MATLAB/tbx/sdmx/+sdmx/addProvider.m index 549e0113..e7a238c1 100644 --- a/MATLAB/addProvider.m +++ b/MATLAB/tbx/sdmx/+sdmx/addProvider.m @@ -1,4 +1,4 @@ -function addProvider(name, endpoint, needsCredentials, needsURLEncoding, supportsCompression, description) +function addProvider(name, endpoint, needsCredentials, needsURLEncoding, supportsCompression, description, sdmxVersion) % Add a new provider to the internal registry. The provider has to be % fully compliant with the SDMX 2.1 specifications % @@ -12,7 +12,8 @@ function addProvider(name, endpoint, needsCredentials, needsURLEncoding, support % needsURLEncoding: set this to true if the provider needs URL encoding % supportsCompression: set this to true if the provider supports stream compression % description: a text description for the provider - % + % sdmxVersion: the sdmx rest api version of the provider (V2 or V3) + % % ############################################################################################# % Copyright 2010,2014 Bank Of Italy % @@ -37,7 +38,7 @@ function addProvider(name, endpoint, needsCredentials, needsURLEncoding, support %deal with arguments - initClasspath; + sdmx.initClasspath; if nargin <2 error(sprintf(['\nUsage: addProvider(name, endpoint, needsCredentials, needsURLEncoding, supportsCompression, description)\n\n' ... @@ -50,6 +51,15 @@ function addProvider(name, endpoint, needsCredentials, needsURLEncoding, support 'description: a brief text description of the provider\n' ... ])); end + if nargin < 7 + sdmxVersion = it.bancaditalia.oss.sdmx.api.SDMXVersion.V2; + else + if(strcmp(sdmxVersion, 'V2')) + sdmxVersion = it.bancaditalia.oss.sdmx.api.SDMXVersion.V2; + else + sdmxVersion = it.bancaditalia.oss.sdmx.api.SDMXVersion.V3; + end + end if nargin < 6 description = ''; end @@ -65,9 +75,9 @@ function addProvider(name, endpoint, needsCredentials, needsURLEncoding, support %try java code try - it.bancaditalia.oss.sdmx.client.SdmxClientHandler.addProvider(name, endpoint, needsCredentials, needsURLEncoding, supportsCompression, description); + it.bancaditalia.oss.sdmx.client.SdmxClientHandler.addProvider(name, endpoint, needsCredentials, needsURLEncoding, supportsCompression, description, sdmxVersion); catch mexp - error(sprintf('SDMX addProvider() error:\n %s', mexp.message)); + error('SDMX addProvider() error:\n %s', mexp.message); end end diff --git a/MATLAB/convert.m b/MATLAB/tbx/sdmx/+sdmx/convert.m similarity index 75% rename from MATLAB/convert.m rename to MATLAB/tbx/sdmx/+sdmx/convert.m index eecb0fa4..f71aee67 100644 --- a/MATLAB/convert.m +++ b/MATLAB/tbx/sdmx/+sdmx/convert.m @@ -115,60 +115,61 @@ function dates = convertDates(freq, dates, iso8601Date) - if(nargin == 3 && iso8601Date == true) - dates = datestr(datetime(dates,'InputFormat','uuuu-MM-dd''T''HH:mm:ss','TimeZone','UTC')); - elseif(strcmp(freq, 'Q')) - dates=regexprep(dates, 'Q1', '03-31'); - dates=regexprep(dates, 'Q2', '06-30'); - dates=regexprep(dates, 'Q3', '09-30'); - dates=regexprep(dates, 'Q4', '12-31'); - dates=(cell2mat(dates)); - elseif(strcmp(freq, 'A')) - dates=strcat(cell2mat(dates), '-12-31'); - elseif(strcmp(freq, 'H')) - dates=regexprep(dates, 'S1', '06-30'); - dates=regexprep(dates, 'S2', '12-31'); - dates=(cell2mat(dates)); - elseif(strcmp(freq, 'W')) - for i = 1 : length(dates) - dates{i} = char(it.bancaditalia.oss.sdmx.util.WeekConverter.convert(dates{i})); - end - dates=(cell2mat(dates)); - else - dates=(cell2mat(dates)); - end +if(nargin == 3 && iso8601Date == true) + dates = string(datetime(dates,'InputFormat','uuuu-MM-dd''T''HH:mm:ss','TimeZone','UTC')); +elseif(strcmp(freq, 'Q')) + dates=regexprep(dates, 'Q1', '03-31'); + dates=regexprep(dates, 'Q2', '06-30'); + dates=regexprep(dates, 'Q3', '09-30'); + dates=regexprep(dates, 'Q4', '12-31'); + dates=(cell2mat(dates)); +elseif(strcmp(freq, 'A')) + dates=strcat(cell2mat(dates), '-12-31'); +elseif(strcmp(freq, 'H')) + dates=regexprep(dates, 'S1', '06-30'); + dates=regexprep(dates, 'S2', '12-31'); + dates=(cell2mat(dates)); +elseif(strcmp(freq, 'W')) + for i = 1 : length(dates) + dates{i} = char(it.bancaditalia.oss.sdmx.util.WeekConverter.convert(dates{i})); + end + dates=(cell2mat(dates)); +else + dates=(cell2mat(dates)); +end + end function metadata = getMetaData(ts) - metadata = containers.Map; + metadata = dictionary; %handle errors if ts.isErrorFlag - metadata('ERROR_FLAG') = true; - metadata('ERROR_MESSAGE') = ts.getErrorMessage; + metadata('ERROR_FLAG') = {true}; + metadata('ERROR_MESSAGE') = {ts.getErrorMessage}; warning('The time series %s is not valid due to errors in the request: %s.', ts.getName, ts.getErrorMessage); end % get all dimensions - tsdims = cell(ts.getDimensionsMap().keySet().toArray()); + tsdims = string(ts.getDimensionsMap().keySet().toArray()); for i=1:length(tsdims) - metadata(tsdims{i}) = char(ts.getDimension(tsdims{i})); + metadata(tsdims(i)) = {string(ts.getDimension(tsdims{i}))}; end % get all ts level attributes - tsattrs = cell(ts.getAttributesMap().keySet().toArray()); + tsattrs = string(ts.getAttributesMap().keySet().toArray()); for i=1:length(tsattrs) - metadata(tsattrs{i}) = char(ts.getAttribute(tsattrs{i})); + metadata(tsattrs(i)) = {string(ts.getAttribute(tsattrs{i}))}; end % get all ts level attributes - obsattrs = cell(ts.getObsLevelAttributesNamesArray); + obsattrs = string(ts.getObsLevelAttributesNamesArray); for i=1:length(obsattrs) - attrval = ts.getObsLevelAttributesArray(obsattrs{i}); + attrval = ts.getObsLevelAttributesArray(obsattrs(i)); if size(attrval) ~= ts.getObservationsArray().size() warning(['Attribute: ', obsattrs{i}, 'is malformed. Skipping.']); else - metadata(obsattrs{i}) = cell(attrval); + metadata(obsattrs(i)) = {string(attrval)}; end end end diff --git a/MATLAB/convertTable.m b/MATLAB/tbx/sdmx/+sdmx/convertTable.m similarity index 100% rename from MATLAB/convertTable.m rename to MATLAB/tbx/sdmx/+sdmx/convertTable.m diff --git a/MATLAB/getCodes.m b/MATLAB/tbx/sdmx/+sdmx/getCodes.m similarity index 91% rename from MATLAB/getCodes.m rename to MATLAB/tbx/sdmx/+sdmx/getCodes.m index 3e2810fe..a3489c01 100644 --- a/MATLAB/getCodes.m +++ b/MATLAB/tbx/sdmx/+sdmx/getCodes.m @@ -31,7 +31,7 @@ % permissions and limitations under the Licence. % -initClasspath; +sdmx.initClasspath; if nargin < 3 error(sprintf(['\nUsage: getCodes(provider, flow, dimension)\n\n' ... @@ -55,8 +55,8 @@ end %create Map -ids = cell(result.keySet.toArray); -description = cell(result.values.toArray); -codes = containers.Map(ids, description); +ids = string(result.keySet.toArray); +description = string(result.values.toArray); +codes = dictionary(ids, description); end diff --git a/MATLAB/getDSDIdentifier.m b/MATLAB/tbx/sdmx/+sdmx/getDSDIdentifier.m similarity index 91% rename from MATLAB/getDSDIdentifier.m rename to MATLAB/tbx/sdmx/+sdmx/getDSDIdentifier.m index d61374a9..42378fe1 100644 --- a/MATLAB/getDSDIdentifier.m +++ b/MATLAB/tbx/sdmx/+sdmx/getDSDIdentifier.m @@ -30,7 +30,7 @@ % permissions and limitations under the Licence. % - initClasspath; + sdmx.initClasspath; if nargin <2 error(sprintf([ '\nUsage: getDSDIdentifier(provider, dataflow)\n\n' ... @@ -41,7 +41,7 @@ end %try java code try - dsd = char(it.bancaditalia.oss.sdmx.client.SdmxClientHandler.getDSDIdentifier(provider, dataflow)); + dsd = string(it.bancaditalia.oss.sdmx.client.SdmxClientHandler.getDSDIdentifier(provider, dataflow)); catch mexp error(['SDMX getDSDIdentifier() error:\n' mexp.message]); end diff --git a/MATLAB/getDimensions.m b/MATLAB/tbx/sdmx/+sdmx/getDimensions.m similarity index 98% rename from MATLAB/getDimensions.m rename to MATLAB/tbx/sdmx/+sdmx/getDimensions.m index 17371fcf..a9c64f30 100644 --- a/MATLAB/getDimensions.m +++ b/MATLAB/tbx/sdmx/+sdmx/getDimensions.m @@ -30,7 +30,7 @@ % permissions and limitations under the Licence. % - initClasspath; + sdmx.initClasspath; if nargin <2 error(sprintf([ '\nUsage: getDimensions(provider, dataflow)\n\n' ... diff --git a/MATLAB/getFlows.m b/MATLAB/tbx/sdmx/+sdmx/getFlows.m similarity index 92% rename from MATLAB/getFlows.m rename to MATLAB/tbx/sdmx/+sdmx/getFlows.m index 662bd045..0ebbd153 100644 --- a/MATLAB/getFlows.m +++ b/MATLAB/tbx/sdmx/+sdmx/getFlows.m @@ -31,7 +31,7 @@ % permissions and limitations under the Licence. % - initClasspath; + sdmx.initClasspath; if nargin == 0 error(sprintf(['\nUsage: getFlows(provider, pattern)\n\n' ... @@ -58,8 +58,8 @@ end %create Map - ids = cell(result.keySet.toArray); - description = cell(result.values.toArray); - flows = containers.Map(ids, description); + ids = string(result.keySet.toArray); + description = string(result.values.toArray); + flows = dictionary(ids, description); end \ No newline at end of file diff --git a/MATLAB/getProviders.m b/MATLAB/tbx/sdmx/+sdmx/getProviders.m similarity index 97% rename from MATLAB/getProviders.m rename to MATLAB/tbx/sdmx/+sdmx/getProviders.m index 38519078..4e520f33 100644 --- a/MATLAB/getProviders.m +++ b/MATLAB/tbx/sdmx/+sdmx/getProviders.m @@ -25,7 +25,7 @@ % permissions and limitations under the Licence. % - initClasspath; + sdmx.initClasspath; try providers = it.bancaditalia.oss.sdmx.client.SdmxClientHandler.getProviders(); diff --git a/MATLAB/getTimeSeries.m b/MATLAB/tbx/sdmx/+sdmx/getTimeSeries.m similarity index 91% rename from MATLAB/getTimeSeries.m rename to MATLAB/tbx/sdmx/+sdmx/getTimeSeries.m index 730d5322..781ad286 100644 --- a/MATLAB/getTimeSeries.m +++ b/MATLAB/tbx/sdmx/+sdmx/getTimeSeries.m @@ -37,7 +37,7 @@ %deal with arguments - initClasspath; + sdmx.initClasspath; if nargin <2 error(sprintf(['\nUsage: getTimeSeriesTable(provider, id, startTime, endTime)\n\n' ... @@ -59,9 +59,9 @@ %try java code try - result = it.bancaditalia.oss.sdmx.client.SdmxClientHandler.getTimeSeries(provider, '', id, '', startTime, endTime, false, '', false); + result = it.bancaditalia.oss.sdmx.client.SdmxClientHandler.getTimeSeries(provider, id, startTime, endTime, false, '', false); catch mexp - error(sprintf('SDMX getTimeSeries() error:\n %s', mexp.message)); + error('SDMX getTimeSeries() error:\n %s', mexp.message); end %verify returned class type @@ -70,7 +70,7 @@ end %convert - list = convert(result); + list = sdmx.convert(result); end diff --git a/MATLAB/getTimeSeriesRevisions.m b/MATLAB/tbx/sdmx/+sdmx/getTimeSeriesRevisions.m similarity index 89% rename from MATLAB/getTimeSeriesRevisions.m rename to MATLAB/tbx/sdmx/+sdmx/getTimeSeriesRevisions.m index 2cdc3e39..f529e046 100644 --- a/MATLAB/getTimeSeriesRevisions.m +++ b/MATLAB/tbx/sdmx/+sdmx/getTimeSeriesRevisions.m @@ -4,7 +4,7 @@ % points updated after a specific date and the history of revisions can % be returned % - % Usage: getTimeSeriesTable(provider, id, startTime, endTime) + % Usage: getTimeSeriesRevisions(provider, id, startTime, endTime, updatedAfter, includeHistory) % % Arguments % @@ -42,7 +42,7 @@ %deal with arguments - initClasspath; + sdmx.initClasspath; if nargin <2 error(sprintf(['\nUsage: getTimeSeriesTable(provider, id, startTime, endTime)\n\n' ... @@ -72,9 +72,9 @@ %try java code try - result = it.bancaditalia.oss.sdmx.client.SdmxClientHandler.getTimeSeriesTable(provider, '', id, '', startTime, endTime, false, updatedAfter, includeHistory); + result = it.bancaditalia.oss.sdmx.client.SdmxClientHandler.getTimeSeriesTable(provider, id, startTime, endTime, false, updatedAfter, includeHistory); catch mexp - error(sprintf('SDMX getTimeSeries() error:\n %s', mexp.message)); + error('SDMX getTimeSeries() error:\n %s', mexp.message); end %verify returned class type @@ -83,7 +83,7 @@ end %convert - tt = convertTable(result); + tt = sdmx.convertTable(result); end diff --git a/MATLAB/getTimeSeriesTable.m b/MATLAB/tbx/sdmx/+sdmx/getTimeSeriesTable.m similarity index 91% rename from MATLAB/getTimeSeriesTable.m rename to MATLAB/tbx/sdmx/+sdmx/getTimeSeriesTable.m index f2d83427..bd589c3d 100644 --- a/MATLAB/getTimeSeriesTable.m +++ b/MATLAB/tbx/sdmx/+sdmx/getTimeSeriesTable.m @@ -38,7 +38,7 @@ %deal with arguments - initClasspath; + sdmx.initClasspath; if nargin <2 error(sprintf(['\nUsage: getTimeSeriesTable(provider, id, startTime, endTime)\n\n' ... @@ -60,9 +60,9 @@ %try java code try - result = it.bancaditalia.oss.sdmx.client.SdmxClientHandler.getTimeSeriesTable(provider, '', id, '', startTime, endTime, false, '', false); + result = it.bancaditalia.oss.sdmx.client.SdmxClientHandler.getTimeSeriesTable(provider, id, startTime, endTime, false, '', false); catch mexp - error(sprintf('SDMX getTimeSeries() error:\n %s', mexp.message)); + error('SDMX getTimeSeries() error:\n %s', mexp.message); end %verify returned class type @@ -71,7 +71,7 @@ end %convert - tt = convertTable(result); + tt = sdmx.convertTable(result); end diff --git a/MATLAB/initClasspath.m b/MATLAB/tbx/sdmx/+sdmx/initClasspath.m similarity index 84% rename from MATLAB/initClasspath.m rename to MATLAB/tbx/sdmx/+sdmx/initClasspath.m index ac48ca1d..9396f394 100644 --- a/MATLAB/initClasspath.m +++ b/MATLAB/tbx/sdmx/+sdmx/initClasspath.m @@ -22,10 +22,10 @@ function initClasspath() jarLoaded = exist('it.bancaditalia.oss.sdmx.helper.SDMXHelper', 'class'); if jarLoaded ~= 8 - mFilesLoaded = exist('sdmxHelp.m', 'file'); + mFilesLoaded = exist('sdmxroot.m', 'file'); if mFilesLoaded == 2 - pathToJar = fileparts(which('sdmxHelp')); - javaaddpath([pathToJar, '/lib/SDMX.jar']); + jar = dir(fullfile(sdmxroot, '/lib/SDMX*.jar')); + javaaddpath(fullfile(jar.folder, jar.name)); else error('Error: the m-files of the MatSDMX toolbox cannot be found in the MATLAB path'); end diff --git a/MATLAB/Contents.m b/MATLAB/tbx/sdmx/Contents.m similarity index 65% rename from MATLAB/Contents.m rename to MATLAB/tbx/sdmx/Contents.m index 2286821c..4cb53b28 100644 --- a/MATLAB/Contents.m +++ b/MATLAB/tbx/sdmx/Contents.m @@ -4,16 +4,16 @@ % % Files % -% getProviders - get the list of available data providers -% addProvider - add a new provider (SDMX 2.1) to the internal registry -% getFlows - get the list of available data flows for the input provider -% getDimensions - get the list of dimensions for the input dataflow -% getDSDIdentifier - get the name of the DSD for the input dataflow -% getTimeSeries - get the list of time series that match the input query +% sdmx.getProviders - get the list of available data providers +% sdmx.addProvider - add a new provider (SDMX 2.1) to the internal registry +% sdmx.getFlows - get the list of available data flows for the input provider +% sdmx.getDimensions - get the list of dimensions for the input dataflow +% sdmx.getDSDIdentifier - get the name of the DSD for the input dataflow +% sdmx.getTimeSeries - get the list of time series that match the input query % and return a cell of timeseries -% getTimeSeriesTable - get the list of time series that match the input query +% sdmx.getTimeSeriesTable - get the list of time series that match the input query % and return a table -% getTimeSeriesRevisions - get the list of time series that match the input query +% sdmx.getTimeSeriesRevisions - get the list of time series that match the input query % and return a table. Revisions in observation values are returned too. % sdmxtable - converts the results of the getTimeSeries call from a cell % array of timeseries to a table @@ -39,4 +39,4 @@ % express or implied. % See the Licence for the specific language governing % permissions and limitations under the Licence. -% +% \ No newline at end of file diff --git a/MATLAB/sdmxHelp.m b/MATLAB/tbx/sdmx/sdmxHelp.m similarity index 97% rename from MATLAB/sdmxHelp.m rename to MATLAB/tbx/sdmx/sdmxHelp.m index 3852cd5d..0f0244c1 100644 --- a/MATLAB/sdmxHelp.m +++ b/MATLAB/tbx/sdmx/sdmxHelp.m @@ -25,7 +25,7 @@ function sdmxHelp() % permissions and limitations under the Licence. % - initClasspath; + sdmx.initClasspath; %try java code try diff --git a/MATLAB/tbx/sdmx/sdmxroot.m b/MATLAB/tbx/sdmx/sdmxroot.m new file mode 100644 index 00000000..66a76363 --- /dev/null +++ b/MATLAB/tbx/sdmx/sdmxroot.m @@ -0,0 +1,8 @@ +function root = sdmxroot() + +arguments (Output) + root (1,1) string +end + +root = fileparts(fileparts(mfilename('fullpath'))); + diff --git a/MATLAB/sdmxtable.m b/MATLAB/tbx/sdmx/sdmxtable.m similarity index 91% rename from MATLAB/sdmxtable.m rename to MATLAB/tbx/sdmx/sdmxtable.m index ec17c3b9..929c556e 100644 --- a/MATLAB/sdmxtable.m +++ b/MATLAB/tbx/sdmx/sdmxtable.m @@ -58,7 +58,7 @@ tableList = cell(1, tsNumber); % retieve all attribute names in all time series - allVariables = containers.Map; + allVariables = dictionary; if meta == true % add metadata entries too for i = 1:tsNumber @@ -78,7 +78,7 @@ end nobs = length(tslist{i}.Data); varNames = cell({'ID', 'TIME_PERIOD', 'OBS_VALUE'}); - varValues = cell({cellstr(repmat(tslist{i}.Name, [nobs 1])), ... + varValues = cell({string(repmat(tslist{i}.Name, [nobs 1])), ... tslist{i}.getabstime, ... tslist{i}.Data}); @@ -86,17 +86,17 @@ if meta == true keys = allVariables.keys; for j = 1:length(keys) - key = keys{j}; + key = keys(j); try - value = tslist{i}.UserData(key); - catch exception + value = tslist{i}.UserData{key}; + catch % attribute not present, set empty value = ''; end % check if this is a ts level attribute. If so, repeat it % for every observation - if ~iscell(value) + if ~iscell(value) && numel(value) ~= nobs if isempty(value) % workaround... value = cellstr(repmat({''}, [nobs 1])); @@ -104,7 +104,8 @@ value = cellstr(repmat(value, [nobs 1])); end end - varNames{3 + j} = key; + + varNames{3 + j} = char(key); varValues{3 + j} = value; % now add the variable to the global list @@ -120,7 +121,7 @@ tstable = cell2table(cell(0, length(varNames))); tstable.Properties.VariableNames = varNames; for i = 1:length(tableList) - tstable = [tstable; tableList{i}]; + tstable = [tstable; tableList{i}]; %#ok end end diff --git a/MATLAB/test/testSDMX.m b/MATLAB/test/testSDMX.m deleted file mode 100644 index f927d482..00000000 --- a/MATLAB/test/testSDMX.m +++ /dev/null @@ -1,44 +0,0 @@ - -% Simple script for UNIT TEST purposes -% -% ############################################################################################# -% Copyright 2010,2014 Bank Of Italy -% -% Licensed under the EUPL, Version 1.1 or as soon as 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. -% - -%% Test 1: getProviders -providers = getProviders; -assert(length(providers) > 1, 'Error getProviders'); - -%% Test 2: getFlows -flows = getFlows('ECB'); -assert(length(flows) > 1, 'Error flow number'); -assert(strcmp(flows('ECB,EXR,1.0'), 'Exchange Rates'), 'Error flow names'); - -%% Test 3: getDimensions -dims = getDimensions('ECB', 'EXR'); -assert(length(dims) == 5), 'Error dimension number'; -assert(strcmp(dims{1}, 'FREQ'), 'Error dimension names'); - -%% Test 4: getTimeSeries -tts = getTimeSeries('ECB', 'EXR.M.USD|GBP.EUR.SP00.A'); -assert(length(tts) == 2, 'Error getTimeseries'); - - diff --git a/MATLAB/tests/testSDMX.m b/MATLAB/tests/testSDMX.m new file mode 100644 index 00000000..8b452055 --- /dev/null +++ b/MATLAB/tests/testSDMX.m @@ -0,0 +1,151 @@ +classdef testSDMX < matlab.unittest.TestCase + % Simple script for UNIT TEST purposes + % + % ############################################################################################# + % Copyright 2010,2014 Bank Of Italy + % + % Licensed under the EUPL, Version 1.1 or as soon as 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. + % + + methods (Test) + + function tGetProviders(tc) + % Test 1: getProviders + providers = sdmx.getProviders; + tc.verifyNotEmpty(providers) + end + + function tGetFlows(tc) + % Test 2: getFlows + flows = sdmx.getFlows('ECB'); + tc.verifyNotEmpty(flows) + tc.verifyEqual(flows('ECB,EXR,1.0'), "Exchange Rates") + end + + function tGetDimensions(tc) + % Test 3: getDimensions + dims = sdmx.getDimensions('ECB', 'EXR'); + tc.verifyLength(dims, 5); + tc.verifyEqual(dims{1}, 'FREQ'); + end + + function tGetTimeSeries(tc) + % Test 4: getTimeSeries + tts = sdmx.getTimeSeries('ECB', 'EXR.M.USD|GBP.EUR.SP00.A'); + tc.verifyLength(tts, 2) + + tts = sdmx.getTimeSeries('EUROSTAT_COMP', 'AID_MARE/A.CY.'); + tc.verifyLength(tts, 3) + tb = sdmxtable(tts, true); + tc.verifyClass(tb, 'table') + + tts = sdmx.getTimeSeries('ISTAT','101_1039.A.001004.ALL.NUMAGRIAUTH'); + tc.verifyLength(tts, 1) + tb = sdmxtable(tts); + tc.verifyClass(tb, 'table') + + tts = sdmx.getTimeSeries('ECB','IEAF.Q.SK.N.V.D92.Z.S2.A1.S.2.X.N.Z'); + tc.verifyLength(tts, 1) + tb = sdmxtable(tts, true); + tc.verifyClass(tb, 'table') + + tts = sdmx.getTimeSeries('ECB', 'BKN/H.AT.A020.....'); + tc.verifyLength(tts, 1) + tb = sdmxtable(tts, true); + tc.verifyClass(tb, 'table') + + end + + function tGetTimeSeriesTable(tc) + % Test 5: getTimeSeriesTable + tb = sdmx.getTimeSeriesTable('ECB', 'EXR.M.USD|GBP.EUR.SP00.A'); + tc.verifyClass(tb, 'table') + + tb = sdmx.getTimeSeriesTable('ECB', 'EXR.M.USD.EUR.SP00.A'); + tc.verifyClass(tb, 'table') + + startTime = datetime(1995,1,1, 'Format','yyyy-MM-dd'); + endTime = datetime(2005,1,1, 'Format','yyyy-MM-dd'); + + tb = sdmx.getTimeSeriesTable('ECB', 'EXR.M.USD.EUR.SP00.A', string(startTime), string(endTime)); + tb.TIME_PERIOD = datetime(tb.TIME_PERIOD, 'InputFormat','uuuu-MM', 'Format','uuuu-MM'); + + tc.verifyLessThan(tb.TIME_PERIOD, endTime); + tc.verifyGreaterThanOrEqual(tb.TIME_PERIOD, startTime) + end + + function tGetTimeSeriesRevisions(tc) + % Test 6: getTimeSeriesRevisions + + startTime = datetime(1995,1,1, 'Format','yyyy-MM-dd'); + endTime = datetime(2005,1,1, 'Format','yyyy-MM-dd'); + + tb = sdmx.getTimeSeriesRevisions('ECB', 'EXR.M.USD.EUR.SP00.A', string(startTime), string(endTime)); + tb.TIME_PERIOD = datetime(tb.TIME_PERIOD, 'InputFormat','uuuu-MM', 'Format','uuuu-MM'); + + tc.verifyLessThan(tb.TIME_PERIOD, endTime); + tc.verifyGreaterThanOrEqual(tb.TIME_PERIOD, startTime) + + startTime = datetime(2002,1,1, 'Format','yyyy-MM-dd'); + tb = sdmx.getTimeSeriesRevisions('ECB', 'EXR.M.USD.EUR.SP00.A', string(startTime), string(endTime), '', true); + tb.TIME_PERIOD = datetime(tb.TIME_PERIOD, 'InputFormat','uuuu-MM', 'Format','uuuu-MM'); + tc.verifyClass(tb, 'table'); + tc.verifyLessThan(tb.TIME_PERIOD, endTime); + tc.verifyGreaterThanOrEqual(tb.TIME_PERIOD, startTime) + + tb = sdmx.getTimeSeriesRevisions('ECB', 'EXR.M.USD.EUR.SP00.A', string(startTime), string(endTime), '2003-01-01', true); + tb.TIME_PERIOD = datetime(tb.TIME_PERIOD, 'InputFormat','uuuu-MM', 'Format','uuuu-MM'); + tc.verifyClass(tb, 'table'); + tc.verifyLessThan(tb.TIME_PERIOD, endTime); + tc.verifyGreaterThanOrEqual(tb.TIME_PERIOD, startTime) + end + + + function tAddProvider(tc) + % Test 7: addProvider + + sdmx.addProvider('ECB_TEST', 'http://sdw-wsrest.ecb.europa.eu/service', false, false, false, 'Sample ECB provider'); + providers = sdmx.getProviders; + tc.verifyTrue(any(contains(providers, 'ECB_TEST'))) + end + + function tGetCodes(tc) + % Test 8: getCodes + + map = sdmx.getCodes('ECB','ECB,EXR,1.0', 'FREQ'); + tc.verifyEqual(map('A'), "Annual") + end + + function tGetDSDIdentifier(tc) + % Test 9: getDSDIdentifier + + id = sdmx.getDSDIdentifier('ECB','ECB,EXR,1.0'); + tc.verifyEqual(id, "ECB/ECB_EXR1/1.0") + end + + function tGetSDMXTable(tc) + % Test 10: getSDMXTable + + tts = sdmx.getTimeSeries('ECB', 'EXR.M.USD|GBP.EUR.SP00.A'); + tb = sdmxtable(tts, true); + tc.verifyClass(tb, 'table') + end + end + +end \ No newline at end of file diff --git a/RJSDMX/inst/java/SDMX.jar b/RJSDMX/inst/java/SDMX.jar index ca3f905e..b5a7e2b6 100644 Binary files a/RJSDMX/inst/java/SDMX.jar and b/RJSDMX/inst/java/SDMX.jar differ diff --git a/STATA/jar/SDMX.jar b/STATA/jar/SDMX.jar index 3619ba60..06f6dd67 100644 Binary files a/STATA/jar/SDMX.jar and b/STATA/jar/SDMX.jar differ