// Path: src/main/java/liquibase/ext/spatial/datatype/GeometryType.java
// @DataTypeInfo(name = "geometry", aliases = { "com.vividsolutions.jts.geom.Geometry" }, minParameters = 0, maxParameters = 2, priority = LiquibaseDataType.PRIORITY_DEFAULT)
// public class GeometryType extends LiquibaseDataType {
//    /**
//     * Returns the value geometry type parameter.
//     * 
//     * @return the geometry type or <code>null</code> if not present.
//     */
//    public String getGeometryType() {
//       String geometryType = null;
//       if (getParameters().length > 0 && getParameters()[0] != null) {
//          geometryType = getParameters()[0].toString();
//       }
//       return geometryType;
//    }
// 
//    /**
//     * Returns the value SRID parameter.
//     * 
//     * @return the SRID or <code>null</code> if not present.
//     */
//    public Integer getSRID() {
//       Integer srid = null;
//       if (getParameters().length > 1 && getParameters()[1] != null) {
//          srid = Integer.valueOf(getParameters()[1].toString());
//       }
//       return srid;
//    }
// 
//    /**
//     * Creates the appropriate Geometry <code>DatabaseDataType</code>.
//     */
//    @Override
//    public DatabaseDataType toDatabaseDataType(final Database database) {
//       final DatabaseDataType databaseDataType;
//       if (database instanceof DerbyDatabase) {
//          databaseDataType = new DatabaseDataType("VARCHAR(32672) FOR BIT DATA");
//       } else if (database instanceof H2Database) {
//          // User's wanting to use a BLOB can use modifySql.
//          databaseDataType = new DatabaseDataType("BINARY");
//       } else if (database instanceof OracleDatabase) {
//          databaseDataType = new DatabaseDataType("SDO_GEOMETRY");
//       } else if (database instanceof PostgresDatabase) {
//          databaseDataType = new DatabaseDataType(getName(), getParameters());
//       } else {
//          databaseDataType = new DatabaseDataType("GEOMETRY");
//       }
//       return databaseDataType;
//    }
// 
//    /**
//     * @see liquibase.datatype.LiquibaseDataType#objectToSql(java.lang.Object,
//     *      liquibase.database.Database)
//     */
//    @Override
//    public String objectToSql(final Object value, final Database database) {
//       final String returnValue;
//       if (value instanceof Geometry) {
//          // TODO: Tailor the output for the database.
//          returnValue = ((Geometry) value).toText();
//       } else if (value instanceof String) {
//          returnValue = value.toString();
//       } else if (value instanceof DatabaseFunction) {
//          returnValue = value.toString();
//       } else if (value == null || value.toString().equalsIgnoreCase("null")) {
//          returnValue = null;
//       } else {
//          throw new UnexpectedLiquibaseException("Cannot convert type " + value.getClass()
//                + " to a Geometry value");
//       }
//       return returnValue;
//    }
// 
//    /**
//     * @see liquibase.datatype.LiquibaseDataType#sqlToObject(java.lang.String,
//     *      liquibase.database.Database)
//     */
//    @Override
//    public Object sqlToObject(final String value, final Database database) {
//       final Geometry returnValue;
//       if (value == null || value.equalsIgnoreCase("null")) {
//          returnValue = null;
//       } else {
//          final WKTReader reader = new WKTReader();
//          try {
//             // TODO: Check for SRID.
//             returnValue = reader.read(value);
//          } catch (final ParseException e) {
//             throw new UnexpectedLiquibaseException("Cannot parse " + value + " to a Geometry", e);
//          }
//       }
//       return returnValue;
//    }
// }


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import liquibase.database.Database;
import liquibase.database.core.DerbyDatabase;
import liquibase.database.core.H2Database;
import liquibase.datatype.DataTypeFactory;
import liquibase.datatype.LiquibaseDataType;
import liquibase.exception.ValidationErrors;
import liquibase.ext.spatial.datatype.GeometryType;
import liquibase.sql.Sql;
import liquibase.sql.UnparsedSql;
import liquibase.sqlgenerator.SqlGenerator;
import liquibase.sqlgenerator.SqlGeneratorChain;
import liquibase.sqlgenerator.core.AbstractSqlGenerator;
import liquibase.statement.core.AddColumnStatement;
import liquibase.util.StringUtils;
package liquibase.ext.spatial.sqlgenerator;



