/* 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;
import com.rgi.geopackage.GeoPackage.OpenMode;
import com.rgi.geopackage.extensions.Extension;
import com.rgi.geopackage.extensions.GeoPackageExtensions;
import com.rgi.geopackage.extensions.Scope;
import com.rgi.geopackage.verification.ConformanceException;
import com.rgi.geopackage.verification.VerificationLevel;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@SuppressWarnings("javadoc")
public class GeoPackageExtensionsAPITest
{
@BeforeClass
public static void setUp() throws ClassNotFoundException
{
Class.forName("org.sqlite.JDBC"); // Register the driver
}
/**
* Tests if GeoPackage Extensions can
* retrieve an extension that has a null value
* for table name and column name
*/
@Test
public void getExtensionWithNullParameters() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
final String extensionName = "something_extension";
final Extension expectedExtension = gpkg.extensions().addExtension(null, null, extensionName, "definition", Scope.ReadWrite); // This works fine
final Extension returnedExtension = gpkg.extensions().getExtension(null, null, extensionName);
assertNotNull("The GeoPackageExtensions did not return the extension expected", returnedExtension);
assertTrue(String.format("The GeoPackageExtensions did not return the extension expected. Expected: %s.\nActual: %s.",
String.format("TableName: %s, Column Name: %s, extension name: %s definition: %s, scope: %s",
expectedExtension.getTableName(),
expectedExtension.getColumnName(),
expectedExtension.getExtensionName(),
expectedExtension.getDefinition(),
expectedExtension.getScope()),
String.format("TableName: %s, Column Name: %s, extension name: %s definition: %s, scope: %s",
returnedExtension.getTableName(),
returnedExtension.getColumnName(),
returnedExtension.getExtensionName(),
returnedExtension.getDefinition(),
expectedExtension.getScope())),
returnedExtension.equals(expectedExtension.getTableName(),
expectedExtension.getTableName(),
expectedExtension.getExtensionName(),
expectedExtension.getDefinition(),
Scope.ReadWrite));
}
}
/**
* Tests if gpkgExtensions returns the values expected
*/
@Test
public void getExtension2() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
final String tableName = "TableName";
final String columnName = "columnName";
final String extensionName = "extension_Name";
final Extension expectedExtension = gpkg.extensions().addExtension(tableName, columnName, extensionName, "definition", Scope.ReadWrite);
final Extension returnedExtension = gpkg.extensions().getExtension(tableName, columnName, extensionName);
assertNotNull("The GeoPackageExtensions did not return the extension expected", returnedExtension);
assertTrue(String.format("Did not return the expected Extension.\nExpected: table_name: %s, column_name: %s, extension_name: %s, definition: %s, Scope: %s."
+ " \nActual: table_name: %s, column_name: %s, extension_name: %s, definition: %s, Scope: %s. ",
tableName,
columnName,
extensionName,
expectedExtension.getDefinition(),
expectedExtension.getScope(),
returnedExtension.getTableName(),
returnedExtension.getColumnName(),
returnedExtension.getExtensionName(),
returnedExtension.getDefinition(),
returnedExtension.getScope()),
returnedExtension.equals(tableName,
columnName,
extensionName,
expectedExtension.getDefinition(),
Scope.ReadWrite));
}
}
/**
* Tests if GeoPackage Extensions returned
* the expected extension and uses the getters
* from Extensions class to verify the values
* were inputted into the class correctly
*/
@Test
public void getExtensionUsingExtensionGetters() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
final String extensionName = "something_extension";
final Extension expectedExtension = gpkg.extensions().addExtension(null, null, extensionName, "definition", Scope.ReadWrite); //this works fine
final Extension returnedExtension = gpkg.extensions().getExtension(null, null, extensionName); //this does not
assertTrue(String.format("The GeoPackageExtensions did not return the extension expected. Expected: %s.\nActual: %s.",
String.format("TableName: %s, Column Name: %s, extension name: %s definition: %s, scope: %s",
expectedExtension.getTableName(),
expectedExtension.getColumnName(),
expectedExtension.getExtensionName(),
expectedExtension.getDefinition(),
expectedExtension.getScope()),
String.format("TableName: %s, Column Name: %s, extension name: %s definition: %s, scope: %s",
returnedExtension.getTableName(),
returnedExtension.getColumnName(),
returnedExtension.getExtensionName(),
returnedExtension.getDefinition(),
expectedExtension.getScope())),
returnedExtension.equals(expectedExtension.getTableName(),
expectedExtension.getTableName(),
expectedExtension.getExtensionName(),
expectedExtension.getDefinition(),
Scope.ReadWrite));
}
}
/**
* Tests if gpkgExtensions returns the values expected
*/
@Test
public void getExtension() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
final String tableName = "TableName";
final String columnName = "columnName";
final String extensionName = "extension_Name";
final Extension expectedExtension = gpkg.extensions().addExtension(tableName, columnName, extensionName, "definition", Scope.ReadWrite);
final Extension returnedExtension = gpkg.extensions().getExtension(tableName, columnName, extensionName);
assertTrue(String.format("Did not return the expected Extension.\nExpected: table_name: %s, column_name: %s, extension_name: %s, definition: %s, Scope: %s."
+ " \nActual: table_name: %s, column_name: %s, extension_name: %s, definition: %s, Scope: %s. ",
tableName,
columnName,
extensionName,
expectedExtension.getDefinition(),
expectedExtension.getScope(),
returnedExtension.getTableName(),
returnedExtension.getColumnName(),
returnedExtension.getExtensionName(),
returnedExtension.getDefinition(),
returnedExtension.getScope()),
returnedExtension.equals(tableName,
columnName,
extensionName,
expectedExtension.getDefinition(),
Scope.ReadWrite));
}
}
/**
* Tests if the GeoPackage Extensions will throw
* and IllegalArgumentException when giving a null
* value for tableName and not to ColumnName (if table
* name is null, then so must columnName)
*/
@Test(expected = IllegalArgumentException.class)
public void addExtensionIllegalArgumentException() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
gpkg.extensions().addExtension(null, "ColumnNameShouldBeNull", "extension_Name", "definition", Scope.ReadWrite);
fail("Expected GeoPackageExtensions to throw an IllegalArgumentException when trying to add an extension with a null value for tableName and not columnName.");
}
}
/**
* Tests if the GeoPackage Extensions will throw
* and IllegalArgumentException when giving an
* empty string for tableName
*/
@Test(expected = IllegalArgumentException.class)
public void addExtensionIllegalArgumentException2() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
gpkg.extensions().addExtension("", "columnName", "extension_Name", "definition", Scope.ReadWrite);
fail("Expected GeoPackageExtensions to throw an IllegalArgumentException when trying to add an extension with a empty string for tableName.");
}
}
/**
* Tests if the GeoPackage Extensions will throw
* and IllegalArgumentException when giving an
* empty string for tableName
*/
@Test(expected = IllegalArgumentException.class)
public void addExtensionIllegalArgumentException3() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
gpkg.extensions().addExtension(null, "columnName", "extension_Name", "definition", Scope.ReadWrite);
fail("Expected GeoPackageExtensions to throw an IllegalArgumentException when trying to add an extension with a empty string for tableName.");
}
}
/**
* Tests if GeoPackage Extensions will throw
* and IllegalArgumentException when adding an
* Extension that has an empty string for
* tableName
*/
@Test(expected = IllegalArgumentException.class)
public void addExtensionIllegalARgumentException4() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
gpkg.extensions().addExtension("", null, "extension_Name", "definition", Scope.WriteOnly);
fail("Expected GeoPackageExtensions to throw an Illegal argument exception when column name is null and table name is an empty string.");
}
}
/**
* Tests if GeoPackage Extensions will throw an
* IllegalArgumentException when columnName is empty
*
*/
@Test(expected = IllegalArgumentException.class)
public void addExtensionIllegalArgumentException5() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
gpkg.extensions().addExtension("TableName", "" , "extension_Name", "definition", Scope.ReadWrite);
fail("Expected GeoPackageExtensions to throw an Illegal argument exception when column name and table name are empty strings.");
}
}
/**
* Tests if an IllegalArgumentException is thrown
* when trying to add an extension with a null value
* for extension name
*/
@Test(expected = IllegalArgumentException.class)
public void addExtensionIllegalArgumentException6() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
gpkg.extensions().addExtension("tableName", "columnName", null, "definition", Scope.ReadWrite);
fail("Expected GeoPackage to throw an IllegalArgumentException when trying to add an extension with a null value for extension name");
}
}
/**
* Tests if GeoPackage will throw an IllegalArgumentException when trying to
* add an extension with an empty string for extension name.
*
*/
@Test(expected = IllegalArgumentException.class)
public void addExtensionIllegalArgumentException7() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
gpkg.extensions().addExtension(null, null, "", "Definition", Scope.ReadWrite);
fail("Expected GeoPackage to throw an IllegalArgumentException when trying to add an extension with an emptry string for extension name.");
}
}
/**
* Tests if GeoPackage will throw an IllegalArgumentException when adding an
* extension that has an invalid extension name.
*
*/
@Test(expected = IllegalArgumentException.class)
public void addExtensionIllegalArgumentException8() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
gpkg.extensions().addExtension("tablename", "columnName", "illegalExtensionName", "definition", Scope.WriteOnly);
fail("Expected GeoPackage to throw an IllegalArgumentException when adding an extension that has an invalid extension name.");
}
}
/**
* Tests if the getters from Extension
* will get the right values when adding an
* extension and then checking its value
*/
@Test
public void addExtensionWithoutNullParameters() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
final String tableName ="tablename";
final String columnName = "columnName";
final String extensionName ="extension_Name";
final String definition = "definition";
final Scope scope = Scope.ReadWrite;
final Extension extensionReturned = gpkg.extensions().addExtension(tableName, columnName, extensionName, definition, scope);
assertTrue("The GeoPackage did not return the expected extension.",
extensionReturned.getTableName() .equals(tableName) &&
extensionReturned.getColumnName() .equals(columnName) &&
extensionReturned.getExtensionName() .equals(extensionName) &&
extensionReturned.getDefinition() .equals(definition) &&
extensionReturned.getScope().equals(scope.toString()));
}
}
/**
* Tests if the getters from Extension
* will get the right values when adding an
* extension when the file already contains
* the extensions table
*/
@Test
public void addExtensionWhenExtensionsTableExists() throws IOException, ClassNotFoundException, SQLException, ConformanceException
{
final File testFile = TestUtility.getRandomFile();
testFile.createNewFile();
//Create Extensions table
GeoPackageExtensionsAPITest.createExtensionsTable(testFile);
try(GeoPackage gpkg = new GeoPackage(testFile, VerificationLevel.None, OpenMode.OpenOrCreate))
{
final String tableName ="tablename";
final String columnName = "columnName";
final String extensionName ="extension_Name";
final String definition = "definition";
final Scope scope = Scope.ReadWrite;
final Extension extensionReturned = gpkg.extensions().addExtension(tableName, columnName, extensionName, definition, scope);
assertTrue("The GeoPackage did not return the expected extension.",
extensionReturned.getTableName() .equals(tableName) &&
extensionReturned.getColumnName() .equals(columnName) &&
extensionReturned.getExtensionName() .equals(extensionName) &&
extensionReturned.getDefinition() .equals(definition) &&
extensionReturned.getScope().equals(scope.toString()));
}
}
/**
* Tests that it will not add the same extension
* twice to the GeoPackage
* and return the values expected
*/
@Test
public void addExistingExtension() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
final String tableName = "tableName";
final String columnName = "columnname";
final String extensionName = "Extension_name";
final String definition = "definition";
final Scope scope = Scope.ReadWrite;
final Extension firstTime = gpkg.extensions().addExtension(tableName, columnName, extensionName, definition, scope);
final Extension secondTime = gpkg.extensions().addExtension(tableName, columnName, extensionName, definition, scope);
assertTrue("When Trying to add the same extension twice, it did not return the values expected",
firstTime.equals(secondTime.getTableName(),
secondTime.getColumnName(),
secondTime.getExtensionName(),
secondTime.getDefinition(),
Scope.fromText(secondTime.getScope())));
}
}
/**
* Tests if GeoPackage Extensions will throw an IllegalArgumentException
* when trying to add two extensions with the same tableName columnName and
* extensionName but different definition and scope values
*
*/
@Test(expected = IllegalArgumentException.class)
public void addExtensionWithSameUniqueValuesButDifferentOtherValues() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
final String tableName = null;
final String columnName = null;
final String extensionName = "Extension_name";
final String definition = "definition";
final Scope scope = Scope.ReadWrite;
gpkg.extensions().addExtension(tableName, columnName, extensionName, definition, scope);
final String differentDefinition = "different definition";
final Scope differentScope = Scope.WriteOnly;
gpkg.extensions().addExtension(tableName, columnName, extensionName, differentDefinition, differentScope);
fail("Expected GeoPackage Extensions to throw an IllegalArgumentException when trying to add two extensions "
+ "with the same tableName columnName and extensionName but different definition and scope values.");
}
}
/**
* Tests if a GeoPackage method hasExtension
* returns the proper values.
*
*/
@Test
public void testHasExtension() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
final boolean hasExtensionShouldBeFalse = gpkg.extensions().hasExtension("extension_Name");
gpkg.extensions().addExtension("tableName", "columnName", "extension_Name", "definition", Scope.ReadWrite);
final boolean hasExstensionShouldBeTrue = gpkg.extensions().hasExtension("extension_Name");
assertTrue(String.format("The hasExtension did not return the expected values. When it should be true returned: %s, when should be false returned: %s",
hasExstensionShouldBeTrue,
hasExtensionShouldBeFalse),
!hasExtensionShouldBeFalse && hasExstensionShouldBeTrue);
}
}
/**
* Tests if the getExtensions method
* returns all the extensions expected
*/
@Test
public void getExtensions() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
final Extension extension1 = gpkg.extensions().addExtension(null, null, "extension_name1", "definition", Scope.ReadWrite);
final Extension extension2 = gpkg.extensions().addExtension("table_name", null, "extension_Name2", "definition", Scope.WriteOnly);
final Extension extension3 = gpkg.extensions().addExtension("table_name2", null, "extension_Name3", "definition", Scope.ReadWrite);
final Collection<Extension> extensionsExpected = new ArrayList<>(Arrays.asList(extension1, extension2, extension3));
final Collection<Extension> extensionsReturned = gpkg.extensions().getExtensions();
assertTrue("The method getExtensions did not return the extensions expected.",
extensionsReturned.stream()
.allMatch(extensionReturned ->
extensionsExpected.stream()
.anyMatch(extensionExpected ->
extensionReturned.equals(extensionExpected.getTableName(),
extensionExpected.getColumnName(),
extensionExpected.getExtensionName(),
extensionExpected.getDefinition(),
Scope.fromText(extensionExpected.getScope())))) &&
extensionsReturned.size() == 3);
}
}
/**
* Tests if GeoPackage Extensions
* will return null when a GeoPackage
* does not have any extensions using
* the getExtensions method
*/
@Test
public void getExtensionsWithNoExtensions() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
final Collection<Extension> shouldBeNull = gpkg.extensions().getExtensions();
assertTrue("Expected GeoPackage Extensions to return an empty collection when there are no extensions "
+ "or extensions table in this geopackage when using the method getExtensions.",
shouldBeNull.isEmpty());
}
}
/**
* Tests if the equals Method in Extension
* returns the expected values
*/
@Test
public void testEqualsExtension() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
final String tableName = "table_name";
final String columnName = null;
final String extensionName = "extension_name";
final String definition = "definition";
final Scope scope = Scope.ReadWrite;
final Extension extension = gpkg.extensions().addExtension(tableName, columnName, extensionName, definition, scope);
final String columnName2 = "column_name";
assertTrue("Expected equals method in Extension would return false when it returned true (when two extensions were not equal)",
!extension.equals(tableName, columnName2, extensionName, definition, scope));
}
}
/**
* Tests if the equals Method in Extension
* returns the expected values
*/
@Test
public void testEqualsExtension2() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
final String tableName = "table_name";
final String columnName = null;
final String extensionName = "extension_name";
final String definition = "definition";
final Scope scope = Scope.ReadWrite;
final Extension extension = gpkg.extensions().addExtension(tableName, columnName, extensionName, definition, scope);
final Scope scope2 = Scope.WriteOnly;
assertTrue("Expected equals method in Extension would return false when it returned true (when two extensions were not equal)",
!extension.equals(tableName, columnName, extensionName, definition, scope2));
}
}
/**
* Tests if the equals Method in Extension
* returns the expected values
*/
@Test
public void testEqualsExtension3() throws ClassNotFoundException, ConformanceException, IOException, SQLException
{
final File testFile = TestUtility.getRandomFile();
try(GeoPackage gpkg = new GeoPackage(testFile, OpenMode.Create))
{
final String tableName = "table_name";
final String columnName = "column_name";
final String extensionName = "extension_name";
final String definition = "definition";
final Scope scope = Scope.ReadWrite;
final Extension extension = gpkg.extensions().addExtension(tableName, columnName, extensionName, definition, scope);
final String extensionName2 = "Different_extension_name";
assertTrue("Expected equals method in Extension would return false when it returned true (when two extensions were not equal)",
!extension.equals(tableName, columnName, extensionName2, definition, scope));
}
}
@Test(expected = IllegalArgumentException.class)
public void scopeFromTextIllegalArgumentException()
{
Scope.fromText("doesn't match anything");
fail("Expected GeoPackage Extensions Scope class to throw an IllegalArgumentException since the text does not match either of the cases.");
}
private static void createExtensionsTable(final File testFile) throws SQLException
{
try(final Connection connection = TestUtility.getConnection(testFile))
{
try(final Statement statement = connection.createStatement())
{
statement.executeUpdate("CREATE TABLE " + GeoPackageExtensions.ExtensionsTableName +
"(table_name TEXT, -- Name of the table that requires the extension. When NULL, the extension is required for the entire GeoPackage. SHALL NOT be NULL when the column_name is not NULL.\n" +
" column_name TEXT, -- Name of the column that requires the extension. When NULL, the extension is required for the entire table.\n" +
" extension_name TEXT NOT NULL, -- The case sensitive name of the extension that is required, in the form <author>_<extension_name>.\n" +
" definition TEXT NOT NULL, -- Definition of the extension in the form specfied by the template in GeoPackage Extension Template (Normative) or reference thereto.\n" +
" scope TEXT NOT NULL, -- Indicates scope of extension effects on readers / writers: read-write or write-only in lowercase.\n" +
" CONSTRAINT ge_tce UNIQUE (table_name, column_name, extension_name))");
}
}
}
}