Merge pull request 'without_jackan' (#1) from without_jackan into master

This commit is contained in:
Francesco Mangiacrapa 2021-02-11 11:20:09 +01:00
commit ff3b7db51f
44 changed files with 6992 additions and 316 deletions

50
pom.xml
View File

@ -12,7 +12,7 @@
<groupId>org.gcube.datacatalogue</groupId>
<artifactId>catalogue-util-library</artifactId>
<version>0.1.0-SNAPSHOT</version>
<version>0.2.0-SNAPSHOT</version>
<name>Ckan utility library</name>
<description>
@ -27,11 +27,11 @@
<properties>
<serviceClass>data-catalogue</serviceClass>
<jackanVersion>0.4.2</jackanVersion>
<postgresVersion>9.4.1208.jre7</postgresVersion>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<gwtVersion>2.7.0</gwtVersion>
<apache.http.version>4.4.1</apache.http.version>
</properties>
<dependencyManagement>
@ -39,7 +39,7 @@
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>maven-portal-bom</artifactId>
<version>LATEST</version>
<version>3.6.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -53,12 +53,40 @@
<scope>provided</scope>
</dependency>
<!-- CKAN client library -->
<dependency>
<groupId>eu.trentorise.opendata</groupId>
<artifactId>jackan</artifactId>
<version>${jackanVersion}</version>
<scope>compile</scope>
<groupId>org.gcube.common</groupId>
<artifactId>gcube-jackson-core</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>gcube-jackson-annotations</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>gcube-jackson-databind</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<version>${apache.http.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4.1</version>
</dependency>
<dependency>
@ -68,9 +96,9 @@
</dependency>
<dependency>
<groupId>org.gcube.data-publishing</groupId>
<groupId>org.gcube.data-catalogue</groupId>
<artifactId>gcat-client</artifactId>
<version>[1.0.0, 2.0.0)</version>
<version>[2.0.0-SNAPSHOT, 3.0.0)</version>
<scope>compile</scope>
</dependency>
@ -121,11 +149,13 @@
<artifactId>json-simple</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>[4.10.2,5.0.0)</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>

View File

@ -11,21 +11,22 @@ import java.util.Map;
import javax.annotation.Nullable;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.fluent.Response;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.datacatalogue.ckanutillibrary.jackan.CkanClient;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanGroup;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanOrganization;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanResponse;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions.CkanException;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions.JackanException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Charsets;
import com.google.common.io.CharStreams;
import eu.trentorise.opendata.jackan.CkanClient;
import eu.trentorise.opendata.jackan.exceptions.CkanException;
import eu.trentorise.opendata.jackan.exceptions.JackanException;
import eu.trentorise.opendata.jackan.internal.org.apache.http.client.fluent.Request;
import eu.trentorise.opendata.jackan.internal.org.apache.http.client.fluent.Response;
import eu.trentorise.opendata.jackan.model.CkanGroup;
import eu.trentorise.opendata.jackan.model.CkanOrganization;
import eu.trentorise.opendata.jackan.model.CkanResponse;
/**

View File

@ -2,14 +2,14 @@ package org.gcube.datacatalogue.ckanutillibrary.ckan;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.com.fasterxml.jackson.core.JsonParseException;
import org.gcube.com.fasterxml.jackson.core.JsonProcessingException;
import org.gcube.com.fasterxml.jackson.databind.JsonMappingException;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanDataset;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanGroup;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanResource;
import eu.trentorise.opendata.jackan.model.CkanDataset;
import eu.trentorise.opendata.jackan.model.CkanGroup;
import eu.trentorise.opendata.jackan.model.CkanResource;
/**
@ -98,11 +98,13 @@ public class MarshUnmarshCkanObject {
* To json value resource.
*
* @param resource the resource
* @param method the method
* @return the string
* @throws JsonProcessingException the json processing exception
*/
public static String toJsonValueResource(CkanResource resource) throws JsonProcessingException{
return ExtendCkanClient.getObjectMapper().writeValueAsString(resource);
public static String toJsonValueResource(CkanResource resource, METHOD method) throws JsonProcessingException{
ObjectMapper om = getObjectMapper(method, CkanResource.class);
return om.writeValueAsString(resource);
}

View File

@ -1,11 +1,11 @@
package org.gcube.datacatalogue.ckanutillibrary.ckan;
import eu.trentorise.opendata.jackan.CkanClient;
import eu.trentorise.opendata.jackan.exceptions.CkanException;
import eu.trentorise.opendata.jackan.exceptions.JackanException;
import eu.trentorise.opendata.jackan.model.CkanGroup;
import eu.trentorise.opendata.jackan.model.CkanOrganization;
import eu.trentorise.opendata.jackan.model.CkanResponse;
import org.gcube.datacatalogue.ckanutillibrary.jackan.CkanClient;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanGroup;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanOrganization;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanResponse;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions.CkanException;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions.JackanException;
/**
* The Interface PatchedCkan.

View File

@ -0,0 +1,285 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.jackan;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.gcube.datacatalogue.ckanutillibrary.server.utils.GenericUtils.checkNotEmpty;
import static org.gcube.datacatalogue.ckanutillibrary.server.utils.GenericUtils.isNotEmpty;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;
import java.util.UUID;
import javax.annotation.Nullable;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanDataset;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanDatasetBase;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanGroup;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanLicense;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanOrganization;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanResource;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanResourceBase;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions.CkanNotFoundException;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions.CkanValidationException;
/**
* This client performs additional checks when writing to CKAN to ensure written
* content is correct. For this reason it might do additional calls and results
* of validation might be different from default Ckan ones. But if Ckan actually
* performed all the checks it should do there wouldn't be any need of this
* class as well..
*
* <p>
* Note: For {@code create} operations, this client fails if item is already
* existing on the server. This behaviour is different from ckan default
* {@code upsert} behaviour (update an existing) to prevent misuse.
* </p>
*
* @author David Leoni
* @since 0.4.1
*/
public class CheckedCkanClient extends CkanClient {
protected CheckedCkanClient() {
super();
}
protected CheckedCkanClient(String url) {
super(url);
}
public CheckedCkanClient(String catalogUrl, @Nullable String ckanToken) {
super(catalogUrl, ckanToken);
}
/**
* Returns a builder instance. The builder is not threadsafe and you can use
* one builder instance to build only one client instance.
*/
public static CkanClient.Builder builder() {
return CkanClient.newBuilder(new CheckedCkanClient());
}
private void checkUrl(String url, String prependedErrorMessage) {
try {
new URL(url).toURI();
} catch (MalformedURLException | URISyntaxException ex) {
throw new CkanValidationException(String.valueOf(prependedErrorMessage) + " -- Ill-formed url:" + url, this,
ex);
}
}
private void checkUuid(String uuid, String prependedErrorMessage) {
try {
UUID.fromString(uuid);
} catch (Exception ex) {
throw new CkanValidationException(String.valueOf(prependedErrorMessage) + " -- Ill-formed uuid:" + uuid,
this, ex);
}
}
/**
* {@inheritDoc}
*
* <p>
* NOTE: In CheckedCkanClient {@code create} operations fail if item already
* exists. This is different from Ckan default behaviour, which updates
* items if they already exist.
* </p>
*/
@Override
public synchronized CkanOrganization createOrganization(CkanOrganization org) {
if (org.getId() != null) {
checkUuid(org.getId(),
"Jackan validation failed! Tried to create organization with invalid id:" + org.getId());
try {
getOrganization(org.getId());
throw new CkanValidationException(
"Jackan validation failed! Tried to create organization with existing id! " + org.getId(),
this);
} catch (CkanNotFoundException ex) {
}
}
return super.createOrganization(org);
}
/**
* {@inheritDoc}
*
* <p>
* NOTE: In CheckedCkanClient {@code create} operations fail if item already
* exists. This is different from Ckan default behaviour, which updates
* items if they already exist.
* </p>
*/
@Override
public synchronized CkanResource createResource(CkanResourceBase resource) {
if (resource.getId() != null) {
checkUuid(resource.getId(),
"Jackan validation failed! Tried to create resource with invalid id:" + resource.getId());
try {
getResource(resource.getId());
throw new CkanValidationException(
"Jackan validation failed! Tried to create resource with existing id! " + resource.getId(),
this);
} catch (CkanNotFoundException ex) {
}
}
// Only check for URL if no file is given
// If a file is given, the URL field is statically set to "upload"
if (resource.getUpload() == null)
checkUrl(resource.getUrl(),
"Jackan validation error! Tried to create resource " + resource.getId() + " with wrong url!");
return super.createResource(resource);
}
@Override
public synchronized CkanResource updateResource(CkanResourceBase resource) {
checkUrl(resource.getUrl(),
"Jackan validation error! Tried to update resource " + resource.getId() + " with wrong url!");
return super.updateResource(resource);
}
@Override
public synchronized CkanResource patchUpdateResource(CkanResourceBase resource) {
checkUrl(resource.getUrl(),
"Jackan validation error! Tried to patch update resource " + resource.getId() + " with wrong url!");
return super.patchUpdateResource(resource);
}
/**
* {@inheritDoc}
*
* <p>
* NOTE: In CheckedCkanClient {@code create} operations fail if item already
* exists. This is different from Ckan default behaviour, which updates
* items if they already exist.
* </p>
*/
@Override
public synchronized CkanGroup createGroup(CkanGroup group) {
if (group.getId() != null) {
checkUuid(group.getId(),
"Jackan validation failed! Tried to create group with invalid id:" + group.getId());
try {
getGroup(group.getId());
throw new CkanValidationException(
"Jackan validation failed! Tried to create group with existing id! " + group.getId(), this);
} catch (CkanNotFoundException ex) {
}
}
return super.createGroup(group);
}
private void checkGroupsExist(Iterable<CkanGroup> groups, String prependedErrorMessage) {
if (groups != null) {
for (CkanGroup group : groups) {
checkNotNull(group, String.valueOf(prependedErrorMessage) + " -- Found null group! ");
checkNotEmpty(group.idOrName(),
String.valueOf(prependedErrorMessage) + " -- Found group with both id and name invalid!");
try {
getGroup(group.idOrName());
} catch (CkanNotFoundException ex) {
throw new CkanValidationException(
prependedErrorMessage + " -- Tried to refer to non existing group " + group.idOrName(),
this, ex);
}
}
}
}
private void checkLicenseExist(@Nullable String licenseId, String prependedErrorMessage) {
if (isNotEmpty(licenseId)) {
List<CkanLicense> licenseList = getLicenseList();
boolean found = false;
for (CkanLicense lic : licenseList) {
if (licenseId.equals(lic.getId())) {
found = true;
break;
}
}
if (!found) {
throw new CkanValidationException(String.valueOf(prependedErrorMessage) + " -- licenseId '" + licenseId
+ "' doesn't belong to allowed licenses: " + licenseList.toString(), this);
}
}
}
/**
* {@inheritDoc}
*
* <p>
* NOTE: In CheckedCkanClient {@code create} operations fail if item already
* exists. This is different from Ckan default behaviour, which updates
* items if they already exist.
* </p>
*/
@Override
public synchronized CkanDataset createDataset(CkanDatasetBase dataset) {
checkGroupsExist(dataset.getGroups(), "Jackan validation error when creating dataset " + dataset.getName());
checkLicenseExist(dataset.getLicenseId(), "Jackan validation error when creating dataset " + dataset.getName());
return super.createDataset(dataset);
}
@Override
public synchronized CkanDataset updateDataset(CkanDatasetBase dataset) {
checkGroupsExist(dataset.getGroups(), "Jackan validation error when updating dataset " + dataset.getName());
checkLicenseExist(dataset.getLicenseId(), "Jackan validation error updating dataset " + dataset.getName());
return super.updateDataset(dataset);
}
@Override
public synchronized CkanDataset patchUpdateDataset(CkanDatasetBase dataset) {
checkGroupsExist(dataset.getGroups(),
"Jackan validation error when patch updating dataset " + dataset.getName());
checkLicenseExist(dataset.getLicenseId(),
"Jackan validation error when patch updating dataset " + dataset.getName());
return super.patchUpdateDataset(dataset);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,143 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.jackan;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.google.common.collect.Lists;
/**
* Usage example: {@code
* CkanQuery.filter().byText("litigations").byGroupNames("justice")
* }
*
* @author David Leoni
*/
public final class CkanQuery {
private String text;
private List<String> groupNames;
private List<String> organizationNames;
private List<String> tagNames;
private List<String> licenseIds;
private CkanQuery() {
this.text = "";
this.groupNames = new ArrayList();
this.organizationNames = new ArrayList();
this.tagNames = new ArrayList();
this.licenseIds = new ArrayList();
}
/**
* Each filtered dataset must belong to all the given groups i.e.
* "british-academy", "home-office", "newcastle-city-council"
*/
public CkanQuery byGroupNames(Iterable<String> groupNames) {
this.groupNames = Lists.newArrayList(groupNames);
return this;
}
/**
* Each filtered dataset must belong to all the given groups i.e.
* "british-academy", "home-office", "newcastle-city-council"
*/
public CkanQuery byGroupNames(String... groupNames) {
this.groupNames = Arrays.asList(groupNames);
return this;
}
/**
* @param text i.e. "health care London"
*/
public CkanQuery byText(String text) {
this.text = text;
return this;
}
/**
* Each filtered dataset must belong to the given organization
*
* @param organizationName i.e. "audit-commission",
* "remploy-limited","royal-society"
*/
public CkanQuery byOrganizationName(String organizationName) {
this.organizationNames = Lists.newArrayList(organizationName);
return this;
}
/**
* Each filtered dataset must have all the given tags
*
* @param tagNames i.e. "Community health partnership", "youth-justice",
* "trade-policy",
*/
public CkanQuery byTagNames(Iterable<String> tagNames) {
this.tagNames = Lists.newArrayList(tagNames);
return this;
}
/**
* Each filtered dataset must have all the given tags
*
* @param tagNames i.e. "Community health partnership", "youth-justice",
* "trade-policy",
*/
public CkanQuery byTagNames(String... tagNames) {
this.tagNames = Arrays.asList(tagNames);
return this;
}
/**
* Each filtered dataset must have the given license
*
* @param licenseId i.e. "cc-by", "odc-by"
*/
public CkanQuery byLicenseId(String licenseId) {
this.licenseIds = Lists.newArrayList(licenseId);
return this;
}
/**
* Factory method to start creating the query.
*/
public static CkanQuery filter() {
return new CkanQuery();
}
public String getText() {
return text;
}
public List<String> getGroupNames() {
return groupNames;
}
public List<String> getOrganizationNames() {
return organizationNames;
}
public List<String> getTagNames() {
return tagNames;
}
public List<String> getLicenseIds() {
return licenseIds;
}
}

View File

@ -0,0 +1,135 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.jackan;
import static org.gcube.datacatalogue.ckanutillibrary.jackan.CkanClient.formatTimestamp;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import org.gcube.com.fasterxml.jackson.core.JsonGenerator;
import org.gcube.com.fasterxml.jackson.core.JsonParser;
import org.gcube.com.fasterxml.jackson.core.JsonToken;
import org.gcube.com.fasterxml.jackson.core.type.TypeReference;
import org.gcube.com.fasterxml.jackson.databind.DeserializationContext;
import org.gcube.com.fasterxml.jackson.databind.JsonDeserializer;
import org.gcube.com.fasterxml.jackson.databind.PropertyNamingStrategy;
import org.gcube.com.fasterxml.jackson.databind.SerializerProvider;
import org.gcube.com.fasterxml.jackson.databind.module.SimpleModule;
import org.gcube.com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanDataset;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Custom Jackson module to serialize/deserialize as JSON Ckan objects with
* fields lower cased (i.e. 'author_email') and also Timestamp, which in Ckan
* has format like "2013-11-11T04:12:11.110868", see
* {@link CkanClient#CKAN_TIMESTAMP_PATTERN}. In case there are problems in
* parsing deserializes them to null.
*
* NOTE: We made a custom module because when reading dates, Jackson defaults to
* using GMT for all processing unless specifically told otherwise, see
* < href="http://wiki.fasterxml.com/JacksonFAQTimestampHandling" target="_blank">Jackson
* FAQ</a>. When writing dates, Jackson would also add a Z for timezone and add
* +1 for GMT, which we don't want.
*
* @author David Leoni
* @since 0.4.1
*/
public class JackanModule extends SimpleModule {
private static final Logger LOG = LoggerFactory.getLogger(JackanModule.class.getName());
public JackanModule() {
setNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
addSerializer(Timestamp.class, new StdSerializer<Timestamp>(Timestamp.class) {
@Override
public void serialize(Timestamp value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
try {
String str = formatTimestamp(value);
jgen.writeString(str);
}
catch (Exception ex) {
LOG.warn("Couldn't format timestamp " + value + ", writing 'null'", ex);
jgen.writeNull();
}
}
});
addDeserializer(Timestamp.class, new JsonDeserializer<Timestamp>() {
@Override
public Timestamp deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_STRING) {
String str = jp.getText().trim();
try {
return CkanClient.parseTimestamp(str);
}
catch (IllegalArgumentException ex) {
LOG.warn("Couldn't parse timestamp " + str + ", returning null", ex);
return null;
}
}
if (t == JsonToken.VALUE_NULL) {
return null;
}
LOG.warn("Unrecognized json token for timestamp {0}, returning null", t.asString());
return null;
}
});
}
/**
* group org packages sometimes are arrays, sometimes numbers. If a number
* is found null is returned.
*/
public static class GroupOrgPackagesDeserializer extends JsonDeserializer<List<CkanDataset>> {
private static final Logger LOG = LoggerFactory.getLogger(GroupOrgPackagesDeserializer.class.getName());
@Override
public List<CkanDataset> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NUMBER_INT) {
return null;
}
if (t == JsonToken.START_ARRAY) {
return jp.readValueAs(new TypeReference<List<CkanDataset>>() {
});
}
LOG.warn("Unrecognized token {0} for 'packages' field, returning an empty array.", t.asString());
return new ArrayList();
}
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.jackan;
import java.util.List;
import javax.annotation.concurrent.Immutable;
/**
*
* @author David Leoni
* @param <T> the type of the results
*/
@Immutable
public class SearchResults<T> {
private int count;
private List<T> results;
/**
* @param count The number of matches on the server, which may be greater
* than the search results.
*/
public SearchResults(List<T> results, int count) {
this.count = count;
this.results = results;
}
private SearchResults() {
}
/**
* Returns the number of matches on the server, which may be greater than
* the search results.
*/
public int getCount() {
return count;
}
public List<T> getResults() {
return results;
}
}

View File

@ -6,11 +6,12 @@ import java.util.Map;
import org.gcube.datacatalogue.ckanutillibrary.shared.LandingPages;
import org.gcube.datacatalogue.ckanutillibrary.shared.ResourceBean;
import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanDataset;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanGroup;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanLicense;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanOrganization;
import eu.trentorise.opendata.jackan.model.CkanDataset;
import eu.trentorise.opendata.jackan.model.CkanGroup;
import eu.trentorise.opendata.jackan.model.CkanLicense;
import eu.trentorise.opendata.jackan.model.CkanOrganization;
/**
* The Interface DataCatalogue.
@ -110,7 +111,7 @@ public interface DataCatalogue {
* Retrieve a ckan dataset given its id.
*
* @param datasetId the dataset id
* @param apiKey the api key
* @param apiKey the api key. If null uses gCat to get the Dataset
* @return the dataset
*/
CkanDataset getDataset(String datasetId, String apiKey);

View File

@ -10,7 +10,16 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.common.scope.impl.ScopeBean.Type;
import org.gcube.datacatalogue.ckanutillibrary.ckan.ExtendCkanClient;
@ -21,30 +30,24 @@ import org.gcube.datacatalogue.ckanutillibrary.gcat.GCatCaller;
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueRunningCluster.ACCESS_LEVEL_TO_CATALOGUE_PORTLET;
import org.gcube.datacatalogue.ckanutillibrary.server.utils.CKANConveter;
import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods;
import org.gcube.datacatalogue.ckanutillibrary.server.utils.GCubeUtils;
import org.gcube.datacatalogue.ckanutillibrary.server.utils.GCubeUtils.GCUBE_SCOPE_LEVEL;
import org.gcube.datacatalogue.ckanutillibrary.server.utils.url.EntityContext;
import org.gcube.datacatalogue.ckanutillibrary.shared.LandingPages;
import org.gcube.datacatalogue.ckanutillibrary.shared.ResourceBean;
import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg;
import org.gcube.datacatalogue.ckanutillibrary.shared.State;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanDataset;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanGroup;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanLicense;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanOrganization;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanResource;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanUser;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions.JackanException;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import eu.trentorise.opendata.jackan.exceptions.JackanException;
import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpResponse;
import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpStatus;
import eu.trentorise.opendata.jackan.internal.org.apache.http.client.methods.HttpPost;
import eu.trentorise.opendata.jackan.internal.org.apache.http.entity.ContentType;
import eu.trentorise.opendata.jackan.internal.org.apache.http.entity.StringEntity;
import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.CloseableHttpClient;
import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.HttpClientBuilder;
import eu.trentorise.opendata.jackan.internal.org.apache.http.util.EntityUtils;
import eu.trentorise.opendata.jackan.model.CkanDataset;
import eu.trentorise.opendata.jackan.model.CkanGroup;
import eu.trentorise.opendata.jackan.model.CkanLicense;
import eu.trentorise.opendata.jackan.model.CkanOrganization;
import eu.trentorise.opendata.jackan.model.CkanResource;
import eu.trentorise.opendata.jackan.model.CkanUser;
/**
* This is the Ckan Utils implementation class.
@ -213,7 +216,7 @@ public class DataCatalogueImpl implements DataCatalogue {
LOG.debug("Request for CKAN licenses");
// get the url and the api key of the user
List<String> result = new ArrayList<String>();
//retrieve the list of available licenses
// retrieve the list of available licenses
List<CkanLicense> licenses = ckanCaller.getLicenseList();
for (CkanLicense ckanLicense : licenses) {
@ -229,10 +232,17 @@ public class DataCatalogueImpl implements DataCatalogue {
@Override
public List<CkanLicense> getLicenses() {
LOG.debug("Request for CKAN licenses (original jackan objects are going to be retrieved)");
//retrieve the list of available licenses
// retrieve the list of available licenses
return ckanCaller.getLicenseList();
}
/*
* (non-Javadoc)
*
* @see
* org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue#getDataset(java.
* lang.String, java.lang.String)
*/
@Override
public CkanDataset getDataset(String datasetId, String apiKey) {
LOG.info("Request ckan dataset with id " + datasetId);
@ -241,25 +251,25 @@ public class DataCatalogueImpl implements DataCatalogue {
checkNotNull(datasetId);
checkArgument(!datasetId.isEmpty());
try{
if(apiKey!=null && !apiKey.isEmpty()) {
LOG.info("API-KEY found. Calling the "+ExtendCkanClient.class.getSimpleName());
try {
if (apiKey != null && !apiKey.isEmpty()) {
LOG.info("API-KEY found. Calling the " + ExtendCkanClient.class.getSimpleName());
ExtendCkanClient client = new ExtendCkanClient(CKAN_CATALOGUE_URL, apiKey);
return client.getDataset(datasetId);
}
String authzToken = SecurityTokenProvider.instance.get();
if(authzToken!=null && !authzToken.isEmpty()) {
if (authzToken != null && !authzToken.isEmpty()) {
LOG.info("gcube-token found. Calling the gCat client");
String jsonDataset = gCatCaller.getDatasetForName(datasetId);
return MarshUnmarshCkanObject.toCkanDataset(jsonDataset, METHOD.TO_READ);
}
LOG.info("No api-key or gcube-token found. Calling Ckan Client without API-KEY");
return ckanCaller.getDataset(datasetId);
}catch(Exception e){
} catch (Exception e) {
LOG.error("Unable to retrieve such dataset, returning null ...", e);
}
@ -275,42 +285,42 @@ public class DataCatalogueImpl implements DataCatalogue {
checkNotNull(datasetIdOrName);
checkArgument(!datasetIdOrName.isEmpty());
String url = null;
try{
try {
// get the dataset from name
ExtendCkanClient client = new ExtendCkanClient(CKAN_CATALOGUE_URL, CKAN_TOKEN_SYS);
CkanDataset dataset = client.getDataset(datasetIdOrName);
String name = dataset.getName();
if(dataset != null){
if (dataset != null) {
if(getUriResolverUrl() != null)
if (getUriResolverUrl() != null)
url = getUrlForProduct(CONTEXT, EntityContext.DATASET, name);
if(url == null || url.isEmpty())
url = getPortletUrl() + "?" + URLEncoder.encode("path=/dataset/" + name, "UTF-8");
if (url == null || url.isEmpty())
url = getPortletUrl() + "?" + URLEncoder.encode("path=/dataset/" + name, "UTF-8");
}
}catch(Exception e){
} catch (Exception e) {
LOG.error("Error while retrieving dataset with id/name=" + datasetIdOrName, e);
} //requestEntity.put("clear_url", Boolean.toString(unencrypted));
} // requestEntity.put("clear_url", Boolean.toString(unencrypted));
return url;
}
@Override
public Map<String, Map<CkanGroup, RolesCkanGroupOrOrg>> getUserRoleByGroup(String username) {
LOG.info("Get user role by group called. The username is: "+username);
LOG.info("Get user role by group called. The username is: " + username);
checkNotNull(username);
Map<String, Map<CkanGroup, RolesCkanGroupOrOrg>> toReturn = new HashMap<String, Map<CkanGroup,RolesCkanGroupOrOrg>>();
Map<String, Map<CkanGroup, RolesCkanGroupOrOrg>> toReturn = new HashMap<String, Map<CkanGroup, RolesCkanGroupOrOrg>>();
try{
try {
String ckanUsername = CatalogueUtilMethods.fromUsernameToCKanUsername(username);
Map<String, RolesCkanGroupOrOrg> partialResult = dbCaller.getGroupsByUserFromDB(ckanUsername);
for (String groupID : partialResult.keySet()) {
CkanGroup group = ckanCaller.getGroup(groupID);
@ -318,27 +328,26 @@ public class DataCatalogueImpl implements DataCatalogue {
subMap.put(group, partialResult.get(groupID));
toReturn.put(groupID, subMap);
}
LOG.debug("Returning map " + toReturn);
LOG.info("Found " + toReturn.size() +" group/s with the user "+username);
}catch(Exception e){
LOG.error("Failed to retrieve roles of user in his/her own groups",e);
LOG.info("Found " + toReturn.size() + " group/s with the user " + username);
} catch (Exception e) {
LOG.error("Failed to retrieve roles of user in his/her own groups", e);
}
return toReturn;
}
@Override
public Map<String, Map<CkanOrganization, RolesCkanGroupOrOrg>> getUserRoleByOrganization(
String username) {
LOG.info("Get user role by organization called. The username is: "+username);
public Map<String, Map<CkanOrganization, RolesCkanGroupOrOrg>> getUserRoleByOrganization(String username) {
LOG.info("Get user role by organization called. The username is: " + username);
checkNotNull(username);
Map<String, Map<CkanOrganization, RolesCkanGroupOrOrg>> toReturn = new HashMap<String, Map<CkanOrganization,RolesCkanGroupOrOrg>>();
Map<String, Map<CkanOrganization, RolesCkanGroupOrOrg>> toReturn = new HashMap<String, Map<CkanOrganization, RolesCkanGroupOrOrg>>();
try{
try {
String ckanUsername = CatalogueUtilMethods.fromUsernameToCKanUsername(username);
Map<String, RolesCkanGroupOrOrg> partialResult = dbCaller.getOrganizationsByUserFromDB(ckanUsername);
@ -349,13 +358,13 @@ public class DataCatalogueImpl implements DataCatalogue {
HashMap<CkanOrganization, RolesCkanGroupOrOrg> subMap = new HashMap<CkanOrganization, RolesCkanGroupOrOrg>();
subMap.put(org, partialResult.get(orgID));
toReturn.put(orgID, subMap);
LOG.debug("For organisation: " + org.getName() + ", the user "+username+" has role: "+subMap);
LOG.debug("For organisation: " + org.getName() + ", the user " + username + " has role: " + subMap);
}
LOG.debug("Returning map " + toReturn);
LOG.info("Found " + toReturn.size() +" organization/s with the user "+username);
}catch(Exception e){
LOG.error("Failed to retrieve roles of user in his/her own groups",e);
LOG.info("Found " + toReturn.size() + " organization/s with the user " + username);
} catch (Exception e) {
LOG.error("Failed to retrieve roles of user in his/her own groups", e);
}
return toReturn;
@ -364,11 +373,12 @@ public class DataCatalogueImpl implements DataCatalogue {
/**
* Retrieve an url for the tuple scope, entity, entity name
*
* @param context
* @param entityContext
* @param entityName
*/
private String getUrlForProduct(String context, EntityContext entityContext, String entityName){
private String getUrlForProduct(String context, EntityContext entityContext, String entityName) {
String toReturn = null;
@ -386,19 +396,19 @@ public class DataCatalogueImpl implements DataCatalogue {
HttpResponse response = httpClient.execute(httpPostRequest);
if(response.getStatusLine().getStatusCode() != 200)
if (response.getStatusLine().getStatusCode() != 200)
throw new Exception("There was an error while creating an url " + response.getStatusLine());
toReturn = EntityUtils.toString(response.getEntity());
LOG.debug("Result is " + toReturn);
}catch(Exception e){
} catch (Exception e) {
LOG.error("Failed to get an url for this product", e);
}
return toReturn;
return toReturn;
}
@Override
public LandingPages getLandingPages() throws Exception {
@ -409,8 +419,6 @@ public class DataCatalogueImpl implements DataCatalogue {
landingPages.setUrlTypes(PORTLET_URL_FOR_SCOPE + "?path=/type/");
return landingPages;
}
@Override
public String getUriResolverUrl() {
@ -438,43 +446,23 @@ public class DataCatalogueImpl implements DataCatalogue {
// list to return
List<CkanOrganization> toReturn = new ArrayList<CkanOrganization>();
try{
try {
Map<String, RolesCkanGroupOrOrg> partialResult = dbCaller.getOrganizationsByUserFromDB(ckanUsername);
for (String orgID : partialResult.keySet()) {
CkanOrganization org = ckanCaller.getOrganization(orgID,false);
CkanOrganization org = ckanCaller.getOrganization(orgID, false);
LOG.debug("User " + ckanUsername + " is into " + org.getName());
toReturn.add(org);
}
// get the list of all organizations
//List<CkanOrganization> organizations = ckanCaller.getOrganizationList();
// iterate over them
/*for (CkanOrganization ckanOrganization : organizations) {
// get the list of users in it (if you try ckanOrganization.getUsers() it returns null.. maybe a bug TODO)
List<CkanUser> users = ckanCaller.getOrganization(ckanOrganization.getName()).getUsers();
// check if the current user is among them
for (CkanUser ckanUser : users) {
if(ckanUser.getName().equals(ckanUsername)){
LOG.debug("User " + ckanUsername + " is into " + ckanOrganization.getName());
toReturn.add(ckanOrganization);
break;
}
}
}*/
}catch(Exception e){
} catch (Exception e) {
LOG.error("Unable to get user's organizations", e);
}
return toReturn;
}
@Override
public List<CkanGroup> getGroupsByUser(String username) {
LOG.debug("Requested groups for user " + username);
@ -486,46 +474,25 @@ public class DataCatalogueImpl implements DataCatalogue {
// list to return
List<CkanGroup> toReturn = new ArrayList<CkanGroup>();
try{
try {
Map<String, RolesCkanGroupOrOrg> partialResult = dbCaller.getGroupsByUserFromDB(ckanUsername);
for (String groupID : partialResult.keySet()) {
CkanGroup group = ckanCaller.getGroup(groupID,false);
CkanGroup group = ckanCaller.getGroup(groupID, false);
LOG.debug("User " + ckanUsername + " is into " + group.getName());
toReturn.add(group);
}
/*
// get the list of all organizations
List<CkanGroup> groups = ckanCaller.getGroupList();
// iterate over them
for (CkanGroup ckanGroup : groups) {
List<CkanUser> users = ckanCaller.getGroup(ckanGroup.getName()).getUsers();
// check if the current user is among them
for (CkanUser ckanUser : users) {
if(ckanUser.getName().equals(ckanUsername)){
LOG.debug("User " + ckanUsername + " is into " + ckanGroup.getName());
toReturn.add(ckanGroup);
break;
}
}
}*/
}catch(Exception e){
} catch (Exception e) {
LOG.error("Unable to get user's groups", e);
}
return toReturn;
}
@Override
public List<String> getOrganizationsIds(){
public List<String> getOrganizationsIds() {
List<String> toReturn = new ArrayList<String>();
List<CkanOrganization> orgs = ckanCaller.getOrganizationList();
@ -539,7 +506,7 @@ public class DataCatalogueImpl implements DataCatalogue {
}
@Override
public List<String> getOrganizationsNames(){
public List<String> getOrganizationsNames() {
List<String> toReturn = new ArrayList<String>();
List<CkanOrganization> orgs = ckanCaller.getOrganizationList();
@ -573,7 +540,7 @@ public class DataCatalogueImpl implements DataCatalogue {
return orgsName;
}
@Override
public String getRoleOfUserInOrganization(String username, String orgName) {
@ -582,19 +549,19 @@ public class DataCatalogueImpl implements DataCatalogue {
String apiKey = getApiKeyFromUsername(username);
String usernameCkan = CatalogueUtilMethods.fromUsernameToCKanUsername(username);
try{
try {
ExtendCkanClient client = new ExtendCkanClient(CKAN_CATALOGUE_URL, apiKey);
List<CkanUser> users = client.getOrganization(orgName).getUsers();
for (CkanUser ckanUser : users) {
if(ckanUser.getName().equals(usernameCkan)){
if (ckanUser.getName().equals(usernameCkan)) {
toReturn = ckanUser.getCapacity();
break;
}
}
}catch(Exception e){
LOG.error("Unable to retrieve the role the user has into organization: "+orgName, e);
} catch (Exception e) {
LOG.error("Unable to retrieve the role the user has into organization: " + orgName, e);
}
return toReturn;
@ -609,10 +576,10 @@ public class DataCatalogueImpl implements DataCatalogue {
*/
@Override
public boolean checkValidUser(String username) {
String apiKey = getApiKeyFromUsername(username);
return apiKey != null;
}
private String getApiKeyFromUsername(String username) {
@ -627,64 +594,144 @@ public class DataCatalogueImpl implements DataCatalogue {
String ckanUsername = CatalogueUtilMethods.fromUsernameToCKanUsername(username);
// check in the hashmap first
if(apiKeysMap.containsKey(ckanUsername)){
if (apiKeysMap.containsKey(ckanUsername)) {
CKANTokenBean bean = apiKeysMap.get(ckanUsername);
if(bean.timestamp + EXPIRE_KEY_TIME > System.currentTimeMillis()){ // it's still ok
if (bean.timestamp + EXPIRE_KEY_TIME > System.currentTimeMillis()) { // it's still ok
return bean.apiKey;
}
}
LOG.debug("Api key was not in cache or it expired");
try{
try {
String apiToReturn = dbCaller.getApiKeyFromUsername(username, State.ACTIVE.name().toLowerCase());
// save into the hashmap
if(apiToReturn != null)
if (apiToReturn != null)
apiKeysMap.put(ckanUsername, new CKANTokenBean(apiToReturn, System.currentTimeMillis()));
return apiToReturn;
}catch(Exception e){
} catch (Exception e) {
LOG.error("Unable to retrieve key for user " + ckanUsername, e);
}
return null;
}
@Override
public boolean existProductWithNameOrId(String nameOrId) {
checkNotNull(nameOrId);
checkArgument(!nameOrId.isEmpty());
try{
try {
ExtendCkanClient client = new ExtendCkanClient(CKAN_CATALOGUE_URL, CKAN_TOKEN_SYS);
CkanDataset product = client.getDataset(nameOrId);
return product != null;
}catch(Exception e){
} catch (Exception e) {
LOG.debug("A dataset with name " + nameOrId + " doesn't exist");
return false;
}
}
@Override
public CkanOrganization getOrganizationByIdOrName(String idOrName) {
checkNotNull(idOrName);
String ckanName = idOrName.toLowerCase();
try{
try {
return ckanCaller.getOrganization(ckanName);
}catch(Exception e){
LOG.warn("Failed to retrieve the organization with name " +idOrName+ " on the ckan: "+ckanCaller.getCatalogUrl(), e);
} catch (Exception e) {
LOG.warn("Failed to retrieve the organization with name " + idOrName + " on the ckan: "
+ ckanCaller.getCatalogUrl(), e);
}
return null;
}
/**
* Check if the user has this role into the organization/group with
* groupOrOrganization name
*
* @param ckanUsername
* @param organizationName
* @param correspondentRoleToCheck
* @return true if he has the role, false otherwise
*/
protected boolean isRoleAlreadySet(String ckanUsername, String groupOrOrganization,
RolesCkanGroupOrOrg correspondentRoleToCheck, boolean group) throws Exception {
// get the users (if you try ckanOrganization.getUsers() it returns null.. maybe
// a bug TODO)
List<CkanUser> users;
if (group)
users = ckanCaller.getGroup(groupOrOrganization).getUsers();
else
users = ckanCaller.getOrganization(groupOrOrganization).getUsers();
for (CkanUser ckanUser : users) {
if (ckanUser.getName().equals(ckanUsername))
if (ckanUser.getCapacity().equals(RolesCkanGroupOrOrg.convertToCkanCapacity(correspondentRoleToCheck)))
return true;
else
break;
}
return false;
}
/**
* Just check if the group exists
*
* @param nameOrId
* @param client
* @return
*/
private CkanGroup groupExists(String nameOrId) {
CkanGroup toReturn = null;
try {
ExtendCkanClient client = new ExtendCkanClient(CKAN_CATALOGUE_URL, CKAN_TOKEN_SYS);
toReturn = client.getGroup(nameOrId);
} catch (JackanException je) {
LOG.error("The group " + nameOrId + " doesn't exist");
}
return toReturn;
}
/*
*
*
*
*
*
*
*
*
*
* WRITE OPERATIONS
*
*
*
*
*
*
*
*
*
*
*/
@Override
public boolean checkRoleIntoOrganization(String username, String organizationName,
@ -800,60 +847,8 @@ public class DataCatalogueImpl implements DataCatalogue {
return false;
}
/**
* Check if the user has this role into the organization/group with groupOrOrganization name
* @param ckanUsername
* @param organizationName
* @param correspondentRoleToCheck
* @return true if he has the role, false otherwise
*/
protected boolean isRoleAlreadySet(String ckanUsername, String groupOrOrganization, RolesCkanGroupOrOrg correspondentRoleToCheck, boolean group) throws Exception{
// get the users (if you try ckanOrganization.getUsers() it returns null.. maybe a bug TODO)
List<CkanUser> users;
if(group)
users = ckanCaller.getGroup(groupOrOrganization).getUsers();
else
users = ckanCaller.getOrganization(groupOrOrganization).getUsers();
for (CkanUser ckanUser : users) {
if(ckanUser.getName().equals(ckanUsername))
if(ckanUser.getCapacity().equals(RolesCkanGroupOrOrg.convertToCkanCapacity(correspondentRoleToCheck)))
return true;
else
break;
}
return false;
}
/*
*
*
*
*
*
*
*
*
*
* WRITE OPERATIONS
*
*
*
*
*
*
*
*
*
*
*/
@Override
public String createCkanDatasetMultipleCustomFields(String username, String title, String name, String organizationNameOrId,
public String createCkanDatasetMultipleCustomFields(String username, String title, String name, String organizationName,
String author, String authorMail, String maintainer, String maintainerMail, long version,
String description, String licenseId, List<String> tags, Map<String, List<String>> customFieldsMultiple,
List<ResourceBean> resources, boolean setPublic, boolean setSearchable, boolean socialPost) throws Exception {
@ -861,13 +856,36 @@ public class DataCatalogueImpl implements DataCatalogue {
// checks (minimum)
checkNotNull(username);
checkNotNull(organizationNameOrId);
checkArgument(!organizationNameOrId.isEmpty());
//checkNotNull(organizationNameOrId);
//checkArgument(!organizationNameOrId.isEmpty());
checkArgument(!(title == null && name == null || title.isEmpty() && name.isEmpty()), "Name and Title cannot be empty/null at the same time!");
try {
//Business logic to pass the organization name to gCat if and only if the scope is of ROOT or VO (not VRE)
String scope = ScopeProvider.instance.get();
if(scope==null)
throw new Exception("No scope detected. You must set it");
GCUBE_SCOPE_LEVEL gCubeScopeLevel = GCubeUtils.toGCubeLevel(scope);
String toPassOrganizationToGcat = null;
if(gCubeScopeLevel!=null) {
switch (gCubeScopeLevel) {
case ROOT:
case VO:
toPassOrganizationToGcat = organizationName;
break;
case VRE:
toPassOrganizationToGcat = null;
default:
break;
}
}
// String ckanUsername = getUserFromApiKey(apiKey).getName();
CkanDataset dataset = CKANConveter.toCkanDataset(ckanCaller, username, title, name, organizationNameOrId, author, authorMail,
CkanDataset dataset = CKANConveter.toCkanDataset(ckanCaller, username, title, name, toPassOrganizationToGcat, author, authorMail,
maintainer, maintainerMail, version, description, licenseId, tags, null, customFieldsMultiple,
resources, setPublic, setSearchable);
@ -910,50 +928,51 @@ public class DataCatalogueImpl implements DataCatalogue {
}
@Override
@Override
public boolean patchFieldsForDataset(String datasetId, Map<String, String> mapFields) throws Exception {
LOG.info("Called patch the fields "+mapFields+" for dataset id: "+datasetId);
LOG.info("Called patch the fields " + mapFields + " for dataset id: " + datasetId);
checkNotNull(datasetId);
checkNotNull(mapFields);
try {
JSONObject jsonObj = new JSONObject();
for (String key : mapFields.keySet()) {
jsonObj.put(key, mapFields.get(key));
}
LOG.debug("Json Dataset is: " + jsonObj);
gCatCaller.patchDataset(datasetId, jsonObj);
LOG.info("Patch operation for dataset "+datasetId+" terminates without errors");
LOG.info("Patch operation for dataset " + datasetId + " terminates without errors");
return true;
}catch (Exception e) {
LOG.error("Error occurred trying to patch the dataset with id: "+datasetId, e.getMessage());
throw new Exception("Unable to patch the dataset. Error: "+e.getMessage());
} catch (Exception e) {
LOG.error("Error occurred trying to patch the dataset with id: " + datasetId, e.getMessage());
throw new Exception("Unable to patch the dataset. Error: " + e.getMessage());
}
}
@Override
public boolean setSearchableFieldForDataset(String datasetId, boolean searchable) throws Exception {
LOG.info("Set searchalbe field as "+searchable+" for dataset id: "+datasetId);
LOG.info("Set searchalbe field as " + searchable + " for dataset id: " + datasetId);
checkNotNull(datasetId);
try {
String searchableAsString = searchable ? "True" : "False";
JSONObject jsonObj = new JSONObject();
jsonObj.put("id", datasetId); //just to be sure
jsonObj.put("id", datasetId); // just to be sure
jsonObj.put("searchable", searchableAsString);
LOG.debug("Json Dataset is: " + jsonObj);
gCatCaller.patchDataset(datasetId, jsonObj);
LOG.info("Set 'searchable' field for dataset "+datasetId+" terminates without errors");
LOG.info("Set 'searchable' field for dataset " + datasetId + " terminates without errors");
return true;
}catch (Exception e) {
LOG.error("Error occured trying to set the 'searchable' field for the dataset with id: "+datasetId, e.getMessage());
throw new Exception("Unable to set the 'searchable' field for this dataset. Error: "+e.getMessage());
} catch (Exception e) {
LOG.error("Error occured trying to set the 'searchable' field for the dataset with id: " + datasetId,
e.getMessage());
throw new Exception("Unable to set the 'searchable' field for this dataset. Error: " + e.getMessage());
}
}
@ -964,23 +983,23 @@ public class DataCatalogueImpl implements DataCatalogue {
// checks
checkNotNull(resourceBean);
if(CatalogueUtilMethods.resourceExists(resourceBean.getUrl())){
if (CatalogueUtilMethods.resourceExists(resourceBean.getUrl())) {
CkanResource resource = CKANConveter.toCkanResource(CKAN_CATALOGUE_URL, resourceBean);
String jsonValueResource = MarshUnmarshCkanObject.toJsonValueResource(resource);
LOG.trace("Serialized resource is: " + jsonValueResource);
String jsonValueResource = MarshUnmarshCkanObject.toJsonValueResource(resource, METHOD.TO_CREATE);
LOG.debug("Serialized resource is: " + jsonValueResource);
jsonValueResource = gCatCaller.addResourceToDataset(resourceBean.getDatasetId(), jsonValueResource);
LOG.debug("Added resource to dataset is: " + jsonValueResource);
CkanResource createdRes = MarshUnmarshCkanObject.toCkanResource(jsonValueResource);
if(createdRes != null){
LOG.debug("Resource " + createdRes.getName() + " is now available");
if (createdRes != null) {
LOG.debug("Resource " + createdRes.getName() + " added correclty");
return createdRes.getId();
}
}else
} else
throw new Exception("It seems there is no is no resource at this url " + resourceBean.getUrl());
return null;
@ -1041,27 +1060,5 @@ public class DataCatalogueImpl implements DataCatalogue {
return toCreate;
}
/**
* Just check if the group exists
* @param nameOrId
* @param client
* @return
*/
private CkanGroup groupExists(String nameOrId){
CkanGroup toReturn = null;
try{
ExtendCkanClient client = new ExtendCkanClient(CKAN_CATALOGUE_URL, CKAN_TOKEN_SYS);
toReturn = client.getGroup(nameOrId);
}catch(JackanException je){
LOG.error("The group "+nameOrId+" doesn't exist");
}
return toReturn;
}
}

View File

@ -8,14 +8,14 @@ import java.util.Map.Entry;
import org.gcube.datacatalogue.ckanutillibrary.ckan.ExtendCkanClient;
import org.gcube.datacatalogue.ckanutillibrary.shared.ResourceBean;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanDataset;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanOrganization;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanPair;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanResource;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanTag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import eu.trentorise.opendata.jackan.model.CkanDataset;
import eu.trentorise.opendata.jackan.model.CkanOrganization;
import eu.trentorise.opendata.jackan.model.CkanPair;
import eu.trentorise.opendata.jackan.model.CkanResource;
import eu.trentorise.opendata.jackan.model.CkanTag;
import net.htmlparser.jericho.Renderer;
import net.htmlparser.jericho.Segment;
import net.htmlparser.jericho.Source;
@ -39,7 +39,7 @@ public class CKANConveter {
* @param username the username
* @param title the title
* @param name the name
* @param organizationNameOrId the organization name or id
* @param organizationName the organization name or id
* @param author the author
* @param authorMail the author mail
* @param maintainer the maintainer
@ -55,7 +55,7 @@ public class CKANConveter {
* @param setSearchable the set searchable
* @return the ckan dataset
*/
public static CkanDataset toCkanDataset(ExtendCkanClient ckanCaller, String username, String title, String name, String organizationNameOrId, String author,
public static CkanDataset toCkanDataset(ExtendCkanClient ckanCaller, String username, String title, String name, String organizationName, String author,
String authorMail, String maintainer, String maintainerMail, long version, String description,
String licenseId, List<String> tags, Map<String, String> customFields,
Map<String, List<String>> customFieldsMultipleValues, List<ResourceBean> resources, boolean setPublic, boolean setSearchable) {
@ -81,8 +81,10 @@ public class CKANConveter {
dataset.setTitle(title);
//TODO SHOULD BE REVISITED by gCAT?
CkanOrganization orgOwner = ckanCaller.getOrganization(organizationNameOrId);
dataset.setOwnerOrg(orgOwner.getId());
if(organizationName!=null) {
CkanOrganization orgOwner = ckanCaller.getOrganization(organizationName);
dataset.setOwnerOrg(orgOwner.getId());
}
dataset.setAuthor(author);
dataset.setAuthorEmail(authorMail);
@ -112,6 +114,7 @@ public class CKANConveter {
}
dataset.setTags(ckanTags);
dataset.setNumTags(ckanTags.size());
}
// set the custom fields, if any

View File

@ -0,0 +1,61 @@
package org.gcube.datacatalogue.ckanutillibrary.server.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class GCubeUtils.
*
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
*
* Feb 10, 2021
*/
public class GCubeUtils {
/**
* The Enum GCUBE_SCOPE_LEVEL.
*
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
*
* Feb 10, 2021
*/
public static enum GCUBE_SCOPE_LEVEL {
ROOT, VO, VRE
}
private static final Logger LOG = LoggerFactory.getLogger(CatalogueUtilMethods.class);
/**
* To G cube level.
*
* @param scope the scope
* @return the gcube scope level
* @throws IllegalArgumentException the illegal argument exception
*/
public static GCUBE_SCOPE_LEVEL toGCubeLevel(String scope) throws IllegalArgumentException {
LOG.debug("called toGCubeLevel on " + scope);
if (scope == null || scope.isEmpty())
throw new IllegalArgumentException("Scope is null or empty");
if (!scope.startsWith("/")) {
throw new IllegalArgumentException("Scope should start with '/' ->" + scope);
}
if (scope.endsWith("/")) {
throw new IllegalArgumentException("Scope should not end with '/' ->" + scope);
}
String[] splits = scope.split("/");
if (splits.length > 4)
throw new IllegalArgumentException("Scope is invalid, too many '/' ->" + scope);
if (splits.length == 2) // is a root VO
return GCUBE_SCOPE_LEVEL.ROOT;
else if (splits.length == 3) {// is a VO
return GCUBE_SCOPE_LEVEL.VO;
} else if (splits.length == 4) {// is a VRE
return GCUBE_SCOPE_LEVEL.VRE;
}
return null;
}
}

View File

@ -0,0 +1,405 @@
package org.gcube.datacatalogue.ckanutillibrary.server.utils;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Locale;
import java.util.Map;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Multimap;
/**
* The Class GenericUtils.
*
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
*
* Feb 9, 2021
*/
public final class GenericUtils {
private static final Logger LOG = LoggerFactory.getLogger(GenericUtils.class.getName());
/**
*
* Checks if provided array is non null and non empty .
*
* @param errorMessageTemplate a template for the exception message should
* the check fail. The message is formed by replacing each {@code %s}
* placeholder in the template with an argument. These are matched by
* position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
* Unmatched arguments will be appended to the formatted message in square
* braces. Unmatched placeholders will be left as-is.
* @param errorMessageArgs the arguments to be substituted into the message
* template. Arguments are converted to strings using
* {@link String#valueOf(Object)}.
* @throws IllegalArgumentException if {@code array} is empty or null
* @throws NullPointerException if the check fails and either
* {@code errorMessageTemplate} or {@code errorMessageArgs} is null (don't
* let this happen)
*
* @return a non-null non-empty array
*/
public static <T> T[] checkNotEmpty(@Nullable T[] array,
@Nullable String errorMessageTemplate,
@Nullable Object... errorMessageArgs) {
String formattedMessage = format(errorMessageTemplate, errorMessageArgs);
checkArgument(array != null, "%s -- Reason: Found null iterable.", formattedMessage);
if (array.length == 0) {
throw new IllegalArgumentException(formattedMessage + " -- Reason: Found empty array.");
}
return array;
}
/**
* Tolerance for probabilities
*/
public static final double TOLERANCE = 0.001;
/**
* Used for unparseable dates and other stuff.
*/
public static final String UNPARSEABLE = "unparseable:";
/**
* Tod Commons build properties path.
*/
public static final String BUILD_PROPERTIES_PATH = "tod.commons.build.properties";
/**
* Converts a language code to Java Locale. On null input returns
* {@link Locale#ROOT}
*
* Notice Java 7 introduced {@link Locale#forLanguageTag(String)}, but that
* method throws null pointer exception on null string, which unfortunately
* can happen quite often, so we use this method instead.
*
* @see Locale#forLanguageTag(String)
* @see #localeToLanguageTag(Locale) localeToLanguageTag(Locale) for the inverse operation
*/
public static Locale languageTagToLocale(@Nullable String languageTag) {
if (languageTag == null) {
LOG.warn("Found null locale, returning Locale.ROOT");
return Locale.ROOT;
}
return Locale.forLanguageTag(languageTag);
}
/**
* Converts a Java locale to a String. On null input returns the empty
* string (which corresponds to Java {@link Locale#ROOT})
*
* @see #languageTagToLocale(java.lang.String) #languageTagToLocale(java.lang.String) for the inverse operation
*/
public static String localeToLanguageTag(@Nullable Locale locale) {
if (locale == null) {
LOG.warn("Found null locale, returning empty string (which corresponds to Locale.ROOT)");
return "";
}
return locale.getLanguage();
}
/**
* Returns a new url with a slash added at the end of provided url. If
* provided url already ends with a slash it just returns it.
*
* @param url
*/
public static String addSlash(String url) {
checkNotNull(url, "invalid url!");
String trimmedUrl = url.trim();
if (trimmedUrl.endsWith("/")) {
return trimmedUrl;
} else {
return trimmedUrl + "/";
}
}
/**
* Returns the provided url with all trailing slash at the end removed.
*/
public static String removeTrailingSlash(String url) {
checkNotNull(url, "invalid url!");
String tempUrl = url.trim();
while (tempUrl.endsWith("/")) {
tempUrl = tempUrl.substring(0, tempUrl.length() - 1);
}
return tempUrl;
}
/**
* Checks if provided URL is to be considered 'dirty'. Method may use some
* heuristics to detect oddities, like i.e. the string "null" inside the
* url.
*
* @deprecated Moved to
* {@link eu.trentorise.opendata.commons.validation.Preconditions#checkNotDirtyUrl(java.lang.String, java.lang.Object) } @
* param url the URL to check
* @param prependedErrorMessage
* the exception message to use if the check fails; will be
* converted to a string using String.valueOf(Object) and
* prepended to more specific error messages.
*
* @throws IllegalArgumentException
* if provided URL fails validation.
*
* @return the non-dirty URL that was validated
*
*/
public static String checkNotDirtyUrl(@Nullable String url, @Nullable Object prependedErrorMessage) {
checkNotEmpty(url, prependedErrorMessage);
if (url.equalsIgnoreCase("null")) {
throw new IllegalArgumentException(String.valueOf(prependedErrorMessage)
+ " -- Reason: Found URL with string \"" + url + "\" as content!");
}
// todo delete this is a too radical checker...
if (url.toLowerCase()
.endsWith("/null")) {
throw new IllegalArgumentException(
String.valueOf(prependedErrorMessage) + " -- Reason: Found URL ending with /\"null\": " + url);
}
return url;
}
/**
*
* Checks if provided string is non null and non empty.
*
* @throws IllegalArgumentException
* if provided string fails validation
*
* @return the non-empty string that was validated
*/
public static String checkNotEmpty(String string, @Nullable Object prependedErrorMessage) {
checkArgument(string != null, "%s -- Reason: Found null string.", prependedErrorMessage);
if (string.length() == 0) {
throw new IllegalArgumentException(
String.valueOf(prependedErrorMessage) + " -- Reason: Found empty string.");
}
return string;
}
/**
* Returns true if provided string is non null and non empty .
*/
public static boolean isNotEmpty(@Nullable String string) {
return string != null && string.length() != 0;
}
/**
* Parses an URL having a numeric ID after the provided prefix, i.e. for
* prefix 'http://entitypedia.org/concepts/' and url
* http://entitypedia.org/concepts/14324 returns 14324
*
* @deprecated this shouldn't be here.....
*
* @throws IllegalArgumentException
* on invalid URL
*/
public static long parseNumericalId(String prefix, String url) {
checkNotNull(prefix, "prefix can't be null!");
checkNotEmpty(url, "Invalid url!");
String s;
if (prefix.length() > 0) {
int pos = url.indexOf(prefix);
if (pos != 0) {
throw new IllegalArgumentException("Invalid URL for prefix " + prefix + ": " + url);
}
s = url.substring(prefix.length());
} else {
s = url;
}
try {
return Long.parseLong(s);
} catch (NumberFormatException ex) {
throw new IllegalArgumentException("Invalid URL for prefix " + prefix + ": " + url, ex);
}
}
/**
*
* Substitutes each {@code %s} in {@code template} with an argument. These
* are matched by position: the first {@code %s} gets {@code args[0]}, etc.
* If there are more arguments than placeholders, the unmatched arguments
* will be appended to the end of the formatted message in square braces.
* <br/>
* <br/>
* (Copied from Guava's
* {@link com.google.common.base.Preconditions#format(java.lang.String, java.lang.Object...) }
* )
*
* @param template
* a non-null string containing 0 or more {@code %s}
* placeholders.
* @param args
* the arguments to be substituted into the message template.
* Arguments are converted to strings using
* {@link String#valueOf(Object)}. Arguments can be null.
*
* @since 1.1
*/
public static String format(String template, @Nullable Object... args) {
if (template == null) {
LOG.warn("Found null template while formatting, converting it to \"null\"");
}
template = String.valueOf(template); // null -> "null"
// start substituting the arguments into the '%s' placeholders
StringBuilder builder = new StringBuilder(template.length() + 16 * args.length);
int templateStart = 0;
int i = 0;
while (i < args.length) {
int placeholderStart = template.indexOf("%s", templateStart);
if (placeholderStart == -1) {
break;
}
builder.append(template.substring(templateStart, placeholderStart));
builder.append(args[i++]);
templateStart = placeholderStart + 2;
}
builder.append(template.substring(templateStart));
// if we run out of placeholders, append the extra args in square braces
if (i < args.length) {
builder.append(" [");
builder.append(args[i++]);
while (i < args.length) {
builder.append(", ");
builder.append(args[i++]);
}
builder.append(']');
}
return builder.toString();
}
/**
* Extracts parameters from given url. Works also with multiple params with
* same name.
*
* @return map of param name : [args]
* @throws IllegalArgumentException
* @since 1.1
*/
public static Multimap<String, String> parseUrlParams(String url) {
URL u;
try {
u = new URL(url);
} catch (MalformedURLException ex) {
throw new IllegalArgumentException("Ill formed url!", ex);
}
Multimap<String, String> queryPairs = LinkedListMultimap.create();
final String[] pairs = u.getQuery()
.split("&");
try {
for (String pair : pairs) {
final int idx = pair.indexOf("=");
final String key;
key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
final String value = idx > 0 && pair.length() > idx + 1
? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : "";
queryPairs.put(key, value);
}
return queryPairs;
} catch (UnsupportedEncodingException ex) {
throw new IllegalArgumentException("Encoding not supported!", ex);
}
}
/**
* Returns a copy of provided map with {@code newObject} set under the given
* key. If key already exists replaces its value in the returned object. Not
* efficient, but sometimes we need it.
*
* @param newObject
* Must be an immutable object.
* @since 1.1
*/
public static <K, V> ImmutableMap<K, V> putKey(Map<K, V> map, K key, V newObject) {
ImmutableMap.Builder<K, V> mapb = ImmutableMap.builder();
for (K k : map.keySet()) {
if (!k.equals(key)) {
mapb.put(k, map.get(k));
}
}
mapb.put(key, newObject);
return mapb.build();
}
// private static final FastDateFormat ISO_YEAR_FORMAT = FastDateFormat.getInstance("yyyy");
//
// private static final FastDateFormat ISO_YEAR_MONTH_FORMAT = FastDateFormat.getInstance("yyyy-MM");
//
// /**
// * @deprecated experimental, try to avoid using it for now
// * @since 1.1
// * @throws TodParseException
// */
// // todo this parser is horrible
// public static Date parseIso8061(String s) {
//
// try {
// return DateFormatUtils.ISO_DATE_TIME_ZONE_FORMAT.parse(s);
// } catch (ParseException ex) {
// }
//
// try {
// return DateFormatUtils.ISO_DATETIME_FORMAT.parse(s);
// } catch (ParseException ex) {
// }
//
// try {
// return DateFormatUtils.ISO_DATE_TIME_ZONE_FORMAT.parse(s);
// } catch (ParseException ex) {
// }
//
// try {
// return DateFormatUtils.ISO_DATE_FORMAT.parse(s);
// } catch (ParseException ex) {
// }
//
// try {
// return ISO_YEAR_MONTH_FORMAT.parse(s);
// } catch (ParseException ex) {
// }
//
// try {
// return ISO_YEAR_FORMAT.parse(s);
// } catch (ParseException ex) {
// }
//
// // todo week dates, ordinal dates
//
// throw new TodParseException("Couldn't parse date as ISO8061. Unparseable date was:" + s);
// }
//
}

View File

@ -0,0 +1,133 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import java.sql.Timestamp;
import java.util.List;
import javax.annotation.Nullable;
/**
*
* @author David Leoni
*/
public class CkanActivity {
/**
* i.e. "ddb21e57-da76-4dc1-a815-4edd0e9e332e"
*/
private String id;
/**
* Ckan always refer to UTC timezone, in JSON looks like i.e. "2013-03-08T09:31:20.833590"
*/
private Timestamp timestamp;
/**
* i.e. "Impostazioni modificate."
*/
private String message;
/**
* i.e. "admin"
*/
private String author;
@Nullable
private Timestamp approvedTimestamp;
private List<CkanDataset> packages;
private List<String> groups;
private CkanState state;
public CkanActivity() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Timestamp getTimestamp() {
return timestamp;
}
/**
* internally date is stored with UTC timezone
*/
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Nullable
public Timestamp getApprovedTimestamp() {
return approvedTimestamp;
}
/**
* internally date is stored with UTC timezone
*
* @param approvedTimestamp
*/
public void setApprovedTimestamp(@Nullable Timestamp approvedTimestamp) {
this.approvedTimestamp = approvedTimestamp;
}
public List<CkanDataset> getPackages() {
return packages;
}
public void setPackages(List<CkanDataset> packages) {
this.packages = packages;
}
/**
* Returns list of group names (i.e. region-trentino)
*/
public List<String> getGroups() {
return groups;
}
/**
* Returns list of group names (i.e. region-trentino)
*/
public void setGroups(List<String> groups) {
this.groups = groups;
}
public CkanState getState() {
return state;
}
public void setState(CkanState state) {
this.state = state;
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
/**
* Actually they are lower case in ckan, but 'public' and 'private' clash with
* Java keywords
*
* @author David Leoni
*/
public enum CkanCapacity {
MEMBER, EDITOR, ADMIN, PUBLIC, PRIVATE;
}

View File

@ -0,0 +1,241 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import java.sql.Timestamp;
import javax.annotation.Nullable;
import org.gcube.com.fasterxml.jackson.annotation.JsonProperty;
/**
* Extends {@link CkanDatasetBase} with fields found in search operations.
*/
public class CkanDataset extends CkanDatasetBase {
private String creatorUserId;
private String licenseUrl;
private String licenseTitle;
private Timestamp metadataCreated;
private Timestamp metadataModified;
private int numResources;
private CkanTrackingSummary trackingSummary;
private int numTags;
private String notesRendered;
private Boolean open;
private CkanOrganization organization;
/**
* Actually it is named 'private' in api. Appears in searches.
*/
private Boolean priv;
private String revisionId;
private Timestamp revisionTimestamp;
public CkanDataset() {
}
/**
* @see CkanDatasetBase#CkanDatasetBase(String)
*/
public CkanDataset(String name) {
super(name);
}
public String getCreatorUserId() {
return creatorUserId;
}
public void setCreatorUserId(@Nullable String creatorUserId) {
this.creatorUserId = creatorUserId;
}
/**
* <a href="http://docs.ckan.org/en/latest/api/legacy-api.html?highlight=isopen" target="_blank">
* Legacy api 1/2 docs</a> says: boolean indication of whether dataset is
* open according to Open Knowledge Definition, based on other fields
*/
@JsonProperty("isopen")
public Boolean isOpen() {
return open;
}
/**
* @see #isOpen()
*/
@JsonProperty("isopen")
public void setOpen(Boolean isOpen) {
this.open = isOpen;
}
public String getLicenseTitle() {
return licenseTitle;
}
public void setLicenseTitle(String licenseTitle) {
this.licenseTitle = licenseTitle;
}
public String getLicenseUrl() {
return licenseUrl;
}
public void setLicenseUrl(String licenseUrl) {
this.licenseUrl = licenseUrl;
}
/**
* CKAN always refer to UTC timezone
*/
public Timestamp getMetadataCreated() {
return metadataCreated;
}
/**
* CKAN always refer to UTC timezone
*/
public void setMetadataCreated(Timestamp metadataCreated) {
this.metadataCreated = metadataCreated;
}
/**
* CKAN always refers to UTC timezone
*/
public Timestamp getMetadataModified() {
return metadataModified;
}
/**
* CKAN always refers to UTC timezone
*/
public void setMetadataModified(Timestamp metadataModified) {
this.metadataModified = metadataModified;
}
public String getNotesRendered() {
return notesRendered;
}
public void setNotesRendered(String notesRendered) {
this.notesRendered = notesRendered;
}
public int getNumTags() {
return numTags;
}
public void setNumTags(int numTags) {
this.numTags = numTags;
}
/**
* The organization that owns the dataset.
*
* Notice that if the dataset was obtained with a
* {@link eu.trentorise.opendata.jackan.CkanClient#getDataset(java.lang.String)} call, the returned
* organization won't have all the params you would get with a
* {@link eu.trentorise.opendata.jackan.CkanClient#getOrganization(java.lang.String)} call.
*/
public CkanOrganization getOrganization() {
return organization;
}
/**
* Sets the organization that owns the dataset.
*/
public void setOrganization(CkanOrganization organization) {
this.organization = organization;
}
/**
* Actually it is named "private" in the CKAN API. Appears in dataset
* searches.
*/
@JsonProperty("private")
public Boolean isPriv() {
return priv;
}
/**
* Actually it is named "private" in the CKAN API. Appears in dataset
* searches.
*/
public void setPriv(Boolean priv) {
this.priv = priv;
}
public int getNumResources() {
return numResources;
}
public void setNumResources(int numResources) {
this.numResources = numResources;
}
/**
* Returns the alphanumerical id, like
* "39d94b20-ea72-4c5e-bd8f-967a77e03946"
*/
public String getRevisionId() {
return revisionId;
}
/**
* Sets the alphanumerical id, like "39d94b20-ea72-4c5e-bd8f-967a77e03946"
*/
public void setRevisionId(String revisionId) {
this.revisionId = revisionId;
}
/**
* Returns date in UTC timezone. Probably it is automatically calculated by
* CKAN.
*/
public Timestamp getRevisionTimestamp() {
return revisionTimestamp;
}
/**
* CKAN always refer to UTC timezone. Probably it is automatically
* calculated by CKAN.
*
* @param revisionTimestamp
*/
public void setRevisionTimestamp(Timestamp revisionTimestamp) {
this.revisionTimestamp = revisionTimestamp;
}
public CkanTrackingSummary getTrackingSummary() {
return trackingSummary;
}
public void setTrackingSummary(CkanTrackingSummary trackingSummary) {
this.trackingSummary = trackingSummary;
}
}

View File

@ -0,0 +1,470 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import static org.gcube.datacatalogue.ckanutillibrary.server.utils.GenericUtils.isNotEmpty;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.gcube.com.fasterxml.jackson.annotation.JsonAnyGetter;
import org.gcube.com.fasterxml.jackson.annotation.JsonAnySetter;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnore;
/**
* A Ckan Dataset, which in turn holds Ckan Resources.
*
* In Ckan terminology it is also known as 'package'.
*
* {@link CkanDatasetBase} holds fields that can be sent when
* <a href="http://docs.ckan.org/en/latest/api/index.html?#ckan.logic.action.create.package_create" target="_blank">creating
* a dataset,</a>, while {@link CkanDataset} holds more fields that can be
* returned with searches.
*
* This class initializes nothing to fully preserve all we get from ckan. In
* practice, all fields of retrieved resources can be null except maybe
* {@code name}.
*
* @author David Leoni
* @since 0.4.1
*/
public class CkanDatasetBase {
private String author;
private String authorEmail;
private List<CkanPair> extras;
private List<CkanGroup> groups;
private String id;
private String licenseId;
private String maintainer;
private String maintainerEmail;
private String name;
private String notes;
private String ownerOrg;
private List<CkanDatasetRelationship> relationshipsAsObject;
private List<CkanDatasetRelationship> relationshipsAsSubject;
private List<CkanResource> resources;
private CkanState state;
private List<CkanTag> tags;
private String title;
private String type;
private String url;
private String version;
/**
* Custom CKAN instances might sometimes gift us with properties that don't
* end up in extras. They will end up here.
*/
@Nullable
private Map<String, Object> others;
public CkanDatasetBase() {
}
/**
* Constructor with the minimal set of attributes required to successfully
* create a dataset on the server.
*
* @param name the dataset name (contains no spaces and has dashes as
* separators, i.e. "limestone-pavement-orders")
*/
public CkanDatasetBase(String name) {
this();
this.name = name;
}
/**
* CKAN instances might have
* <a href="http://docs.ckan.org/en/latest/extensions/adding-custom-fields.html">
* custom data schemas</a> that force presence of custom properties among
* 'regular' ones. In this case, they go to 'others' field. Note that to
* further complicate things there is also an {@link #getExtras() extras}
* field.
*
* @see #putOthers(java.lang.String, java.lang.Object)
*/
@JsonAnyGetter
@Nullable
public Map<String, Object> getOthers() {
return others;
}
/**
* @see #getOthers()
* @see #putOthers(java.lang.String, java.lang.Object)
*/
public void setOthers(@Nullable Map<String, Object> others) {
this.others = others;
}
/**
* See {@link #getOthers()}
*
* @see #setOthers(java.util.Map)
*/
@JsonAnySetter
public void putOthers(String name, Object value) {
if (others == null) {
others = new HashMap<>();
}
others.put(name, value);
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getAuthorEmail() {
return authorEmail;
}
public void setAuthorEmail(String authorEmail) {
this.authorEmail = authorEmail;
}
/**
* Notice that if the dataset was obtained with a
* {@link eu.trentorise.opendata.jackan.CkanClient#getDataset(java.lang.String)} call, the returned group
* won't have all the params you would get with a
* {@link eu.trentorise.opendata.jackan.CkanClient#getGroup(java.lang.String)} call.
*/
public List<CkanGroup> getGroups() {
return groups;
}
public void setGroups(List<CkanGroup> groups) {
this.groups = groups;
}
/**
* Adds CkanGroups
*
* @param ckanGroups The CkanGroups elements
*
* @since 0.4.3
*/
public void addGroups(CkanGroup... ckanGroups) {
if (this.groups == null) {
this.groups = new ArrayList<>(ckanGroups.length);
}
Collections.addAll(this.groups, ckanGroups);
}
/**
* Regular place where to put custom metadata. See also
* {@link #getOthers()}. Note also extras can be in CkanDataset but not in
* CkanResource.
*/
public List<CkanPair> getExtras() {
return extras;
}
/**
* See {@link #getExtras()}
*/
public void setExtras(List<CkanPair> extras) {
this.extras = extras;
}
/**
* Always returns a non-null map (which might be empty)
*/
@JsonIgnore
public Map<String, String> getExtrasAsHashMap() {
HashMap<String, String> hm = new HashMap<>();
if (extras != null) {
for (CkanPair cp : extras) {
hm.put(cp.getKey(), cp.getValue());
}
}
return hm;
}
/**
* Adds CkanExtras
*
* @param extras The CkanExtra elements
*
* @since 0.4.3
*/
public void addExtras(CkanPair... extras) {
if (this.extras == null) {
this.extras = new ArrayList<>(extras.length);
}
Collections.addAll(this.extras, extras);
}
/**
* Returns the alphanumerical id, i.e.
* "c4577b8f-5603-4098-917e-da03e8ddf461"
*/
public String getId() {
return id;
}
/**
* Sets the alphanumerical id, i.e. "c4577b8f-5603-4098-917e-da03e8ddf461"
*/
public void setId(String id) {
this.id = id;
}
/**
* The license id (i.e. 'cc-zero')
*/
public String getLicenseId() {
return licenseId;
}
/**
* The license id (i.e. 'cc-zero')
*/
public void setLicenseId(String licenseId) {
this.licenseId = licenseId;
}
public String getMaintainer() {
return maintainer;
}
public void setMaintainer(String maintainer) {
this.maintainer = maintainer;
}
public String getMaintainerEmail() {
return maintainerEmail;
}
public void setMaintainerEmail(String maintainerEmail) {
this.maintainerEmail = maintainerEmail;
}
/**
* The dataset name (contains no spaces and has dashes as separators, i.e.
* "limestone-pavement-orders")
*/
public String getName() {
return name;
}
/**
* The dataset name. Name must not contain spaces and have dashes as
* separators, i.e. "limestone-pavement-orders"
*
*/
public void setName(String name) {
this.name = name;
}
/**
* A description of the dataset. See also
* {@link CkanDataset#getNotesRendered()} Note CkanResource has instead a
* field called {@link CkanResourceBase#getDescription() description}.
*/
public String getNotes() {
return notes;
}
/**
* A description of the dataset. See also
* {@link CkanDataset#getNotesRendered()} Note CkanResource has instead a
* field called {@link CkanResourceBase#getDescription() description}.
*/
public void setNotes(String notes) {
this.notes = notes;
}
/**
* The owner organization alphanunmerical id, like
* "b112ed55-01b7-4ca4-8385-f66d6168efcc".
*/
public String getOwnerOrg() {
return ownerOrg;
}
/**
* The owner organization alphanunmerical id, like
* "b112ed55-01b7-4ca4-8385-f66d6168efcc".
*/
public void setOwnerOrg(String ownerOrg) {
this.ownerOrg = ownerOrg;
}
public List<CkanDatasetRelationship> getRelationshipsAsObject() {
return relationshipsAsObject;
}
public void setRelationshipsAsObject(List<CkanDatasetRelationship> relationshipsAsObject) {
this.relationshipsAsObject = relationshipsAsObject;
}
public List<CkanDatasetRelationship> getRelationshipsAsSubject() {
return relationshipsAsSubject;
}
public void setRelationshipsAsSubject(List<CkanDatasetRelationship> relationshipsAsSubject) {
this.relationshipsAsSubject = relationshipsAsSubject;
}
public List<CkanResource> getResources() {
return this.resources;
}
public void setResources(List<CkanResource> resources) {
this.resources = resources;
}
/**
* Adds CkanResources
*
* @param resources The CkanResources elements
*
* @since 0.4.3
*/
public void addCkanResources(CkanResource... resources) {
if (this.resources == null) {
this.resources = new ArrayList<>(resources.length);
}
Collections.addAll(this.resources, resources);
}
/**
* The current state of the dataset, e.g. 'active' or 'deleted', only active
* datasets show up in search results and other lists of datasets, this
* parameter will be ignored if you are not authorized to change the state
* of the dataset (optional, default: 'active')
*/
public CkanState getState() {
return state;
}
/**
* The current state of the dataset, e.g. 'active' or 'deleted', only active
* datasets show up in search results and other lists of datasets, this
* parameter will be ignored if you are not authorized to change the state
* of the dataset (optional, default: 'active')
*/
public void setState(CkanState state) {
this.state = state;
}
public List<CkanTag> getTags() {
return tags;
}
public void setTags(List<CkanTag> tags) {
this.tags = tags;
}
/**
* Adds CkanTag
*
* @param tags The CkanTags elements
*
* @since 0.4.3
*/
public void addTags(CkanTag... tags) {
if (this.tags == null) {
this.tags = new ArrayList<>(tags.length);
}
Collections.addAll(this.tags, tags);
}
/**
* The title, like "Hospitals of Trento"
*/
public String getTitle() {
return title;
}
/**
* The title, like "Hospitals of Trento"
*/
public void setTitle(String title) {
this.title = title;
}
/**
* The type of the dataset (optional), IDatasetForm plugins associate
* themselves with different dataset types and provide custom dataset
* handling behaviour for these types
*/
public String getType() {
return type;
}
/**
* The type of the dataset (optional), IDatasetForm plugins associate
* themselves with different dataset types and provide custom dataset
* handling behaviour for these types
*/
public void setType(String type) {
this.type = type;
}
/**
* Should be the landing page on original data provider website describing
* the dataset.
*/
public String getUrl() {
return url;
}
/**
* Should be the landing page on original data provider website describing
* the dataset.
*/
public void setUrl(String url) {
this.url = url;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
/**
* Returns the id if non-empty, the name otherwise
*/
@Nullable
public String idOrName() {
return isNotEmpty(getId()) ? getId() : getName();
}
/**
* Returns the name if non-empty, the id otherwise
*/
@Nullable
public String nameOrId() {
return isNotEmpty(getName()) ? getName() : getId();
}
}

View File

@ -0,0 +1,111 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
/**
*
* @author David Leoni
*/
public class CkanDatasetRelationship {
private String comment;
private String id;
private String object;
private String subject;
private String type;
public CkanDatasetRelationship() {
}
/**
* Constructor with the minal amount of fields required for creation
*/
public CkanDatasetRelationship(String subject, String object, String type) {
this.object = object;
this.subject = subject;
this.type = type;
}
/**
* A comment about the relationship
*/
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
/**
* The id or name of the dataset that is the object of the relationship
*
*/
public String getObject() {
return object;
}
/**
* The id or name of the dataset that is the object of the relationship
*
*/
public void setObject(String object) {
this.object = object;
}
/**
* The id or name of the dataset that is the subject of the relationship
*/
public String getSubject() {
return subject;
}
/**
* The id or name of the dataset that is the subject of the relationship
*/
public void setSubject(String subject) {
this.subject = subject;
}
/**
* The type of the relationship, one of 'depends_on', 'dependency_of',
* 'derives_from', 'has_derivation', 'links_to', 'linked_from', 'child_of'
* or 'parent_of'
*
*/
public String getType() {
return type;
}
/**
* The type of the relationship, one of 'depends_on', 'dependency_of',
* 'derives_from', 'has_derivation', 'links_to', 'linked_from', 'child_of'
* or 'parent_of'
*
*/
public void setType(String type) {
this.type = type;
}
}

View File

@ -0,0 +1,101 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import java.util.HashMap;
import java.util.Map;
import org.gcube.com.fasterxml.jackson.annotation.JsonAnyGetter;
import org.gcube.com.fasterxml.jackson.annotation.JsonAnySetter;
import org.gcube.com.fasterxml.jackson.annotation.JsonProperty;
/**
* For list of errors see <a href="https://github.com/ckan/ckan/blob/master/ckan/controllers/api.py">controllers/api.py</a>.
* For error descriptions see <a href="https://github.com/ckan/ckan/blob/master/ckan/logic/__init__.py">logic/__init__.py</a>
*
* @author David Leoni
*/
public class CkanError {
public static final String AUTHORIZATION_ERROR = "Authorization Error";
public static final String INTEGRITY_ERROR = "Integrity Error";
public static final String NOT_FOUND_ERROR = "Not Found Error";
public static final String SEARCH_QUERY_ERROR = "Search Query Error";
public static final String SEARCH_ERROR = "Search Error";
public static final String SEARCH_INDEX_ERROR = "Search Index Error";
public static final String VALIDATION_ERROR = "Validation Error";
private String message;
/**
* actually the original is __type
*/
private String type;
/**
* Holds fields we can't foresee
*/
private Map<String, Object> others = new HashMap();
@Override
public String toString() {
return "Ckan error of type: " + getType() + " message:" + getMessage() +
" Other fields:" + others.toString();
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
/**
* For types, see {@link CkanError class description}
*/
@JsonProperty("__type")
public String getType() {
return type;
}
/**
* todo what are possible types?
*/
public void setType(String type) {
this.type = type;
}
/**
* Holds fields we can't foresee
*/
@JsonAnyGetter
public Map<String, Object> getOthers() {
return others;
}
/**
* Holds fields we can't foresee
*/
@JsonAnySetter
public void setOthers(String name, Object value) {
others.put(name, value);
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
/**
* Class to explicitly model a Ckan group, which is <i> not </i> an organization,
* although it has the same attributes.
*
* {@link CkanGroupOrgBase} holds fields that can be sent when
* <a href="http://docs.ckan.org/en/latest/api/index.html?#ckan.logic.action.create.group_create" target="_blank">creating
* a group/organization</a>, while {@link CkanGroupOrg} holds more fields that can be
* returned with searches.
*
* This class initializes nothing to fully preserve all we get from ckan. In
* practice, all fields of retrieved resources can be null except maybe
* {@code name}.
*
* @author David Leoni
*/
public class CkanGroup extends CkanGroupOrg {
public CkanGroup() {
super();
setOrganization(false);
}
/**
* Constructor with minimal amount of parameters needed to successfully
* create an instance on the server.
*
* @param name Name in the url, lowercased and without spaces. i.e.
* management-of-territory
*/
public CkanGroup(String name) {
this();
this.setName(name);
}
}

View File

@ -0,0 +1,87 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import java.sql.Timestamp;
/**
* Abstract class with additional fields found during searches of groups and
* organizations.
*
* @author David Leoni
* @since 0.4.1
*/
public abstract class CkanGroupOrg extends CkanGroupOrgBase {
private Timestamp created;
private String displayName;
private String imageDisplayUrl;
private int numFollowers;
private int packageCount;
private String revisionId;
protected CkanGroupOrg(){
super();
}
public Timestamp getCreated() {
return created;
}
public void setCreated(Timestamp created) {
this.created = created;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getImageDisplayUrl() {
return imageDisplayUrl;
}
public void setImageDisplayUrl(String imageDisplayUrl) {
this.imageDisplayUrl = imageDisplayUrl;
}
public int getNumFollowers() {
return numFollowers;
}
public void setNumFollowers(int numFollowers) {
this.numFollowers = numFollowers;
}
public int getPackageCount() {
return packageCount;
}
public void setPackageCount(int packageCount) {
this.packageCount = packageCount;
}
public String getRevisionId() {
return revisionId;
}
public void setRevisionId(String revisionId) {
this.revisionId = revisionId;
}
}

View File

@ -0,0 +1,256 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import static org.gcube.datacatalogue.ckanutillibrary.server.utils.GenericUtils.isNotEmpty;
import java.util.List;
import javax.annotation.Nullable;
import org.gcube.com.fasterxml.jackson.annotation.JsonProperty;
import org.gcube.com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.gcube.datacatalogue.ckanutillibrary.jackan.JackanModule;
/**
* Abstract class to model the same data structure that Ckan uses for creating
* both groups and organizations. Since they are different things and work with
* different APIs we made two different implementations, {@link CkanGroup} and
* {@link CkanOrganization}. The Ckan way to tell the difference is the {@link #isOrganization()
* } field).
*
* @author David Leoni
* @since 0.4.1
*/
public abstract class CkanGroupOrgBase {
private String approvalStatus;
private String description;
private List<CkanPair> extras;
private List<CkanGroup> groups;
private String id;
private String imageUrl;
private String name;
private boolean organization;
@JsonDeserialize(using = JackanModule.GroupOrgPackagesDeserializer.class)
private List<CkanDataset> packages;
private CkanState state;
private String title;
private String type;
private List<CkanUser> users;
protected CkanGroupOrgBase() {
}
/**
* Constructor with minimal amount of parameters needed to successfully
* create an instance on the server.
*
* @param name Name in the url, lowercased and without spaces. i.e.
* management-of-territory
*/
protected CkanGroupOrgBase(String name) {
this.name = name;
}
/**
* can be "approved" or what? Bah
*/
public String getApprovalStatus() {
return approvalStatus;
}
public void setApprovalStatus(String approvalStatus) {
this.approvalStatus = approvalStatus;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<CkanPair> getExtras() {
return extras;
}
public void setExtras(List<CkanPair> extras) {
this.extras = extras;
}
/**
* Have no idea what this could mean inside a group!
*/
public List<CkanGroup> getGroups() {
return groups;
}
public void setGroups(List<CkanGroup> groups) {
this.groups = groups;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
/**
* The URL to an image to be displayed on the group/orgs page (optional)
*/
public String getImageUrl() {
return imageUrl;
}
/**
* The URL to an image to be displayed on the group/orgs page (optional)
*/
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
/**
* Name in the url, lowercased and without spaces. i.e.
* management-of-territory
*/
public String getName() {
return name;
}
/**
* @param name Name in the url, lowercased and without spaces. i.e.
* management-of-territory
*/
public void setName(String name) {
this.name = name;
}
/**
* A ckan group can also be an organization.
*/
@JsonProperty("is_organization")
public boolean isOrganization() {
return organization;
}
/**
* Protected, we use it only when deserializing
*/
@JsonProperty("is_organization")
protected void setOrganization(boolean organization) {
this.organization = organization;
}
/**
* The datasets of the group. Some api return the *number* of packages, in
* this case we set the value to null.
*/
public List<CkanDataset> getPackages() {
return packages;
}
/**
* The datasets of the group. Some api return the *number* of packages, in
* this case we set the value to null.
*/
public void setPackages(List<CkanDataset> packages) {
this.packages = packages;
}
/**
* The current state of the group, e.g. 'active' or 'deleted', only active
* groups show up in search results and other lists of groups, this
* parameter will be ignored if you are not authorized to change the state
* of the group (optional, default: 'active')
*/
public CkanState getState() {
return state;
}
/**
* The current state of the group/organization, e.g. 'active' or 'deleted',
* only active groups/organizations show up in search results and other
* lists of groups/organizations, this parameter will be ignored if you are
* not authorized to change the state (optional, default: 'active')
*/
public void setState(CkanState state) {
this.state = state;
}
/**
* Human readable name, i.e. "Department of Justice"
*
* @see #getName()
*/
public String getTitle() {
return title;
}
/**
* Human readable name, i.e. "Department of Justice"
*
* @see #setName(java.lang.String)
*/
public void setTitle(String title) {
this.title = title;
}
public String getType() {
return type;
}
/**
* Don't know possible ckan types
*/
public void setType(String type) {
this.type = type;
}
public List<CkanUser> getUsers() {
return users;
}
public void setUsers(List<CkanUser> users) {
this.users = users;
}
/**
* Returns the id if non-empty, the name otherwise
*/
@Nullable
public String idOrName() {
return isNotEmpty(getId()) ? getId() : getName();
}
/**
* Returns the name if non-empty, the id otherwise
*/
@Nullable
public String nameOrId() {
return isNotEmpty(getName()) ? getName() : getId();
}
}

View File

@ -0,0 +1,233 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import org.gcube.com.fasterxml.jackson.annotation.JsonProperty;
/**
*
* @author David Leoni
* @since 0.4.1
*/
public class CkanLicense {
private String status;
private String maintainer;
private String family;
private String title;
private boolean domainData;
private boolean okdCompliant;
private boolean domainContent;
private String url;
private boolean osiCompliant;
private boolean domainSoftware;
/**
* i.e. "cc-zero"
*/
private String id;
public CkanLicense() {
}
/**
* Returns true if it complies with the OpenDefinition:
* http://opendefinition.org/
*/
@JsonProperty("is_okd_compliant")
public boolean isOkdCompliant() {
return okdCompliant;
}
/**
* @param okdCompliant True if it complies with the OpenDefinition:
* http://opendefinition.org/
*
* @see #setOsiCompliant(boolean)
*/
public void setOkdCompliant(boolean okdCompliant) {
this.okdCompliant = okdCompliant;
}
/**
* Returns true if it complies with the Open Source Initiative?
* http://opensource.org/licenses
*/
@JsonProperty("is_osi_compliant")
public boolean isOsiCompliant() {
return osiCompliant;
}
/**
*
* @param osiCompliant True if it complies with the Open Source Initiative?
* http://opensource.org/licenses
*
* @see #setOkdCompliant(boolean)
*/
public void setOsiCompliant(boolean osiCompliant) {
this.osiCompliant = osiCompliant;
}
/**
* Returns true if the license applies to content domain.
*
* @see #isDomainSoftware()
* @see #isDomainData()
*/
@JsonProperty("domain_content")
public boolean isDomainContent() {
return domainContent;
}
/**
* @param domainContent True if the license applies to content domain.
*
* @see #setDomainSoftware(boolean)
* @see #setDomainData(boolean)
*/
public void setDomainContent(boolean domainContent) {
this.domainContent = domainContent;
}
/**
* True if the license applies to data domain.
*
* @see #isDomainContent()
* @see #isDomainSoftware()
*/
@JsonProperty("domain_data")
public boolean isDomainData() {
return domainData;
}
/**
* @param domainData True if the license applies to data domain.
*
* @see #setDomainSoftware(boolean)
* @see #setDomainContent(boolean)
*/
public void setDomainData(boolean domainData) {
this.domainData = domainData;
}
/**
* True if the license applies to software domain.
*
* @see #isDomainContent()
* @see #isDomainData()
*/
@JsonProperty("domain_software")
public boolean isDomainSoftware() {
return domainSoftware;
}
/**
* @param domainSoftware True if the license applies to software domain.
*
* @see #setDomainData(boolean)
* @see #setDomainContent(boolean)
*/
public void setDomainSoftware(boolean domainSoftware) {
this.domainSoftware = domainSoftware;
}
/**
* Gets the status, i.e. "active" todo check possaible status
*/
public String getStatus() {
return status;
}
/**
* Sets the status, i.e. "active" todo check possaible status
*/
public void setStatus(String status) {
this.status = status;
}
public String getMaintainer() {
return maintainer;
}
public void setMaintainer(String maintainer) {
this.maintainer = maintainer;
}
public String getFamily() {
return family;
}
public void setFamily(String family) {
this.family = family;
}
/**
* Gets the title, i.e. "Creative Commons CCZero"
*/
public String getTitle() {
return title;
}
/**
* Sets the title, i.e. "Creative Commons CCZero"
*
* @param title
*/
public void setTitle(String title) {
this.title = title;
}
/**
* Returns the url of a document describing the license i.e.
* "http://creativecommons.org/publicdomain/zero/1.0/deed.it",
*/
public String getUrl() {
return url;
}
/**
* Sets the url of a document describing the license i.e.
* "http://creativecommons.org/publicdomain/zero/1.0/deed.it",
*/
public void setUrl(String url) {
this.url = url;
}
/**
* Returns the id of the license as used by ckan, i.e. "cc-zero"
*/
public String getId() {
return id;
}
/**
* Sets the id of the license as used by ckan, i.e. "cc-zero"
*/
public void setId(String id) {
this.id = id;
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
/**
* Class to explicitly model a Ckan organization, which is <i> not </i> a group,
* although it has the same attributes.
*
* {@link CkanGroupOrgBase} holds fields that can be sent when
* <a href="http://docs.ckan.org/en/latest/api/index.html?#ckan.logic.action.create.organization_create" target="_blank">creating
* a group/organization</a>, while {@link CkanGroupOrg} holds more fields that can be
* returned with searches.
*
* This class initializes nothing to fully preserve all we get from ckan. In
* practice, all fields of retrieved resources can be null except maybe
* {@code name}.
*
* @author David Leoni
*/
public class CkanOrganization extends CkanGroupOrg {
public CkanOrganization() {
super();
setOrganization(true);
}
/**
* Constructor with minimal amount of parameters needed to successfully
* create an instance on the server.
*
* @param name Name in the url, lowercased and without spaces. i.e.
* management-of-territory
*/
public CkanOrganization(String name) {
this();
this.setName(name);
}
}

View File

@ -0,0 +1,85 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import java.util.Objects;
import javax.annotation.Nullable;
/**
* For key/value pairs present in extras field. Implements equals and hashCode.
*
* @author David Leoni
*/
public class CkanPair {
private String key;
@Nullable
private String value;
public CkanPair() {
}
public CkanPair(String key, @Nullable String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
@Nullable
public String getValue() {
return value;
}
public void setValue(@Nullable String value) {
this.value = value;
}
@Override
public int hashCode() {
int hash = 3;
hash = 97 * hash + Objects.hashCode(this.key);
hash = 97 * hash + Objects.hashCode(this.value);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final CkanPair other = (CkanPair) obj;
if (!Objects.equals(this.key, other.key)) {
return false;
}
if (!Objects.equals(this.value, other.value)) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,134 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import javax.annotation.Nullable;
/**
* Extends {@link CkanResourceBase} with fields found in search operations.
*/
public class CkanResource extends CkanResourceBase {
private String resourceGroupId;
private String owner;
private int position;
private String revisionTimestamp;
private CkanTrackingSummary trackingSummary;
private CkanState state;
private String urlType;
public CkanResource() {
}
/**
*
* @see CkanResourceBase#CkanResourceBase(String, String)
*/
public CkanResource(String url, String packageId) {
super(url, packageId);
}
/**
* todo - What the hell is this? alphanumerical id, i.e.
* "fd6375cd-1d6a-41e8-8e10-460a11e2308e"
*/
public String getResourceGroupId() {
return resourceGroupId;
}
/**
* todo - What the hell is this? alphanumerical id, i.e.
* "fd6375cd-1d6a-41e8-8e10-460a11e2308e"
*/
public void setResourceGroupId(String resourceGroupId) {
this.resourceGroupId = resourceGroupId;
}
/**
* Username of the owner
*/
@Nullable
public String getOwner() {
return owner;
}
/**
* @param owner Username of the owner
*/
public void setOwner(@Nullable String owner) {
this.owner = owner;
}
/**
* Position inside the dataset?
*/
public int getPosition() {
return position;
}
/**
* @param position Position inside the dataset?
*/
public void setPosition(int position) {
this.position = position;
}
/**
*
*/
public String getRevisionTimestamp() {
return revisionTimestamp;
}
/**
*
*/
public void setRevisionTimestamp(@Nullable String revisionTimestamp) {
this.revisionTimestamp = revisionTimestamp;
}
public CkanState getState() {
return state;
}
public void setState(CkanState state) {
this.state = state;
}
public CkanTrackingSummary getTrackingSummary() {
return trackingSummary;
}
public void setTrackingSummary(CkanTrackingSummary trackingSummary) {
this.trackingSummary = trackingSummary;
}
/**
* todo - Don't know what it is
*/
public String getUrlType() {
return urlType;
}
/**
* todo - Don't know what it is
*/
public void setUrlType(String urlType) {
this.urlType = urlType;
}
}

View File

@ -0,0 +1,490 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import java.io.File;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
import org.gcube.com.fasterxml.jackson.annotation.JsonAnyGetter;
import org.gcube.com.fasterxml.jackson.annotation.JsonAnySetter;
import org.gcube.com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions.JackanException;
import org.slf4j.Logger;
/**
*
* A Ckan Resource describes with metadata a physical file, which may reside
* outside ckan. Resources are part of {@link CkanDataset}. In DCAT terminology,
* a Ckan Resource is a DCAT Distribution.
*
* {@link CkanResourceBase} holds fields that can be sent when
* <a href="http://docs.ckan.org/en/latest/api/index.html?#ckan.logic.action.create.resource_create" target="_blank">creating
* a resource,</a>, while {@link CkanResource} holds more fields that can be
* returned with searches.
*
* This class initializes nothing to fully preserve all we get from ckan. In
* practice, all fields of retrieved resources can be null except maybe
* {@code url}.
*
* @author David Leoni
* @since 0.4.1
*/
@JsonIgnoreProperties({"upload"})
public class CkanResourceBase {
private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(CkanResourceBase.class.getName());
private String cacheLastUpdated;
private String cacheUrl;
private Timestamp created;
private String description;
private String format;
private String hash;
private String id;
private String lastModified;
private String mimetype;
private String mimetypeInner;
private String name;
private String resourceType;
private String revisionId;
private String size;
private String url;
private File upload;
private Timestamp webstoreLastUpdated;
private String webstoreUrl;
/**
* The dataset this resource belongs to. Not present when getting resources
* but needed when uploading them.
*/
private String packageId;
/**
* See {@link #getOthers()}
*/
private Map<String, Object> others;
/**
* The dataset this resource belongs to. Latest ckan give it back, but older ones
* may return {@code null}. Required when creating resources.
*/
@Nullable
public String getPackageId() {
return packageId;
}
/**
* The dataset this resource belongs to. Latest ckan give it back, but older ones
* may return {@code null}. Required when creating resources.
*
* @param packageId the dataset this resource belongs to.
*/
public void setPackageId(@Nullable String packageId) {
this.packageId = packageId;
}
public CkanResourceBase() {
}
/**
* Constructor with the minimal list of required items to successfully
* create a resource on the server.
*
* @param url the Url to the pyhsical file i.e.
* http://dati.trentino.it/storage/f/2013-05-09T140831/TRENTO_Laghi_monitorati_UTM.csv
* (could also be a file outside ckan server)
* @param packageId id of the dataset that contains the resource
*/
public CkanResourceBase(String url,
String packageId) {
this();
this.url = url;
this.packageId = packageId;
}
/**
* CKAN instances might have
* <a href="http://docs.ckan.org/en/latest/extensions/adding-custom-fields.html">
* custom data schemas</a> that force presence of custom properties among
* 'regular' ones. In this case, they go to 'others' field. Notice that
* differently from dataset a resource down't have 'extras' field.
*
* @see #putOthers(java.lang.String, java.lang.Object)
*/
@JsonAnyGetter
@Nullable
public Map<String, Object> getOthers() {
return others;
}
/**
* @param others
* @see #getOthers()
* @see #putOthers(java.lang.String, java.lang.Object)
*/
public void setOthers(@Nullable Map<String, Object> others) {
this.others = others;
}
/**
* See {@link #getOthers()}
*
* @see #setOthers(java.util.Map)
*/
@JsonAnySetter
public void putOthers(String name, Object value) {
if (others == null) {
others = new HashMap();
}
others.put(name, value);
}
/**
* Should be a Timestamp
*/
public String getCacheLastUpdated() {
return cacheLastUpdated;
}
/**
* Should be a Timestamp
*/
public void setCacheLastUpdated(@Nullable String cacheLastUpdated) {
this.cacheLastUpdated = cacheLastUpdated;
}
/**
* God only knows what this is
*/
@Nullable
public String getCacheUrl() {
return cacheUrl;
}
/**
* God only knows what this is
*/
public void setCacheUrl(String cacheUrl) {
this.cacheUrl = cacheUrl;
}
/**
* In JSON is something like this: i.e. "2013-05-09T14:08:32.666477" . Ckan
* always refers to UTC timezone
*/
public Timestamp getCreated() {
return created;
}
/**
* Ckan always refers to UTC timezone
*/
public void setCreated(Timestamp created) {
this.created = created;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
/**
* In Ckan 1.8 was lowercase, 2.2a seems capitalcase.
*/
public String getFormat() {
return format;
}
/**
* In Ckan 1.8 was lowercase, 2.2a seems capitalcase.
*/
public void setFormat(String format) {
this.format = format;
}
/**
* Sometimes for dati.trentino.it can be the empty string
*/
public String getHash() {
return hash;
}
/**
* Sometimes for dati.trentino.it can be the empty string
*/
public void setHash(String hash) {
this.hash = hash;
}
/**
* Returns the alphanumerical id, i.e.
* "c4577b8f-5603-4098-917e-da03e8ddf461"
*/
public String getId() {
return id;
}
/**
* @param id alphanumerical id, i.e. "c4577b8f-5603-4098-917e-da03e8ddf461"
*/
public void setId(String id) {
this.id = id;
}
/**
* Jackan note: this field should represent the timestamp of the last update
* of the resource *data*, not metadata. I think it's set by extensions and
* harvesters. Notice Ckan always refers to UTC timezone in
* {@link eu.trentorise.opendata.jackan.CkanClient#CKAN_TIMESTAMP_PATTERN} format, so this field probably
* should follow the same format.
*/
public String getLastModified() {
return lastModified;
}
/**
* Jackan note: this field should represent the timestamp of the last update
* of the resource *data*, not metadata. I think it's set by extensions and
* harvesters. Notice Ckan always refers to UTC timezone in
* {@link eu.trentorise.opendata.jackan.CkanClient#CKAN_TIMESTAMP_PATTERN} format, so this field probably
* should follow the same format.
*/
public void setLastModified(String lastModified) {
this.lastModified = lastModified;
}
/**
* i.e. text/csv
*/
public String getMimetype() {
return mimetype;
}
/**
* i.e. text/csv
*/
public void setMimetype(String mimetype) {
this.mimetype = mimetype;
}
/**
* Unknown meaning, as usual. Can be the empty string or null
*/
public String getMimetypeInner() {
return mimetypeInner;
}
/**
* Unknown meaning, as usual. Can be the empty string or null
*/
public void setMimetypeInner(@Nullable String mimetypeInner) {
this.mimetypeInner = mimetypeInner;
}
/**
*
* Human readable name, i.e. "Apple Production 2013 in CSV format". Not to
* be confused with {@link CkanDataset#name} which instead is lowercased and
* intended to be part of the url.
*
*
* Notice we found name null in data.gov.uk datasets... i.e.
* <a href="http://data.gov.uk/api/3/action/resource_show?id=77d2dba8-d0d9-49ef-9fd2-37a4a8bc5a17" target="_blank">
* unclaimed-estates-list </a>, taken
* <a href="http://data.gov.uk/api/3/action/package_search?rows=20&start=0" target="_blank">from
* this dataset search</a> (They use description field instead)
*/
@Nullable
public String getName() {
return name;
}
/**
* Human readable name, i.e. "Apple Production 2013 in CSV format". Not to
* be confused with {@link CkanDataset#name} which instead is lowercased and
* intended to be part of the url. For Nullable explanation see
* {@link #getName()}
*/
public void setName(@Nullable String name) {
this.name = name;
}
/**
* So far, found: "api", "file", "file.upload"
*/
public String getResourceType() {
return resourceType;
}
/**
* So far, found: "api", "file", "file.upload"
*/
public void setResourceType(String resourceType) {
this.resourceType = resourceType;
}
/**
* alphanumerical id, i.e. 0c949f17-d123-4379-8536-cfcf25b3b0e9
*/
public String getRevisionId() {
return revisionId;
}
/**
* alphanumerical id, i.e. 0c949f17-d123-4379-8536-cfcf25b3b0e9
*/
public void setRevisionId(String revisionId) {
this.revisionId = revisionId;
}
/**
* File size in bytes, if calculated by ckan for files in storage, like i.e.
* "242344". Otherwise it can be anything a human can insert.
*/
public String getSize() {
return size;
}
/**
* File size in bytes, if calculated by ckan for files in storage, like i.e.
* "242344". Otherwise it can be anything a human can insert.
*/
public void setSize(@Nullable String size) {
this.size = size;
}
/**
* The Url to the pyhsical file i.e.
* http://dati.trentino.it/storage/f/2013-05-09T140831/TRENTO_Laghi_monitorati_UTM.csv
* (could also be a file outside ckan server)
*/
public String getUrl() {
return url;
}
/**
* The Url to the pyhsical file i.e.
* http://dati.trentino.it/storage/f/2013-05-09T140831/TRENTO_Laghi_monitorati_UTM.csv
* (could also be a file outside ckan server)
*/
public void setUrl(String url) {
this.url = url;
}
/**
* The file to be added to the resource. See {@link #setUpload(File, boolean)} for further info.
*
* @since 0.4.3
*/
public File getUpload() {
return upload;
}
/**
* Sets the file to upload.
*
* @param upload the File to upload.
* @deprecated Put here only to have a bean-style setter,
* if possible prefer calling {@link #setUpload(File, boolean)}
*
* @since 0.4.3
*/
public void setUpload(@Nullable File upload){
this.setUpload(upload, false);
}
/**
* A file to be added to the resource.
*
* @param upload
* the file to upload. Its {@link #getSize() size} is automatically set. If passed file is {@code null},
* reset upload and size fields.
* @param guessMimeTypeAndFormat
* whether automatic guessing of {@link #getMimetype() mime type} and {@link #getFormat() format} is done.
*
* @throws JackanException
* if asked for automatic guessing of mime type and format but those could not be guessed.
*
* @since 0.4.3
*/
public void setUpload(@Nullable File upload, boolean guessMimeTypeAndFormat) {
LOG.error("Set UPLOAD IS NOT IMPLEMENTED!");
// if (upload == null) {
// this.upload = null;
// this.size = null;
// } else {
// this.upload = upload;
// this.size = String.valueOf(upload.length());
// if (guessMimeTypeAndFormat) {
// try (InputStream is = new FileInputStream(upload);
// BufferedInputStream bis = new BufferedInputStream(is);) {
// AutoDetectParser parser = new AutoDetectParser();
// Metadata md = new Metadata();
// md.add(Metadata.RESOURCE_NAME_KEY, upload.getName());
// MediaType mediaType = parser.getDetector().detect(bis, md);
// this.mimetype = mediaType.getBaseType().toString();
// this.format = mediaType.getSubtype().toUpperCase();
// } catch (FileNotFoundException e) {
// LOG.log(Level.WARNING, "Unable to load file {0}", upload.getName());
// throw new JackanException("Unable to load file " + upload.getName(), e);
// } catch (IOException e) {
// LOG.log(Level.WARNING, "Unable to detect mime type and format for file " + upload.getName(), e);
// throw new JackanException("Unable to detect mime type and format for file " + upload.getName(), e);
// }
// }
// }
}
/**
* Ckan always refers to UTC timezone
*/
public Timestamp getWebstoreLastUpdated() {
return webstoreLastUpdated;
}
/**
* Ckan always refers to UTC timezone
*/
public void setWebstoreLastUpdated(Timestamp webstoreLastUpdated) {
this.webstoreLastUpdated = webstoreLastUpdated;
}
/**
* Found "active" as value. Maybe it is a CkanState?
*/
public String getWebstoreUrl() {
return webstoreUrl;
}
/**
* @param webstoreUrl Found "active" as value. Maybe it is a CkanState?
*/
public void setWebstoreUrl(String webstoreUrl) {
this.webstoreUrl = webstoreUrl;
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
/**
*
* @author David Leoni
*/
public class CkanResponse {
private String help;
private boolean success;
private CkanError error;
public CkanResponse() {
}
public CkanResponse(String help, boolean success, CkanError error) {
this.help = help;
this.success = success;
this.error = error;
}
public String getHelp() {
return help;
}
public void setHelp(String help) {
this.help = help;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public CkanError getError() {
return error;
}
public void setError(CkanError error) {
this.error = error;
}
@Override
public String toString() {
return "CkanResponse{error=" + error+ ", success=" + success + ", help=" + help + '}';
}
}

View File

@ -0,0 +1,31 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
/**
* Possible states of a Dataset or Resource - only active datasets show up in
* search results and other lists of datasets
*
* @author David Leoni
*/
public enum CkanState {
/**
* Means element shows up in search results
*/
active,
deleted
}

View File

@ -0,0 +1,92 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import java.sql.Timestamp;
import javax.annotation.Nullable;
/**
* Extends {@link CkanTagBase} with fields found in search operations.
*/
public class CkanTag extends CkanTagBase {
private String displayName;
private Timestamp revisionTimestamp;
private CkanState state;
public CkanTag() {
super();
}
/**
* You can use this constructor when adding a free tag to a dataset.
*
* @param name the name for the new tag, a string between 2 and 100
* characters long containing only alphanumeric characters and -, _ and .,
* e.g. 'Jazz'
*/
public CkanTag(String name) {
super(name);
}
/**
* You can use this constructor when creating a tag associated to a
* controlled vocabulary
*
* @param name the name for the new tag, a string between 2 and 100
* characters long containing only alphanumeric characters and -, _ and .,
* e.g. 'Jazz'
*/
public CkanTag(String name, String vocabularyId) {
super(name, vocabularyId);
}
/**
*
* @return a human readable name, i.e. "Habitat Quality"
*/
public String getDisplayName() {
return displayName;
}
/**
*
* @param displayName a human readable name, i.e. "Habitat Quality"
*/
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
@Nullable
public Timestamp getRevisionTimestamp() {
return revisionTimestamp;
}
public void setRevisionTimestamp(@Nullable Timestamp revisionTimestamp) {
this.revisionTimestamp = revisionTimestamp;
}
public CkanState getState() {
return state;
}
public void setState(CkanState state) {
this.state = state;
}
}

View File

@ -0,0 +1,108 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
/**
* A Ckan Tag. Tags can be free or belong to a controlled vocabulary.
*
* {@link CkanTag} holds fields that can be sent when
* <a href="http://docs.ckan.org/en/latest/api/index.html?#ckan.logic.action.create.tag_create" target="_blank">creating
* a tag</a>, while {@link CkanTag} holds more fields that can be returned with
* searches. Notice free tags can be created by just adding them to a dataset to
* create.
*
* This class initializes nothing to fully preserve all we get from ckan. In
* practice, all fields of retrieved resources can be null except maybe
* {@code name}.
*
* @author David Leoni
* @since 0.4.1
*/
public class CkanTagBase {
private String id;
private String name;
private String vocabularyId;
public CkanTagBase() {
}
/**
* You can use this constructor when adding a free tag to a dataset.
*
* @param name the name for the new tag, a string between 2 and 100
* characters long containing only alphanumeric characters and -, _ and .,
* e.g. 'Jazz'
*/
public CkanTagBase(String name) {
this();
this.name = name;
}
/**
* You can use this constructor when creating a tag associated to a
* controlled vocabulary
*
* @param name the name for the new tag, a string between 2 and 100
* characters long containing only alphanumeric characters and -, _ and .,
* e.g. 'Jazz'
*/
public CkanTagBase(String name, String vocabularyId) {
this(name);
this.vocabularyId = vocabularyId;
}
/**
*
* @return alphanumerical id, i.e. "7f0aa2fe-9733-4ce2-a351-d10278ba44ac"
*/
public String getId() {
return id;
}
/**
*
* @param id alphanumerical id, i.e. "7f0aa2fe-9733-4ce2-a351-d10278ba44ac"
*/
public void setId(String id) {
this.id = id;
}
/**
*
* @return a human readable name, i.e. "Habitat Quality"
*/
public String getName() {
return name;
}
/**
*
* @param name a human readable name, i.e. "Habitat Quality"
*/
public void setName(String name) {
this.name = name;
}
public String getVocabularyId() {
return vocabularyId;
}
public void setVocabularyId(String vocabularyId) {
this.vocabularyId = vocabularyId;
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
/**
* Just don't know what it is.
*
* @author David Leoni
*/
public class CkanTrackingSummary {
private int recent;
private int total;
public CkanTrackingSummary() {
}
public int getRecent() {
return recent;
}
public void setRecent(int recent) {
this.recent = recent;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
}

View File

@ -0,0 +1,169 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import java.sql.Timestamp;
import java.util.List;
import javax.annotation.Nullable;
/**
*
*
* @author David Leoni
*/
public class CkanUser extends CkanUserBase {
private List<CkanActivity> activity;
private boolean activityStreamsEmailNotifications;
private Timestamp created;
private String capacity;
private String displayName;
private String emailHash;
private int numberAdministeredPackages;
private int numFollowers;
private int numberOfEdits;
private CkanState state;
private boolean sysadmin;
public CkanUser() {
super();
}
/**
* Constructor with the minimal amount of fields required for a successful
* creation.
*
* @param name the name of the new user, a string between 2 and 100
* characters in length, containing only lowercase alphanumeric characters,
* - and _
*/
public CkanUser(String name, String email, String password) {
super(name, email, password);
}
public boolean isActivityStreamsEmailNotifications() {
return activityStreamsEmailNotifications;
}
public void setActivityStreamsEmailNotifications(boolean activityStreamsEmailNotifications) {
this.activityStreamsEmailNotifications = activityStreamsEmailNotifications;
}
/**
* Ckan uses UTC timezone
*/
public Timestamp getCreated() {
return created;
}
/**
* Ckan uses UTC timezone
*/
public void setCreated(Timestamp created) {
this.created = created;
}
/**
* i.e. David Leoni
*/
public String getDisplayName() {
return displayName;
}
/**
* i.e. David Leoni
*/
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getEmailHash() {
return emailHash;
}
public void setEmailHash(String emailHash) {
this.emailHash = emailHash;
}
public int getNumberAdministeredPackages() {
return numberAdministeredPackages;
}
public void setNumberAdministeredPackages(int numberAdministeredPackages) {
this.numberAdministeredPackages = numberAdministeredPackages;
}
public int getNumberOfEdits() {
return numberOfEdits;
}
public void setNumberOfEdits(int numberOfEdits) {
this.numberOfEdits = numberOfEdits;
}
public CkanState getState() {
return state;
}
public void setState(CkanState state) {
this.state = state;
}
public boolean isSysadmin() {
return sysadmin;
}
public void setSysadmin(boolean sysadmin) {
this.sysadmin = sysadmin;
}
/**
* You can obtain it with getUser(id)
*/
public List<CkanActivity> getActivity() {
return activity;
}
/**
* You can obtain it with getUser(id)
*/
public void setActivity(List<CkanActivity> activity) {
this.activity = activity;
}
/**
* i.e. "admin"
*/
public String getCapacity() {
return capacity;
}
/**
* i.e. "admin"
*/
public void setCapacity(@Nullable String capacity) {
this.capacity = capacity;
}
public Integer getNumFollowers() {
return numFollowers;
}
public void setNumFollowers(@Nullable Integer numFollowers) {
this.numFollowers = numFollowers;
}
}

View File

@ -0,0 +1,159 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import javax.annotation.Nullable;
/*
* A Ckan User. Hopefully a happy one.
*
* {@link CkanUserBase} holds fields that can be sent when
* <a href="http://docs.ckan.org/en/latest/api/index.html?#ckan.logic.action.create.user_create" target="_blank">creating
* a user,</a>, while {@link CkanUser} holds more fields that can be returned
* with searches.
*
* This class initializes nothing to fully preserve all we get from ckan. In
* practice, all fields of retrieved resources can be null except maybe
* {@code name}.
* @since 0.4.1
*/
public class CkanUserBase {
private String about;
private String fullname;
private String email;
private String id;
private String name;
private String openid;
private String password;
public CkanUserBase() {
}
/**
* Constructor with the minimal amount of fields required for a successful
* creation.
*
* @param name the name of the new user, a string between 2 and 100
* characters in length, containing only lowercase alphanumeric characters,
* - and _
*/
public CkanUserBase(String name, String email, String password) {
this();
this.email = email;
this.name = name;
this.password = password;
}
/**
* A description of the new user
*/
public String getAbout() {
return about;
}
/**
* A description of the new user
*/
public void setAbout(@Nullable String about) {
this.about = about;
}
/**
* Only used when creating the user.
*/
public String getEmail() {
return email;
}
/**
* Only used when creating the user.
*/
public void setEmail(String email) {
this.email = email;
}
/**
* Seems quite useless something like i.e. Mr David Leoni the Third ?
*/
public String getFullname() {
return fullname;
}
/**
* Seems quite useless something like i.e. Mr David Leoni the Third ?
*/
public void setFullname(@Nullable String fullname) {
this.fullname = fullname;
}
/**
* Alphanumerical id. i.e. "01ab5c4e-6d6b-46bc-8cn7-e37drs9aeb00"
*/
public String getId() {
return id;
}
/**
* Alphanumerical id. i.e. "01ab5c4e-6d6b-46bc-8cn7-e37drs9aeb00"
*/
public void setId(String id) {
this.id = id;
}
/**
* The name of the new user, a string between 2 and 100 characters in
* length, containing only lowercase alphanumeric characters, - and _ (i.e.
* david_leoni)
*/
public String getName() {
return name;
}
/**
* The name of the new user, a string between 2 and 100 characters in
* length, containing only lowercase alphanumeric characters, - and _ (i.e.
* david_leoni)
*/
public void setName(String name) {
this.name = name;
}
public String getOpenid() {
return openid;
}
public void setOpenid(@Nullable String openid) {
this.openid = openid;
}
/**
* The password of the new user, a string of at least 4 characters. Only
* available when creating the user.
*/
public String getPassword() {
return password;
}
/**
* The password of the new user, a string of at least 4 characters. Only
* available when creating the user.
*/
public void setPassword(String password) {
this.password = password;
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import java.util.List;
/**
*
* @author David Leoni
* @since 0.4.1
*/
public class CkanVocabulary extends CkanVocabularyBase {
public CkanVocabulary() {
super();
}
/**
* Constructor with required fields for vocabulary creation.
* @param name the name of the new vocabulary, e.g. 'Genre'
* @param tags
*/
public CkanVocabulary(String name, List<CkanTag> tags) {
super(name, tags);
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model;
import java.util.List;
/**
*
* @author David Leoni
* @since 0.4.1
*/
public class CkanVocabularyBase {
private String id;
private String name;
private List<CkanTag> tags;
public CkanVocabularyBase() {
}
/**
* Constructor with required fields for vocabulary creation.
* @param name the name of the new vocabulary, e.g. 'Genre'
* @param tags
*/
public CkanVocabularyBase(String name, List<CkanTag> tags) {
this();
this.name = name;
this.tags = tags;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
/**
* The name of the new vocabulary, e.g. 'Genre'
*/
public String getName() {
return name;
}
/**
* The name of the new vocabulary, e.g. 'Genre'
*/
public void setName(String name) {
this.name = name;
}
public List<CkanTag> getTags() {
return tags;
}
public void setTags(List<CkanTag> tags) {
this.tags = tags;
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions;
import org.gcube.datacatalogue.ckanutillibrary.jackan.CkanClient;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanResponse;
/**
* Exception raised when the user is not authorized to call the action.
*
* @author David Leoni
* @since 0.4.3
*/
public class CkanAuthorizationException extends CkanException {
public CkanAuthorizationException(String msg, CkanClient client, Throwable ex) {
super(msg, client, ex);
}
public CkanAuthorizationException(String msg, CkanClient client) {
super(msg, client);
}
public CkanAuthorizationException(String msg, CkanResponse ckanResponse, CkanClient client) {
super(msg, ckanResponse, client);
}
public CkanAuthorizationException(String msg, CkanResponse ckanResponse, CkanClient client, Throwable ex) {
super(msg, ckanResponse, client, ex);
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions;
import javax.annotation.Nullable;
import org.gcube.datacatalogue.ckanutillibrary.jackan.CkanClient;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanResponse;
/**
* Runtime exception for ckan-related problems. For possible cases description, see {@link eu.trentorise.opendata.jackan.model.CkanError CkanError}
*
* @author David Leoni
*/
public class CkanException extends JackanException {
@Nullable
private CkanResponse ckanResponse = null;
@Nullable
private CkanClient ckanClient = null;
private static String makeMessage(String msg, @Nullable CkanResponse ckanResponse, @Nullable CkanClient client) {
return msg + " "
+ (ckanResponse != null ? ckanResponse + " " : "")
+ (client != null ? client : "");
}
public CkanException(String msg, CkanClient client) {
super(makeMessage(msg, null, client));
this.ckanClient = client;
}
public CkanException(String msg, CkanResponse ckanResponse, CkanClient client) {
super(makeMessage(msg, ckanResponse, client));
this.ckanResponse = ckanResponse;
this.ckanClient = client;
}
public CkanException(String msg, CkanClient client, Throwable ex) {
this(msg, null, client, ex);
}
public CkanException(String msg, CkanResponse ckanResponse, CkanClient client, Throwable ex) {
super(makeMessage(msg, ckanResponse, client),
ex);
this.ckanResponse = ckanResponse;
this.ckanClient = client;
}
@Nullable
public CkanResponse getCkanResponse() {
return ckanResponse;
}
@Nullable
public CkanClient getCkanClient() {
return ckanClient;
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions;
import org.gcube.datacatalogue.ckanutillibrary.jackan.CkanClient;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanResponse;
/**
* Thrown when Ckan tells us something was not found. Notice this is not related
* to more generic {@link JackanNotFoundException}
*
* @author David Leoni
*/
public class CkanNotFoundException extends CkanException {
public CkanNotFoundException(String msg, CkanResponse ckanResponse, CkanClient client) {
super(msg, ckanResponse, client);
}
public CkanNotFoundException(String msg, CkanResponse ckanResponse, CkanClient client, Throwable ex) {
super(msg, ckanResponse, client, ex);
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions;
import org.gcube.datacatalogue.ckanutillibrary.jackan.CkanClient;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanResponse;
/**
* Thrown when Ckan tells us something was not in the proper format.
*
* @author David Leoni
*/
public class CkanValidationException extends CkanException {
public CkanValidationException(String msg, CkanClient client, Throwable ex) {
super(msg, client, ex);
}
public CkanValidationException(String msg, CkanClient client) {
super(msg, client);
}
public CkanValidationException(String msg, CkanResponse ckanResponse, CkanClient client) {
super(msg, ckanResponse, client);
}
public CkanValidationException(String msg, CkanResponse ckanResponse, CkanClient client, Throwable ex) {
super(msg, ckanResponse, client, ex);
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright 2015 Trento Rise (trentorise.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions;
/**
* Generic Jackan Runtime Exception.
*
* @author David Leoni
*/
public class JackanException extends RuntimeException {
public JackanException(String msg) {
super(msg);
}
public JackanException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright 2015 Trento Rise.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.exceptions;
/**
* A runtime exception to raise when something is not found. Note this is not
* related to ckan specific {@link CkanNotFoundException}
*
* @author David Leoni <david.leoni@unitn.it>
*/
public class JackanNotFoundException extends JackanException {
/**
* Creates the JackanNotFoundException using the provided message
*/
public JackanNotFoundException(String msg) {
super(msg);
}
/**
* Creates the JackanNotFoundException using the provided message and throwable
*/
public JackanNotFoundException(String msg, Throwable tr) {
super(msg, tr);
}
}

View File

@ -14,13 +14,15 @@ import org.gcube.datacatalogue.ckanutillibrary.server.ApplicationProfileScopePer
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueFactory;
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueImpl;
import org.gcube.datacatalogue.ckanutillibrary.shared.ResourceBean;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanDataset;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanGroup;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanOrganization;
import org.gcube.datacatalogue.ckanutillibrary.shared.jackan.model.CkanUser;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import eu.trentorise.opendata.jackan.model.CkanGroup;
import eu.trentorise.opendata.jackan.model.CkanOrganization;
import eu.trentorise.opendata.jackan.model.CkanUser;
/**
* The Class TestDataCatalogueLib.
@ -87,7 +89,7 @@ public class TestDataCatalogueLib {
public void getScopePerUrl(){
ScopeProvider.instance.set(scope);
String url = "https://dev4.d4science.org/group/devvre/ckan";
String url = "https://dev2.d4science.org/group/devvre/ckan";
String scopeToUse = ApplicationProfileScopePerUrlReader.getScopePerUrl(url);
LOG.debug("Retrieved scope is " + scopeToUse);
@ -222,8 +224,8 @@ public class TestDataCatalogueLib {
ScopeProvider.instance.set(scope);
SecurityTokenProvider.instance.set(authorizationToken);
DataCatalogueImpl instance = factory.getUtilsPerScope(scope);
DataCatalogueImpl instance = factory.getUtilsPerScope(scope);
String licenseId = instance.getLicenses().get(0).getId();
Map<String, List<String>> customFieldsMultiple = new HashMap<String, List<String>>();
@ -236,6 +238,8 @@ public class TestDataCatalogueLib {
customFieldsMultiple.put("key-random-"+new Random().nextInt(10), values);
}
customFieldsMultiple.put("empty-key", Arrays.asList(""));
customFieldsMultiple.put("system:type", Arrays.asList("EmptyProfile"));
boolean setSearchable = true;
@ -268,7 +272,7 @@ public class TestDataCatalogueLib {
setSearchable,
true);
LOG.info(createdDataset);
LOG.info("Created the dataset with id: " +createdDataset);
}catch (Exception e) {
e.printStackTrace();
}
@ -277,8 +281,10 @@ public class TestDataCatalogueLib {
//@Test
public void createGroup() throws Exception{
ScopeProvider.instance.set(scope);
SecurityTokenProvider.instance.set(authorizationToken);
DataCatalogueImpl instance = factory.getUtilsPerScope(scope);
int random = new Random().nextInt();
String groupTitle = "a grop created by catalogue-util-library "+random;
@ -286,6 +292,22 @@ public class TestDataCatalogueLib {
CkanGroup ckanGroup = instance.createGroup(groupName, groupTitle, "description");
LOG.info("Created the group: "+ckanGroup);
}
@Test
public void testAddResource() throws Exception{
ScopeProvider.instance.set(scope);
SecurityTokenProvider.instance.set(authorizationToken);
DataCatalogueImpl instance = factory.getUtilsPerScope(scope);
CkanDataset dataset = instance.getDataset("adatasetcreatedbycatalogue-util-library-873805063", null);
for (int i = 0; i < 1; i++) {
ResourceBean resourceBean = new ResourceBean("https://google.com", "resouce "+i, "description "+i, null, testUser, dataset.getId(), null);
instance.addResourceToDataset(resourceBean);
}
}
@ -436,7 +458,7 @@ public class TestDataCatalogueLib {
// DataCatalogueImpl instance = factory.getUtilsPerScope(scope);
//
// String username = "francescomangiacrapa";
// List<CkanOrganization> organizations = instance.getOrganizationsByUser(username);
// List<CkanO)rganization> organizations = instance.getOrganizationsByUser(username);
//
// System.out.println("organizations for user " + username + " are: ");
//
@ -576,27 +598,7 @@ public class TestDataCatalogueLib {
//
// }
//
// //@Test
// public void testAddResource() throws Exception{
//
// DataCatalogueImpl instance = factory.getUtilsPerScope(scope);
// String datasetId = "test_publish_folder_15_44";
// //instance.assignDatasetToGroup(groupName, datasetId, instance.getApiKeyFromUsername("costantino_perciante"));
//
// String api = instance.getApiKeyFromUsername("costantino_perciante");
// CheckedCkanClient client = new CheckedCkanClient(instance.getCatalogueUrl(), api);
// List<String> randomName = Arrays.asList("FIRMS", "RAM", "FishSource");
// for (int i = 0; i < 100; i++) {
//
// CkanResource resource = new CkanResource("https://goo.gl/FH5AQ5", datasetId);
// String name = randomName.get((int)Math.round(Math.ceil(Math.random() * 3)));
//
// resource.setName(name);
// client.createResource(resource);
//
// }
// }
//
// //@Test
// public void checkGroupRole() throws Exception{
//