com.rgi.geopackage.metadata.MetadataVerifier Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of swagd Show documentation
Show all versions of swagd Show documentation
SWAGD: Software to Aggregate Geospatial Data
The newest version!
/* The MIT License (MIT)
*
* Copyright (c) 2015 Reinventing Geospatial, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.rgi.geopackage.metadata;
import com.rgi.common.util.jdbc.JdbcUtility;
import com.rgi.common.util.jdbc.ResultSetStream;
import com.rgi.geopackage.core.GeoPackageCore;
import com.rgi.geopackage.utility.DatabaseUtility;
import com.rgi.geopackage.verification.AssertionError;
import com.rgi.geopackage.verification.ColumnDefinition;
import com.rgi.geopackage.verification.ForeignKeyDefinition;
import com.rgi.geopackage.verification.Requirement;
import com.rgi.geopackage.verification.Severity;
import com.rgi.geopackage.verification.VerificationLevel;
import com.rgi.geopackage.verification.Verifier;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.rgi.geopackage.verification.Assert.assertTrue;
/**
* @author Luke Lambert
* @author Jenifer Cochran
*/
public class MetadataVerifier extends Verifier
{
/**
* @param sqliteConnection
* the handle to the database connection
* @param verificationLevel
* Controls the level of verification testing performed
* @throws SQLException
* throws when the method
* {@link DatabaseUtility#tableOrViewExists(Connection, String)}
* or when other SQLExceptions occur
*/
public MetadataVerifier(final Connection sqliteConnection, final VerificationLevel verificationLevel) throws SQLException
{
super(sqliteConnection, verificationLevel);
this.hasMetadataTable = DatabaseUtility.tableOrViewExists(this.getSqliteConnection(), GeoPackageMetadata.MetadataTableName);
this.hasMetadataReferenceTable = DatabaseUtility.tableOrViewExists(this.getSqliteConnection(), GeoPackageMetadata.MetadataReferenceTableName);
this.metadataValues = this.hasMetadataTable ? JdbcUtility.select(this.getSqliteConnection(),
String.format("SELECT md_scope, id FROM %s;", GeoPackageMetadata.MetadataTableName),
null,
resultSet -> new MetadataVerifier.MetadataEntry(resultSet.getInt("id"),
resultSet.getString("md_scope")))
: Collections.emptyList();
final String metadataReferencesQuery = String.format("SELECT reference_scope, table_name, column_name, row_id_value, timestamp, md_file_id, md_parent_id FROM %s;", GeoPackageMetadata.MetadataReferenceTableName);
this.metadataReferenceValues = this.hasMetadataReferenceTable ? JdbcUtility.select(this.getSqliteConnection(),
metadataReferencesQuery,
null,
resultSet -> new MetadataVerifier.MetadataReference(resultSet.getString("reference_scope"),
resultSet.getString("table_name"),
resultSet.getString("column_name"),
resultSet.getString("timestamp"),
resultSet.getInt ("md_file_id"), // Cannot be null
nullSafeGet(resultSet, "row_id_value"), // getInt() returns 0 if the value in the database was null
nullSafeGet(resultSet, "md_parent_id")))
: Collections.emptyList();
}
/**
* Requirement 93
*
*
* A GeoPackage MAY contain a table named gpkg_metadata. If present it
* SHALL be defined per clause 2.4.2.1.1 Table
* Definition, Metadata Table
* Definition and gpkg_metadata Table
* Definition SQL.
*
*
* @throws SQLException
* if the method verifyTable throws
* @throws AssertionError
* when the GeoPackage fails to meet this requirement
*/
@Requirement(reference = "Requirement 93",
text = "A GeoPackage MAY contain a table named gpkg_metadata. If present it SHALL be defined per clause 2.4.2.1.1 Table Definition, Metadata Table Definition and gpkg_metadata Table Definition SQL.")
public void Requirement93() throws AssertionError, SQLException
{
if(this.hasMetadataTable)
{
final Map metadataTableColumns = new HashMap<>();
metadataTableColumns.put("id", new ColumnDefinition("INTEGER", true, true, false, null));
metadataTableColumns.put("md_scope", new ColumnDefinition("TEXT", true, false, false, "'dataset'"));
metadataTableColumns.put("md_standard_uri", new ColumnDefinition("TEXT", true, false, false, null));
metadataTableColumns.put("mime_type", new ColumnDefinition("TEXT", true, false, false, "'text/xml'"));
metadataTableColumns.put("metadata", new ColumnDefinition("TEXT", true, false, false, "''"));
this.verifyTable(GeoPackageMetadata.MetadataTableName,
metadataTableColumns,
Collections.emptySet(),
Collections.emptyList());
}
}
/**
* Requirement 94
*
*
* Each {@code md_scope} column value in a {@code gpkg_metadata} table or
* updateable view SHALL be one of the name column values from Metadata Scopes.
*
*
* @throws AssertionError throws when the GeoPackage fails to meet this requirement
*/
@Requirement(reference = "Requirement 94",
text = "Each md_scope column value in a gpkg_metadata table or updateable view SHALL be one of the name column values from Metadata Scopes.")
public void Requirement94() throws AssertionError
{
if(this.hasMetadataTable)
{
final List invalidScopeValues = this.metadataValues.stream()
.filter(metadata -> !MetadataVerifier.isValidMdScope(metadata.mdScope))
.map(metadata -> metadata.mdScope)
.collect(Collectors.toList());
assertTrue(String.format("The following md_scope(s) are invalid values in the %s table: %s",
GeoPackageMetadata.MetadataTableName,
String.join(", ", invalidScopeValues)),
invalidScopeValues.isEmpty(),
Severity.Warning);
}
}
/**
* Requirement 95
*
*
* A GeoPackage that contains a {@code gpkg_metadata} table SHALL contain a
* {@code gpkg_metadata_reference} table per clause 2.4.3.1.1 Table Definition, Metadata
* Reference Table Definition (Table Name: gpkg_metadata_reference) and
*
* gpkg_metadata_reference Table Definition SQL.
*
*
* @throws SQLException
* if there is a database error
* @throws AssertionError
* when the GeoPackage fails to meet this requirement
*/
@Requirement(reference = "Requirement 95",
text = "A GeoPackage that contains a gpkg_metadata table SHALL contain a gpkg_metadata_reference table per clause 2.4.3.1.1 Table Definition, Metadata Reference Table Definition (Table Name: gpkg_metadata_reference) and gpkg_metadata_reference Table Definition SQL.")
public void Requirement95() throws SQLException, AssertionError
{
if(this.hasMetadataTable)
{
assertTrue(String.format("This contains a %1$s table but not a %2$s table. Either drop the %1$s table or add a %2$s table",
GeoPackageMetadata.MetadataTableName,
GeoPackageMetadata.MetadataReferenceTableName),
this.hasMetadataReferenceTable,
Severity.Error);
final Map metadataReferenceTableColumns = new HashMap<>();
metadataReferenceTableColumns.put("reference_scope", new ColumnDefinition("TEXT", true, false, false, null));
metadataReferenceTableColumns.put("table_name", new ColumnDefinition("TEXT", false, false, false, null));
metadataReferenceTableColumns.put("column_name", new ColumnDefinition("TEXT", false, false, false, null));
metadataReferenceTableColumns.put("row_id_value", new ColumnDefinition("INTEGER", false, false, false, null));
metadataReferenceTableColumns.put("timestamp", new ColumnDefinition("DATETIME", true, false, false, "strftime('%Y-%m-%dT%H:%M:%fZ', 'now')"));
metadataReferenceTableColumns.put("md_file_id", new ColumnDefinition("INTEGER", true, false, false, null));
metadataReferenceTableColumns.put("md_parent_id", new ColumnDefinition("INTEGER", false, false, false, null));
this.verifyTable(GeoPackageMetadata.MetadataReferenceTableName,
metadataReferenceTableColumns,
new HashSet<>(Arrays.asList(new ForeignKeyDefinition(GeoPackageMetadata.MetadataTableName, "md_parent_id", "id"),
new ForeignKeyDefinition(GeoPackageMetadata.MetadataTableName, "md_file_id", "id"))),
Collections.emptyList());
}
}
/**
* Requirement 96
*
*
* Every {@code gpkg_metadata_reference} table reference scope column value
* SHALL be one of 'geopackage', 'table', 'column', 'row', 'row/col' in
* lowercase.
*
*
* @throws AssertionError
* when the GeoPackage fails to meet this requirement
*/
@Requirement(reference = "Requirement 96",
text = "Every gpkg_metadata_reference table reference scope column value SHALL be one of 'geopackage', 'table', 'column', 'row', 'row/col' in lowercase.")
public void Requirement96() throws AssertionError
{
if(this.hasMetadataReferenceTable)
{
final Collection invalidScopeValues = this.metadataReferenceValues
.stream()
.filter(value -> !MetadataVerifier.isValidReferenceScope(value.referenceScope))
.map(value -> value.referenceScope)
.collect(Collectors.toList());
assertTrue(String.format("The following reference_scope value(s) are invalid from the %s table: %s",
GeoPackageMetadata.MetadataReferenceTableName,
String.join(", ", invalidScopeValues)),
invalidScopeValues.isEmpty(),
Severity.Warning);
}
}
/**
* Requirement 97
*
*
* Every {@code gpkg_metadata_reference} table row with a {@code
* reference_scope} column value of 'geopackage' SHALL have a {@code
* table_name} column value that is NULL. Every other {@code
* gpkg_metadata_reference} table row SHALL have a {@code table_name}
* column value that references a value in the {@code gpkg_contents}
* {@code table_name} column.
*
*
* @throws SQLException
* if there is a database error
* @throws AssertionError
* when the GeoPackage fails to meet this requirement
*/
@Requirement(reference = "Requirement 97",
text = "Every gpkg_metadata_reference table row with a reference_scope column value of 'geopackage' SHALL have a table_name column value that is NULL. Every other gpkg_metadata_reference table row SHALL have a table_name column value that references a value in the gpkg_contents table_name column.")
public void Requirement97() throws SQLException, AssertionError
{
if(this.hasMetadataReferenceTable)
{
// Check reference_scope column that has 'geopackage'
final List invalidGeoPackageValue = this.metadataReferenceValues.stream()
.filter(columnValue -> columnValue.referenceScope.equalsIgnoreCase(ReferenceScope.GeoPackage.toString()))
.filter(columnValue -> columnValue.columnName != null)
.collect(Collectors.toList());
assertTrue(String.format("The following column_name value(s) from %s table are invalid. They have a reference_scope = 'geopackage' and a non-null value in column_name: %s.",
GeoPackageMetadata.MetadataReferenceTableName,
invalidGeoPackageValue.stream()
.map(columnValue -> columnValue.columnName)
.collect(Collectors.joining(", "))),
invalidGeoPackageValue.isEmpty(),
Severity.Warning);
// Get table_name values from the gpkg_contents table
final String query = String.format("SELECT table_name FROM %s;", GeoPackageCore.ContentsTableName);
try(PreparedStatement stmt = this.getSqliteConnection().prepareStatement(query);
ResultSet contentsTableNamesRS = stmt.executeQuery())
{
final List contentsTableNames = ResultSetStream.getStream(contentsTableNamesRS)
.map(resultSet -> { try
{
return resultSet.getString("table_name");
}
catch(final SQLException ignored)
{
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
//check other records that does not have 'geopackage' as a value
final List invalidTableNameValues = this.metadataReferenceValues.stream()
.filter(columnValue -> !columnValue.referenceScope.equalsIgnoreCase(ReferenceScope.GeoPackage.toString()))
.filter(columnValue -> contentsTableNames.stream().anyMatch(contentsTableName -> !columnValue.tableName.equals(contentsTableName)))
.collect(Collectors.toList());
assertTrue(String.format("The following table_name value(s) in %s table are invalid. The table_name value(s) must reference the table_name(s) in %s table.\n%s",
GeoPackageMetadata.MetadataReferenceTableName,
GeoPackageCore.ContentsTableName,
invalidTableNameValues.stream()
.map(tableName -> String.format("reference_scope: %s, invalid table_name: %s.",
tableName.referenceScope,
tableName.tableName))
.collect(Collectors.joining("\n"))),
invalidTableNameValues.isEmpty(),
Severity.Warning);
}
}
}
/**
* Requirement 98
*
*
* Every {@code gpkg_metadata_reference} table row with a {@code
* reference_scope} column value of 'geopackage','table' or 'row'
* SHALL have a {@code column_name} column value that is NULL. Every
* other {@code gpkg_metadata_reference} table row SHALL have a {@code
* column_name} column value that contains the name of a column in
* the SQLite table or view identified by the {@code table_name}
* column value.
*
*
* @throws AssertionError throws when the GeoPackage fails to meet this requirement
* @throws SQLException throws if various SQLExceptions occur
*/
@Requirement(reference = "Requirement 98",
text = "Every gpkg_metadata_reference table row with a reference_scope column "
+ "value of 'geopackage','table' or 'row' SHALL have a column_name column"
+ " value that is NULL. Every other gpkg_metadata_reference table row SHALL"
+ " have a column_name column value that contains the name of a column in the "
+ "SQLite table or view identified by the table_name column value. ")
public void Requirement98() throws AssertionError, SQLException
{
if(this.hasMetadataReferenceTable)
{
final List invalidColumnNameValues = this.metadataReferenceValues.stream()
.filter(columnValue -> columnValue.referenceScope.equalsIgnoreCase(ReferenceScope.GeoPackage.toString()) ||
columnValue.referenceScope.equalsIgnoreCase(ReferenceScope.Table.toString()) ||
columnValue.referenceScope.equalsIgnoreCase(ReferenceScope.Row.toString()))
.filter(columnValue -> columnValue.columnName != null)
.collect(Collectors.toList());
assertTrue(String.format("The following column_name values from %s table are invalid. They contain a reference_scope of either 'geopackage', 'table' or 'row' and need to have a column_value of NULL.\n%s",
GeoPackageMetadata.MetadataReferenceTableName,
invalidColumnNameValues.stream()
.map(value -> String.format("reference_scope: %s, invalid column_name: %s.", value.referenceScope, value.columnName))
.collect(Collectors.joining("\n"))),
invalidColumnNameValues.isEmpty(),
Severity.Warning);
final List otherReferenceScopeValues = this.metadataReferenceValues.stream()
.filter(columnValue -> !columnValue.referenceScope.equalsIgnoreCase(ReferenceScope.GeoPackage.toString()) &&
!columnValue.referenceScope.equalsIgnoreCase(ReferenceScope.Table.toString()) &&
!columnValue.referenceScope.equalsIgnoreCase(ReferenceScope.Row.toString()))
.collect(Collectors.toList());
for(final MetadataVerifier.MetadataReference value : otherReferenceScopeValues)
{
if(DatabaseUtility.tableOrViewExists(this.getSqliteConnection(), value.tableName))
{
final String query = "PRAGMA table_info('?');";
try(PreparedStatement statement = this.getSqliteConnection().prepareStatement(query))
{
statement.setString(1, value.tableName);
try( ResultSet tableInfo = statement.executeQuery(query))
{
final boolean columnExists = ResultSetStream.getStream(tableInfo)
.anyMatch(resultSet -> { try
{
return resultSet.getString("name").equals(value.columnName);
}
catch(final SQLException ignored)
{
return false;
}
});
assertTrue(String.format("The column_name %s referenced in the %s table doesn't exist in the table %s.",
value.columnName,
GeoPackageMetadata.MetadataReferenceTableName,
value.tableName),
columnExists,
Severity.Warning);
}
}
}
}
}
}
/**
* Requirement 75
*
*
* Every {@code gpkg_metadata_reference} table row with a {@code
* reference_scope} column value of 'geopackage', 'table' or 'column'
* SHALL have a {@code row_id_value} column value that is NULL. Every
* other {@code gpkg_metadata_reference} table row SHALL have a {@code
* row_id_value} column value that contains the ROWID of a row in the
* SQLite table or view identified by the {@code table_name} column
* value.
*
*
* @throws AssertionError throws when the GeoPackage fails to meet this requirement
* @throws SQLException throws if various SQLExceptions occur
*/
@Requirement(reference = "Requirement 75",
text = "Every gpkg_metadata_reference table row with a reference_scope column value "
+ "of 'geopackage', 'table' or 'column' SHALL have a row_id_value column value "
+ "that is NULL. Every other gpkg_metadata_reference table row SHALL have a row_id_value"
+ " column value that contains the ROWID of a row in the SQLite table or view identified "
+ "by the table_name column value.")
public void Requirement75() throws AssertionError, SQLException
{
if(this.hasMetadataReferenceTable)
{
final List invalidColumnValues = this.metadataReferenceValues.stream()
.filter(columnValue -> columnValue.referenceScope.equalsIgnoreCase(ReferenceScope.GeoPackage.toString()) ||
columnValue.referenceScope.equalsIgnoreCase(ReferenceScope.Table.toString()) ||
columnValue.referenceScope.equalsIgnoreCase(ReferenceScope.Column.toString()))
.filter(columnValue -> columnValue.rowIdValue != null)
.collect(Collectors.toList());
assertTrue(String.format("The following row_id_value(s) has(have) a reference_scope value of 'geopackage', "
+ "'table' or 'column and do not have a value of NULL in row_id_value.\n %s",
invalidColumnValues.stream()
.map(columnValue -> String.format("reference_scope: %s, invalid row_id_value: %d.", columnValue.referenceScope, columnValue.rowIdValue))
.collect(Collectors.joining("\n"))),
invalidColumnValues.isEmpty(),
Severity.Warning);
final List invalidColumnNameValues = this.metadataReferenceValues.stream()
.filter(columnValue -> !columnValue.referenceScope.equalsIgnoreCase(ReferenceScope.GeoPackage.toString()) &&
!columnValue.referenceScope.equalsIgnoreCase(ReferenceScope.Table.toString()) &&
!columnValue.referenceScope.equalsIgnoreCase(ReferenceScope.Column.toString()))
.collect(Collectors.toList());
for(final MetadataVerifier.MetadataReference value: invalidColumnNameValues)
{
final String query = String.format("SELECT COUNT(1) FROM %s WHERE ROWID = ?;", // TODO make sure COUNT(1) works the way I think it does...
value.tableName);
try(PreparedStatement statement = this.getSqliteConnection().prepareStatement(query))
{
statement.setString(1, value.tableName);
statement.setInt (2, value.rowIdValue);
try(ResultSet matchingRowIdRS = statement.executeQuery())
{
assertTrue(String.format("The row_id_value %d in the %s table does not reference a row id in the table %s.",
value.rowIdValue,
GeoPackageMetadata.MetadataReferenceTableName,
value.tableName),
matchingRowIdRS.next(),
Severity.Warning);
}
}
}
}
}
/**
* Requirement 76
*
*
* Every {@code gpkg_metadata_reference} table row timestamp column
* value SHALL be in ISO 8601 format containing a complete date plus UTC
* hours, minutes, seconds and a decimal fraction of a second, with a 'Z'
* ('zulu') suffix indicating UTC.
*
*
* @throws AssertionError throws when the GeoPackage fails to meet this requirement
*/
@Requirement(reference = "Requirement 76",
text = "Every gpkg_metadata_reference table row timestamp column value "
+ "SHALL be in ISO 8601 format containing a complete date plus "
+ "UTC hours, minutes, seconds and a decimal fraction of a second, with "
+ "a 'Z' ('zulu') suffix indicating UTC.")
public void Requirement76() throws AssertionError
{
if(this.hasMetadataReferenceTable)
{
for(final MetadataVerifier.MetadataReference value : this.metadataReferenceValues)
{
assertTrue(String.format("The timestamp %s in the %s table is not in the correct format.",
value.timestamp,
GeoPackageMetadata.MetadataReferenceTableName),
isValidDate(value.timestamp),
Severity.Warning);
}
}
}
/**
* Requirement 77
*
*
* Every {@code gpkg_metadata_reference} table row {@code md_file_id
* } column value SHALL be an id column value from the {@code
* gpkg_metadata} table.
*
*
* @throws AssertionError throws when the GeoPackage fails to meet this requirement
*/
@Requirement(reference = "Requirement 77",
text = "Every gpkg_metadata_reference table row md_file_id column "
+ "value SHALL be an id column value from the gpkg_metadata table. ")
public void Requirement77() throws AssertionError
{
if(this.hasMetadataReferenceTable)
{
final List invalidIds = this.metadataReferenceValues.stream()
.filter(metadataReferenceValue -> !(this.metadataValues.stream()
.anyMatch(metadataValue -> metadataReferenceValue.mdFileId == metadataValue.id)))
.collect(Collectors.toList());
assertTrue(String.format("The following md_file_id(s) from %s table do not reference an id column value from the %s table.\n%s",
GeoPackageMetadata.MetadataReferenceTableName,
GeoPackageMetadata.MetadataTableName,
invalidIds.stream()
.map(invalidId -> String.format("invalid md_file_id: %s, md_parent_id: %d, reference_scope: %s.",
invalidId.mdFileId,
invalidId.mdParentId,
invalidId.referenceScope))
.collect(Collectors.joining("\n"))),
invalidIds.isEmpty(),
Severity.Warning);
}
}
/**
* Requirement 78
*
*
* Every {@code gpkg_metadata_reference} table row {@code md_parent_id
* } column value that is NOT NULL SHALL be an id column value from
* the {@code gpkg_metadata} table that is not equal to the {@code
* md_file_id} column value for that row.
*
*
* @throws AssertionError throws when the GeoPackage fails to meet this requirement
*/
@Requirement(reference = "Requirement 78",
text = "Every gpkg_metadata_reference table row md_parent_id column value "
+ "that is NOT NULL SHALL be an id column value from the gpkg_metadata "
+ "table that is not equal to the md_file_id column value for that row. ")
public void Requirement78() throws AssertionError
{
if(this.hasMetadataReferenceTable)
{
final List invalidParentIdsBcFileIds = this.metadataReferenceValues.stream()
.filter(metadataReferenceValue -> metadataReferenceValue.mdFileId == metadataReferenceValue.mdParentId)
.collect(Collectors.toList());
assertTrue(String.format("The following md_parent_id(s) are invalid because they cannot be equivalent to their correspoding md_file_id.\n%s",
invalidParentIdsBcFileIds.stream()
.map(value -> String.format("Invalid md_parent_id: %d, md_file_id: %d.",
value.mdParentId,
value.mdFileId))
.collect(Collectors.joining("\n"))),
invalidParentIdsBcFileIds.isEmpty(),
Severity.Warning);
final List invalidParentIds = this.metadataReferenceValues.stream()
.filter(metadataReferenceValue -> metadataReferenceValue.mdParentId != null)
.filter(metadataReferenceValue -> !(this.metadataValues.stream()
.anyMatch(metadataValue -> metadataReferenceValue.mdParentId.equals(metadataValue.id))))
.collect(Collectors.toList());
assertTrue(String.format("The following md_parent_id value(s) are invalid because they do not equal id column value from the %s table. \n%s",
GeoPackageMetadata.MetadataTableName,
invalidParentIds.stream()
.map(value -> String.format("Invalid md_parent_id: %d, md_file_id: %d.",
value.mdParentId,
value.mdFileId))
.collect(Collectors.joining("\n"))),
invalidParentIds.isEmpty(),
Severity.Warning);
}
}
private static Integer nullSafeGet(final ResultSet resultSet, final String columnLabel) throws SQLException
{
final Integer value = resultSet.getInt(columnLabel);
return resultSet.wasNull() ? null
: value;
}
private static boolean isValidReferenceScope(final String referenceScope)
{
return Stream.of(ReferenceScope.values()).anyMatch(scope -> scope.toString().equalsIgnoreCase(referenceScope));
}
private static boolean isValidMdScope(final String mdScope)
{
return Stream.of(Scope.values()).anyMatch(scope -> scope.toString().equalsIgnoreCase(mdScope));
}
private static boolean isValidDate(final String date)
{
final SimpleDateFormat dateFormatWithFractionalSeconds = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.'SS'Z'");
final SimpleDateFormat dateFormatWithoutFractionalSeconds = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
return isValidDate(dateFormatWithFractionalSeconds, date) ||
isValidDate(dateFormatWithoutFractionalSeconds, date);
}
private static boolean isValidDate(final SimpleDateFormat dateFormat, final String date)
{
try
{
dateFormat.parse(date);
return true;
}
catch(final ParseException ignored)
{
return false;
}
}
private final boolean hasMetadataTable;
private final boolean hasMetadataReferenceTable;
private final List metadataValues;
private final List metadataReferenceValues;
// TODO don't use these inner classes
private static final class MetadataEntry
{
private MetadataEntry(final int id,
final String mdScope)
{
this.id = id;
this.mdScope = mdScope;
}
private final int id;
private final String mdScope;
}
// TODO don't use these inner classes
private static final class MetadataReference
{
private final String referenceScope;
private final String tableName;
private final String columnName;
private final Integer rowIdValue;
private final String timestamp;
private final int mdFileId;
private final Integer mdParentId;
private MetadataReference(final String referenceScope,
final String tableName,
final String columnName,
final String timestamp,
final int mdFileId,
final Integer rowIdValue,
final Integer mdParentId)
{
this.referenceScope = referenceScope;
this.tableName = tableName;
this.columnName = columnName;
this.rowIdValue = rowIdValue;
this.timestamp = timestamp;
this.mdFileId = mdFileId;
this.mdParentId = mdParentId;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy