diff --git a/.gitignore b/.gitignore
index 84adb3f..dfd6afc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,8 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
+/target/
+/.project
+/.settings
+
+/.classpath
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..86e3d3a
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,8 @@
+This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+# Changelog for Accounting Postgresql Utilities
+
+
+## [v1.0.0-SNAPSHOT]
+
+- First Release
diff --git a/README.md b/README.md
index 9ac4295..e6bc911 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,71 @@
-# accounting-postgresql-utilities
+# Accounting Postgresql Utilities
+
+Accounting Postgresql Utilities
+
+## Built With
+
+* [OpenJDK](https://openjdk.java.net/) - The JDK used
+* [Maven](https://maven.apache.org/) - Dependency Management
+
+## Documentation
+
+[Accounting](https://wiki.gcube-system.org/gcube/Accounting)
+
+## Change log
+
+See [Releases](https://code-repo.d4science.org/gCubeSystem/accounting-postgresql-utilities/releases).
+
+## Authors
+
+* **Luca Frosini** ([ORCID](https://orcid.org/0000-0003-3183-2291)) - [ISTI-CNR Infrascience Group](http://nemis.isti.cnr.it/groups/infrascience)
+
+## How to Cite this Software
+
+Tell people how to cite this software.
+* Cite an associated paper?
+* Use a specific BibTeX entry for the software?
+
+
+ @Manual{,
+ title = {Accounting Postgresql Utilities},
+ author = {{Frosini, Luca}},
+ organization = {ISTI - CNR},
+ address = {Pisa, Italy},
+ year = 2021,
+ url = {http://www.gcube-system.org/}
+ }
+
+## License
+
+This project is licensed under the EUPL V.1.2 License - see the [LICENSE.md](LICENSE.md) file for details.
+
+
+## About the gCube Framework
+This software is part of the [gCubeFramework](https://www.gcube-system.org/ "gCubeFramework"): an
+open-source software toolkit used for building and operating Hybrid Data
+Infrastructures enabling the dynamic deployment of Virtual Research Environments
+by favouring the realisation of reuse oriented policies.
+
+The projects leading to this software have received funding from a series of European Union programmes including:
+
+- the Sixth Framework Programme for Research and Technological Development
+ - DILIGENT (grant no. 004260).
+- the Seventh Framework Programme for research, technological development and demonstration
+ - D4Science (grant no. 212488);
+ - D4Science-II (grant no.239019);
+ - ENVRI (grant no. 283465);
+ - iMarine(grant no. 283644);
+ - EUBrazilOpenBio (grant no. 288754).
+- the H2020 research and innovation programme
+ - SoBigData (grant no. 654024);
+ - PARTHENOS (grant no. 654119);
+ - EGIEngage (grant no. 654142);
+ - ENVRIplus (grant no. 654182);
+ - BlueBRIDGE (grant no. 675680);
+ - PerformFish (grant no. 727610);
+ - AGINFRAplus (grant no. 731001);
+ - DESIRA (grant no. 818194);
+ - ARIADNEplus (grant no. 823914);
+ - RISIS2 (grant no. 824091);
+
-This repository contains common utility classes used by accounting PostgreSQL persistences
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..bb5aaa2
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,61 @@
+
+ 4.0.0
+
+ org.gcube.tools
+ maven-parent
+ 1.1.0
+
+ org.gcube.accounting
+ accounting-postgresql-utilities
+ 1.0.0-SNAPSHOT
+ Accounting Postgresql Utilities
+ Utility classes to persist/query Record in PostgreSQL database
+
+
+ scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git
+ scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git
+ https://code-repo.d4science.org/gCubeSystem/${project.artifactId}
+
+
+
+
+
+ org.gcube.distribution
+ gcube-bom
+ 2.0.1
+ pom
+ import
+
+
+
+
+
+
+ org.gcube.data.publishing
+ document-store-lib
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+ org.postgresql
+ postgresql
+ 42.2.19
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+ ch.qos.logback
+ logback-classic
+ test
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/gcube/accounting/utility/postgresql/RecordToDBConnection.java b/src/main/java/org/gcube/accounting/utility/postgresql/RecordToDBConnection.java
new file mode 100644
index 0000000..1cb8d51
--- /dev/null
+++ b/src/main/java/org/gcube/accounting/utility/postgresql/RecordToDBConnection.java
@@ -0,0 +1,50 @@
+package org.gcube.accounting.utility.postgresql;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+
+import org.gcube.documentstore.persistence.PersistenceBackendConfiguration;
+import org.gcube.documentstore.records.Record;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RecordToDBConnection {
+
+ private static final Logger logger = LoggerFactory.getLogger(RecordToDBConnection.class);
+
+ public static final String URL_PROPERTY_KEY = "url";
+ public static final String DB_SUFFIX = "-db";
+ public static final String USERNAME_SUFFIX = "-username";
+ public static final String PASSWORD_SUFFIX = "-password";
+
+ private final String baseURL;
+ private final String dbName;
+ private final String url;
+ private final String username;
+ private final String password;
+
+ protected final Class extends Record> clz;
+ protected final String typeName;
+
+ protected RecordToDBConnection(String type, Class extends Record> clz, PersistenceBackendConfiguration configuration) throws Exception {
+ this.clz = clz;
+ this.typeName = type;
+
+ this.baseURL = configuration.getProperty(URL_PROPERTY_KEY);
+ this.dbName = configuration.getProperty(typeName+DB_SUFFIX);
+ this.url = baseURL + "/" + dbName;
+
+ this.username = configuration.getProperty(typeName+USERNAME_SUFFIX);
+ this.password = configuration.getProperty(typeName+PASSWORD_SUFFIX);
+
+ }
+
+ public Connection getConnection() throws Exception {
+ Class.forName("org.postgresql.Driver");
+ Connection connection = DriverManager.getConnection(url, username, password);
+ logger.trace("Database {} opened successfully", url);
+ connection.setAutoCommit(false);
+ return connection;
+ }
+
+}
diff --git a/src/main/java/org/gcube/accounting/utility/postgresql/RecordToDBFields.java b/src/main/java/org/gcube/accounting/utility/postgresql/RecordToDBFields.java
new file mode 100644
index 0000000..58a17c5
--- /dev/null
+++ b/src/main/java/org/gcube/accounting/utility/postgresql/RecordToDBFields.java
@@ -0,0 +1,76 @@
+package org.gcube.accounting.utility.postgresql;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.gcube.documentstore.records.Record;
+
+public class RecordToDBFields {
+
+ protected static String getKey(String fieldName) {
+ StringBuffer stringBuffer = new StringBuffer();
+ int lenght = fieldName.length();
+ boolean lastLowerCase = true;
+ for (int i=0; i clz;
+
+ protected final String typeName;
+ protected final String tableName;
+
+ protected final Map tableFieldToRecordField;
+ protected final Map recordFieldToTableField;
+
+ public RecordToDBFields(String typeName, Class extends Record> clz) throws Exception {
+ this.clz = clz;
+ this.typeName = typeName;
+ this.tableName = typeName.toLowerCase();
+ this.tableFieldToRecordField = new HashMap<>();
+ this.recordFieldToTableField = new HashMap<>();
+ mapFields();
+ }
+
+ protected void mapFields() throws Exception {
+ Set requiredFields = clz.newInstance().getRequiredFields();
+ for(String usageRecordField : requiredFields) {
+ String dbField = getKey(usageRecordField);
+ tableFieldToRecordField.put(dbField, usageRecordField);
+ recordFieldToTableField.put(usageRecordField, dbField);
+ }
+ }
+
+ public String getTableField(String recordField) {
+ return recordFieldToTableField.get(recordField);
+ }
+
+ public String getRecordField(String tableField) {
+ String ret = tableFieldToRecordField.get(tableField);
+ if(ret==null && recordFieldToTableField.keySet().contains(tableField)) {
+ ret = tableField;
+ }
+ return ret;
+ }
+
+ public String getTypeName() {
+ return typeName;
+ }
+
+ public String getTableName() {
+ return tableName;
+ }
+
+}
diff --git a/src/main/java/org/gcube/accounting/utility/postgresql/RecordToDBMapping.java b/src/main/java/org/gcube/accounting/utility/postgresql/RecordToDBMapping.java
new file mode 100644
index 0000000..b2b07a2
--- /dev/null
+++ b/src/main/java/org/gcube/accounting/utility/postgresql/RecordToDBMapping.java
@@ -0,0 +1,49 @@
+package org.gcube.accounting.utility.postgresql;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.gcube.documentstore.persistence.PersistenceBackendConfiguration;
+import org.gcube.documentstore.records.AggregatedRecord;
+import org.gcube.documentstore.records.Record;
+
+public class RecordToDBMapping {
+
+ public static String getRecordTypeByClass(Class extends Record> clz) {
+ try {
+ Record r = clz.newInstance();
+ return r.getRecordType();
+ }catch (Exception e) {
+ String type = clz.getSimpleName();
+ type = type.replace("Abstract", "");
+ type = type.replace("Aggregated", "");
+ return type;
+ }
+ }
+
+ protected final static Map classToRecordToDBMapper;
+ protected final static Map recordToDBInfo;
+
+ static {
+ classToRecordToDBMapper = new HashMap<>();
+ recordToDBInfo= new HashMap<>();
+ }
+
+ public static synchronized void addRecordToDB(Class extends AggregatedRecord, ?>> clz, PersistenceBackendConfiguration configuration) throws Exception {
+ String type = getRecordTypeByClass(clz);
+ RecordToDBFields recordToDBMapper = new RecordToDBFields(type, clz);
+ classToRecordToDBMapper.put(type, recordToDBMapper);
+ RecordToDBConnection recordDBInfo = new RecordToDBConnection(type, clz, configuration);
+ recordToDBInfo.put(type, recordDBInfo);
+ }
+
+ public static synchronized RecordToDBFields getRecordToDB(Class extends Record> clz) throws Exception {
+ String type = getRecordTypeByClass(clz);
+ return classToRecordToDBMapper.get(type);
+ }
+
+ public static synchronized RecordToDBConnection getRecordDBInfo(Class extends Record> clz) throws Exception {
+ String type = getRecordTypeByClass(clz);
+ return recordToDBInfo.get(type);
+ }
+}