/**
 * <code>AddGeometryColumnGeneratorGeoDB</code> is a SQL generator that
 * specializes in GeoDB. Regardless of the column type, the next SQL generator
 * in the chain is invoked to handle the normal column addition. If the column
 * to be added has a geometry type, the <code>AddGeometryColumn</code> stored
 * procedure is invoked to ensure that the necessary metadata is created in the
 * database.
 */
public class AddGeometryColumnGeneratorGeoDB extends
      AbstractSqlGenerator<AddColumnStatement> {
   /**
    * @see liquibase.sqlgenerator.core.AbstractSqlGenerator#supports(liquibase.statement.SqlStatement,
    *      liquibase.database.Database)
    */
   @Override
   public boolean supports(final AddColumnStatement statement,
         final Database database) {
      return database instanceof DerbyDatabase
            || database instanceof H2Database;
   }

   /**
    * @see liquibase.sqlgenerator.core.AbstractSqlGenerator#getPriority()
    */
   @Override
   public int getPriority() {
      return SqlGenerator.PRIORITY_DATABASE + 1;
   }

   @Override
   public ValidationErrors validate(final AddColumnStatement statement,
         final Database database, final SqlGeneratorChain sqlGeneratorChain) {
      final ValidationErrors errors = new ValidationErrors();
      final LiquibaseDataType dataType = DataTypeFactory.getInstance()
            .fromDescription(statement.getColumnType(), database);

      // Ensure that the SRID parameter is provided.
// Path: src/main/java/liquibase/ext/spatial/datatype/GeometryType.java
// @DataTypeInfo(name = "geometry", aliases = { "com.vividsolutions.jts.geom.Geometry" }, minParameters = 0, maxParameters = 2, priority = LiquibaseDataType.PRIORITY_DEFAULT)
// public class GeometryType extends LiquibaseDataType {
//    /**
//     * Returns the value geometry type parameter.
//     * 
//     * @return the geometry type or <code>null</code> if not present.
//     */
//    public String getGeometryType() {
//       String geometryType = null;
//       if (getParameters().length > 0 && getParameters()[0] != null) {
//          geometryType = getParameters()[0].toString();
//       }
//       return geometryType;
//    }
// 
//    /**
//     * Returns the value SRID parameter.
//     * 
//     * @return the SRID or <code>null</code> if not present.
//     */
//    public Integer getSRID() {
//       Integer srid = null;
//       if (getParameters().length > 1 && getParameters()[1] != null) {
//          srid = Integer.valueOf(getParameters()[1].toString());
//       }
//       return srid;
//    }
// 
//    /**
//     * Creates the appropriate Geometry <code>DatabaseDataType</code>.
//     */
//    @Override
//    public DatabaseDataType toDatabaseDataType(final Database database) {
//       final DatabaseDataType databaseDataType;
//       if (database instanceof DerbyDatabase) {
//          databaseDataType = new DatabaseDataType("VARCHAR(32672) FOR BIT DATA");
//       } else if (database instanceof H2Database) {
//          // User's wanting to use a BLOB can use modifySql.
//          databaseDataType = new DatabaseDataType("BINARY");
//       } else if (database instanceof OracleDatabase) {
//          databaseDataType = new DatabaseDataType("SDO_GEOMETRY");
//       } else if (database instanceof PostgresDatabase) {
//          databaseDataType = new DatabaseDataType(getName(), getParameters());
//       } else {
//          databaseDataType = new DatabaseDataType("GEOMETRY");
//       }
//       return databaseDataType;
//    }
// 
//    /**
//     * @see liquibase.datatype.LiquibaseDataType#objectToSql(java.lang.Object,
//     *      liquibase.database.Database)
//     */
//    @Override
//    public String objectToSql(final Object value, final Database database) {
//       final String returnValue;
//       if (value instanceof Geometry) {
//          // TODO: Tailor the output for the database.
//          returnValue = ((Geometry) value).toText();
//       } else if (value instanceof String) {
//          returnValue = value.toString();
//       } else if (value instanceof DatabaseFunction) {
//          returnValue = value.toString();
//       } else if (value == null || value.toString().equalsIgnoreCase("null")) {
//          returnValue = null;
//       } else {
//          throw new UnexpectedLiquibaseException("Cannot convert type " + value.getClass()
//                + " to a Geometry value");
//       }
//       return returnValue;
//    }
// 
//    /**
//     * @see liquibase.datatype.LiquibaseDataType#sqlToObject(java.lang.String,
//     *      liquibase.database.Database)
//     */
//    @Override
//    public Object sqlToObject(final String value, final Database database) {
//       final Geometry returnValue;
//       if (value == null || value.equalsIgnoreCase("null")) {
//          returnValue = null;
//       } else {
//          final WKTReader reader = new WKTReader();
//          try {
//             // TODO: Check for SRID.
//             returnValue = reader.read(value);
//          } catch (final ParseException e) {
//             throw new UnexpectedLiquibaseException("Cannot parse " + value + " to a Geometry", e);
//          }
//       }
//       return returnValue;
//    }
// }


// Path: src/main/java/liquibase/ext/spatial/sqlgenerator/AddGeometryColumnGeneratorGeoDB.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import liquibase.database.Database;
import liquibase.database.core.DerbyDatabase;
import liquibase.database.core.H2Database;
import liquibase.datatype.DataTypeFactory;
import liquibase.datatype.LiquibaseDataType;
import liquibase.exception.ValidationErrors;
import liquibase.ext.spatial.datatype.GeometryType;
import liquibase.sql.Sql;
import liquibase.sql.UnparsedSql;
import liquibase.sqlgenerator.SqlGenerator;
import liquibase.sqlgenerator.SqlGeneratorChain;
import liquibase.sqlgenerator.core.AbstractSqlGenerator;
import liquibase.statement.core.AddColumnStatement;
import liquibase.util.StringUtils;

package liquibase.ext.spatial.sqlgenerator;



/**
 * <code>AddGeometryColumnGeneratorGeoDB</code> is a SQL generator that
 * specializes in GeoDB. Regardless of the column type, the next SQL generator
 * in the chain is invoked to handle the normal column addition. If the column
 * to be added has a geometry type, the <code>AddGeometryColumn</code> stored
 * procedure is invoked to ensure that the necessary metadata is created in the
 * database.
 */
public class AddGeometryColumnGeneratorGeoDB extends
      AbstractSqlGenerator<AddColumnStatement> {
   /**
    * @see liquibase.sqlgenerator.core.AbstractSqlGenerator#supports(liquibase.statement.SqlStatement,
    *      liquibase.database.Database)
    */
   @Override
   public boolean supports(final AddColumnStatement statement,
         final Database database) {
      return database instanceof DerbyDatabase
            || database instanceof H2Database;
   }

   /**
    * @see liquibase.sqlgenerator.core.AbstractSqlGenerator#getPriority()
    */
   @Override
   public int getPriority() {
      return SqlGenerator.PRIORITY_DATABASE + 1;
   }

   @Override
   public ValidationErrors validate(final AddColumnStatement statement,
         final Database database, final SqlGeneratorChain sqlGeneratorChain) {
      final ValidationErrors errors = new ValidationErrors();
      final LiquibaseDataType dataType = DataTypeFactory.getInstance()
            .fromDescription(statement.getColumnType(), database);

      // Ensure that the SRID parameter is provided.
      if (dataType instanceof GeometryType) {