//$Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/tools/datastore/DDLGenerator.java,v 1.25 2006/12/04 18:23:52 mschneider Exp $
/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstraße 19
53177 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.tools.datastore;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import org.deegree.datatypes.Types;
import org.deegree.datatypes.UnknownTypeException;
import org.deegree.framework.xml.XMLParsingException;
import org.deegree.framework.xml.schema.XMLSchemaException;
import org.deegree.io.datastore.schema.MappedFeaturePropertyType;
import org.deegree.io.datastore.schema.MappedFeatureType;
import org.deegree.io.datastore.schema.MappedGMLId;
import org.deegree.io.datastore.schema.MappedGMLSchema;
import org.deegree.io.datastore.schema.MappedGMLSchemaDocument;
import org.deegree.io.datastore.schema.MappedGeometryPropertyType;
import org.deegree.io.datastore.schema.MappedPropertyType;
import org.deegree.io.datastore.schema.MappedSimplePropertyType;
import org.deegree.io.datastore.schema.TableRelation;
import org.deegree.io.datastore.schema.content.MappingField;
import org.deegree.io.datastore.schema.content.SimpleContent;
import org.deegree.model.crs.UnknownCRSException;
import org.deegree.model.feature.schema.FeatureType;
import org.deegree.model.feature.schema.PropertyType;
import org.xml.sax.SAXException;
/**
* Abstract base class for DDL generation from annotated GML schema files.
* <p>
* This abstract base class only implements the functionality needed to retrieve the necessary
* tables and columns used in an annotated GML schema. DDL generation is dependent on the specific
* SQL backend to be used, so this is implemented in concrete extensions of this class.
*
* @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a>
* @author last edited by: $Author: mschneider $
*
* @version $Revision: 1.25 $, $Date: 2006/12/04 18:23:52 $
*/
public abstract class DDLGenerator {
protected static final String FT_PREFIX = "FT_";
protected static final int FEATURE_TYPE_TABLE = 0;
protected static final int JOIN_TABLE = 1;
protected static final int MULTI_PROPERTY_TABLE = 2;
protected MappedGMLSchema schema;
// key type: String (table names), value type: TableDefinition
protected Map<String, TableDefinition> tables = new HashMap<String, TableDefinition>();
/**
* Creates a new instance of <code>DDLGenerator</code> from the given parameters.
*
* @param schemaURL
* @throws MalformedURLException
* @throws IOException
* @throws SAXException
* @throws XMLParsingException
* @throws XMLSchemaException
* @throws UnknownCRSException
*/
protected DDLGenerator( URL schemaURL ) throws MalformedURLException, IOException,
SAXException, XMLParsingException, XMLSchemaException, UnknownCRSException {
System.out.println( Messages.format( "LOADING_SCHEMA_FILE", schemaURL ) );
MappedGMLSchemaDocument schemaDoc = new MappedGMLSchemaDocument();
schemaDoc.load( schemaURL );
schema = schemaDoc.parseMappedGMLSchema();
FeatureType[] featureTypes = schema.getFeatureTypes();
int concreteCount = 0;
for ( int i = 0; i < featureTypes.length; i++ ) {
if ( !featureTypes[i].isAbstract() ) {
concreteCount++;
}
}
System.out.println( Messages.format( "SCHEMA_INFO", new Integer( featureTypes.length ),
new Integer( featureTypes.length - concreteCount ),
new Integer( concreteCount ) ) );
System.out.println( Messages.getString( "RETRIEVING_TABLES" ) );
buildTableMap();
}
/**
* Returns all table definitions of the given type.
*
* @param type
* FEATURE_TYPE_TABLE, JOIN_TABLE or MULTI_PROPERTY_TABLE
* @return all table definitions of the given type.
*/
protected TableDefinition[] getTables( int type ) {
Collection<TableDefinition> tableList = new ArrayList<TableDefinition>();
Iterator iter = this.tables.keySet().iterator();
while ( iter.hasNext() ) {
String tableName = (String) iter.next();
TableDefinition table = this.tables.get( tableName );
if ( table.getType() == type ) {
tableList.add( table );
}
}
return tableList.toArray( new TableDefinition[tableList.size()] );
}
/**
* Returns the table definition for the table with the given name. If no such definition exists,
* a new table definition is created and added to the internal <code>tables</code> map.
*
* @param tableName
* table definition to look up
* @param type
* type of the table (only respected, if a new TableDefinition instance is created)
* @return the table definition for the table with the given name.
*/
private TableDefinition lookupTableDefinition( String tableName, int type ) {
TableDefinition table = this.tables.get( tableName );
if ( table == null ) {
table = new TableDefinition( tableName, type );
this.tables.put( tableName, table );
}
return table;
}
/**
* Collects the referenced tables and their columns from the input schema. Builds the member map
* <code>tables</code> from this data.
*/
private void buildTableMap() {
FeatureType[] featureTypes = schema.getFeatureTypes();
for ( int i = 0; i < featureTypes.length; i++ ) {
if ( !featureTypes[i].isAbstract() ) {
buildTableMap( (MappedFeatureType) featureTypes[i] );
}
}
}
/**
* Collects the tables and their columns used in the annotation of the given feature type.
* Builds the member map <code>tables</code> from this data.
*
* @param featureType
* feature type to process
*/
private void buildTableMap( MappedFeatureType featureType ) {
TableDefinition table = lookupTableDefinition( featureType.getTable(), FEATURE_TYPE_TABLE );
addGMLIdColumns( featureType.getGMLId(), table );
PropertyType[] properties = featureType.getProperties();
for ( int i = 0; i < properties.length; i++ ) {
MappedPropertyType property = (MappedPropertyType) properties[i];
if ( property instanceof MappedSimplePropertyType ) {
buildTableMap( (MappedSimplePropertyType) property, table );
} else if ( property instanceof MappedGeometryPropertyType ) {
buildTableMap( (MappedGeometryPropertyType) property, table );
} else if ( property instanceof MappedFeaturePropertyType ) {
buildTableMap( (MappedFeaturePropertyType) property, table );
} else {
throw new RuntimeException( Messages.format( "ERROR_UNEXPECTED_PROPERTY_TYPE",
property.getClass().getName() ) );
}
}
}
/**
* Adds the columns used in the given <code>MappedGMLId</code> to the also given
* <code>TableDefinition</code>.
*
* @param gmlId
* columns are taken from this gmlId mapping
* @param table
* columns are added to this table definition
*/
private void addGMLIdColumns( MappedGMLId gmlId, TableDefinition table ) {
MappingField[] idFields = gmlId.getIdFields();
for ( int i = 0; i < idFields.length; i++ ) {
ColumnDefinition column = new ColumnDefinition( idFields[i].getField(),
idFields[i].getType(), false, true );
table.addColumn( column );
}
}
/**
* Collects the tables and their columns used in the annotation of the given simple property
* type. Builds the <code>table</code> member map from this data.
* <p>
* If the data for the property is stored in a related table, the table and column information
* used on the path to this table is also added to the <code>tables</code> member map.
*
* @param simpleProperty
* simple property type to process
* @param table
* table definition associated with the property definition
*/
private void buildTableMap( MappedSimplePropertyType simpleProperty, TableDefinition table ) {
Collection<ColumnDefinition> newColumns = new ArrayList<ColumnDefinition>();
// array must always have length 1
TableRelation[] relations = simpleProperty.getTableRelations();
if ( simpleProperty.getMaxOccurs() != 1 && ( relations == null || relations.length < 1 ) ) {
throw new RuntimeException( Messages.format( "ERROR_INVALID_PROPERTY_DEFINITION",
simpleProperty.getName() ) );
}
SimpleContent content = simpleProperty.getContent();
if ( content instanceof MappingField ) {
MappingField mf = (MappingField) content;
if ( relations == null || relations.length == 0 ) {
newColumns.add( new ColumnDefinition( mf.getField(), mf.getType(),
simpleProperty.getMinOccurs() == 0, false ) );
} else {
TableRelation firstRelation = relations[0];
MappingField[] fromFields = firstRelation.getFromFields();
for ( int i = 0; i < fromFields.length; i++ ) {
MappingField fromField = fromFields[i];
newColumns.add( new ColumnDefinition( fromField.getField(),
fromField.getType(), false, false ) );
}
buildTableMap( relations, mf );
}
} else {
String msg = "Ignoring property '" + simpleProperty + "' - has virtual content.";
System.out.println( msg );
}
table.addColumns( newColumns );
}
/**
* Collects the tables and their columns used in the annotation of the given geometry property
* type. Builds the <code>table</code> member map from this data.
* <p>
* If the geometry for the property is stored in a related table, the table and column
* information used on the path to this table is also added to the <code>tables</code> member
* map.
*
* @param geometryProperty
* feature property type to process
* @param table
* table definition associated with the property definition
*/
private void buildTableMap( MappedGeometryPropertyType geometryProperty, TableDefinition table ) {
Collection<ColumnDefinition> newColumns = new ArrayList<ColumnDefinition>();
TableRelation[] relations = geometryProperty.getTableRelations();
if ( geometryProperty.getMaxOccurs() != 1 && ( relations == null || relations.length < 1 ) ) {
throw new RuntimeException( Messages.format( "ERROR_INVALID_PROPERTY_DEFINITION",
geometryProperty.getName() ) );
}
if ( relations == null || relations.length == 0 ) {
newColumns.add( new ColumnDefinition( geometryProperty.getMappingField().getField(),
geometryProperty.getMappingField().getType(),
geometryProperty.getMinOccurs() == 0, true ) );
} else {
TableRelation firstRelation = relations[0];
MappingField[] fromFields = firstRelation.getFromFields();
for ( int i = 0; i < fromFields.length; i++ ) {
MappingField fromField = fromFields[i];
newColumns.add( new ColumnDefinition( fromField.getField(), fromField.getType(),
false, true ) );
}
buildTableMap( relations, geometryProperty.getMappingField() );
}
table.addColumns( newColumns );
}
/**
* Collects the tables and their columns used in the annotation of the given feature property
* type. Builds the <code>table</code> member map from this data.
* <p>
* The table and column information used on the path to the table of the feature type is also
* added to the <code>tables</code> member map.
*
* @param featureProperty
* feature property type to process
* @param table
* table definition associated with the property definition
*/
private void buildTableMap( MappedFeaturePropertyType featureProperty, TableDefinition table ) {
Collection<ColumnDefinition> newColumns = new ArrayList<ColumnDefinition>();
// array must always have length 1
TableRelation[] relations = featureProperty.getTableRelations();
// target feature type table must always be accessed via 'Relation'-elements
if ( relations == null || relations.length < 1 ) {
throw new RuntimeException(
Messages.format(
"ERROR_INVALID_FEATURE_PROPERTY_DEFINITION_1",
featureProperty.getName() ) );
}
// maxOccurs > 1: target feature type table must be accessed via join table
if ( featureProperty.getMaxOccurs() != 1 && ( relations.length < 2 ) ) {
throw new RuntimeException(
Messages.format(
"ERROR_INVALID_FEATURE_PROPERTY_DEFINITION_2",
featureProperty.getName() ) );
}
// add this feature type's key columns to current table
TableRelation firstRelation = relations[0];
MappingField[] fromFields = firstRelation.getFromFields();
boolean isNullable = featureProperty.getMinOccurs() == 0 && relations.length == 1;
for ( int i = 0; i < fromFields.length; i++ ) {
MappingField fromField = fromFields[i];
newColumns.add( new ColumnDefinition( fromField.getField(), fromField.getType(),
isNullable, false ) );
}
table.addColumns( newColumns );
MappedFeatureType contentType = featureProperty.getFeatureTypeReference().getFeatureType();
buildTableMap( relations, featureProperty, contentType );
}
/**
* Collects the tables and their columns used in the relation tables from a simple/geometry
* property to it's content table. Builds the <code>table</code> member map from this data.
*
* @param relations
* relation tables from annotation of property type
* @param targetField
* holds the properties data
*/
private void buildTableMap( TableRelation[] relations, MappingField targetField ) {
// process tables used in 'To'-element of each 'Relation'-element
for ( int i = 0; i < relations.length; i++ ) {
String tableName = relations[i].getToTable();
TableDefinition table = lookupTableDefinition( tableName, MULTI_PROPERTY_TABLE );
MappingField[] toFields = relations[i].getToFields();
for ( int j = 0; j < toFields.length; j++ ) {
ColumnDefinition column = new ColumnDefinition( toFields[j].getField(),
toFields[j].getType(), false, false );
table.addColumn( column );
}
}
// process table used in 'To'-element of last 'Relation'-element (targetField refers to
// this)
ColumnDefinition column = new ColumnDefinition( targetField.getField(),
targetField.getType(), false, false );
TableDefinition table = lookupTableDefinition(
relations[relations.length - 1].getToTable(),
MULTI_PROPERTY_TABLE );
table.addColumn( column );
}
/**
* Collects the tables and their columns used in the relation tables from a feature property to
* it's content feature type. Builds the <code>table</code> member map from this data.
*
* @param relations
* relation tables from annotation of feature property type
* @param property
* @param targetType
* type contained in the feature property
*/
private void buildTableMap( TableRelation[] relations, MappedPropertyType property,
MappedFeatureType targetType ) {
TableDefinition table = lookupTableDefinition( relations[0].getFromTable(),
FEATURE_TYPE_TABLE );
// process tables used in 'To'-element of each 'Relation'-element (except the last)
for ( int i = 0; i < relations.length - 1; i++ ) {
String tableName = relations[i].getToTable();
table = lookupTableDefinition( tableName, JOIN_TABLE );
MappingField[] toFields = relations[i].getToFields();
for ( int j = 0; j < toFields.length; j++ ) {
ColumnDefinition column = new ColumnDefinition( toFields[j].getField(),
toFields[j].getType(), false, false );
table.addColumn( column );
}
}
// process table used in 'To'-element of last 'Relation'-element
FeatureType[] concreteTypes = targetType.getGMLSchema().getSubstitutions( targetType );
MappingField[] toFields = relations[relations.length - 1].getToFields();
// if it refers to several target tables (target feature type is abstract), an additional
// column is needed (which determines the target feature type)
if ( concreteTypes.length > 1 ) {
String typeColumn = "featuretype";
if ( relations.length == 1 ) {
typeColumn = FT_PREFIX + property.getName().getLocalName().toUpperCase();
}
ColumnDefinition column = new ColumnDefinition( typeColumn, Types.VARCHAR, false, false );
table.addColumn( column );
}
for ( int i = 0; i < concreteTypes.length; i++ ) {
MappedFeatureType concreteType = (MappedFeatureType) concreteTypes[i];
String tableName = concreteType.getTable();
table = lookupTableDefinition( tableName, FEATURE_TYPE_TABLE );
for ( int j = 0; j < toFields.length; j++ ) {
ColumnDefinition column = new ColumnDefinition( toFields[j].getField(),
toFields[j].getType(), false, false );
table.addColumn( column );
}
}
// process tables used in 'From'-element of each 'Relation'-element (except the first)
for ( int i = 1; i < relations.length; i++ ) {
String tableName = relations[i].getFromTable();
if ( i != relations.length - 1 ) {
table = lookupTableDefinition( tableName, JOIN_TABLE );
} else {
table = lookupTableDefinition( tableName, FEATURE_TYPE_TABLE );
}
MappingField[] fromFields = relations[i].getFromFields();
for ( int j = 0; j < fromFields.length; j++ ) {
ColumnDefinition column = new ColumnDefinition( fromFields[j].getField(),
fromFields[j].getType(), false,
false );
table.addColumn( column );
}
}
}
/**
* Generates the DDL statements that can be used to build a relational schema that backs the
* GML schema.
*
* @param outputFile
* @throws IOException
*/
public void generateCreateScript( String outputFile )
throws IOException {
PrintWriter writer = new PrintWriter( new FileWriter( outputFile ) );
TableDefinition[] tables = getTables( FEATURE_TYPE_TABLE );
System.out.println( Messages.format( "CREATE_FEATURE_TYPE", new Integer( tables.length ) ) );
for ( int i = 0; i < tables.length; i++ ) {
writer.println( generateCreateStatements( tables[i] ) );
}
tables = getTables( JOIN_TABLE );
System.out.println( Messages.format( "CREATE_JOIN_TABLES", new Integer( tables.length ) ) );
for ( int i = 0; i < tables.length; i++ ) {
writer.println( generateCreateStatements( tables[i] ) );
}
tables = getTables( MULTI_PROPERTY_TABLE );
System.out.println( Messages.format( "CREATE_PROPERTY_TABLES", new Integer( tables.length ) ) );
for ( int i = 0; i < tables.length; i++ ) {
writer.println( generateCreateStatements( tables[i] ) );
}
writer.close();
}
/**
* Generates the DDL statements necessary for the creation of the given table definition. Must
* be overwritten by the concrete implementation.
*
* @param table
* @return the DDL statements necessary for the creation of the given table definition
*/
protected abstract StringBuffer generateCreateStatements( TableDefinition table );
/**
* Generates the DDL statements that can be used to remove the relational schema again.
*
* @param outputFile
* @throws IOException
*/
public void generateDropScript( String outputFile )
throws IOException {
PrintWriter writer = new PrintWriter( new FileWriter( outputFile ) );
TableDefinition[] tables = getTables( FEATURE_TYPE_TABLE );
System.out.println( Messages.format( "DROP_FEATURE_TYPE", new Integer( tables.length ) ) );
for ( int i = 0; i < tables.length; i++ ) {
writer.println( generateDropStatements( tables[i] ) );
}
tables = getTables( JOIN_TABLE );
System.out.println( Messages.format( "DROP_JOIN_TABLES", new Integer( tables.length ) ) );
for ( int i = 0; i < tables.length; i++ ) {
writer.println( generateDropStatements( tables[i] ) );
}
tables = getTables( MULTI_PROPERTY_TABLE );
System.out.println( Messages.format( "DROP_PROPERTY_TABLES", new Integer( tables.length ) ) );
for ( int i = 0; i < tables.length; i++ ) {
writer.println( generateDropStatements( tables[i] ) );
}
writer.close();
}
/**
* Generates the DDL statements necessary for the removal of the given table definition. Must
* be overwritten by the concrete implementation.
*
* @param table
* @return the DDL statements necessary for the removal of the given table definition
*/
protected abstract StringBuffer generateDropStatements( TableDefinition table );
/**
* @param args
* @throws IOException
* @throws SAXException
* @throws XMLParsingException
* @throws XMLSchemaException
* @throws UnknownCRSException
*/
public static void main( String[] args )
throws IOException, SAXException, XMLParsingException,
XMLSchemaException, UnknownCRSException {
if ( args.length != 4 ) {
System.out.println( "Usage: DDLGenerator [FLAVOUR] <input.xsd> <create.sql> <drop.sql>" );
System.exit( 0 );
}
String flavour = args[0];
String schemaFile = args[1];
String createFile = args[2];
String dropFile = args[3];
DDLGenerator generator = null;
if ( "POSTGIS".equals( flavour ) ) {
generator = new PostGISDDLGenerator( new File( schemaFile ).toURL() );
} else {
System.out.println( Messages.format( "ERROR_UNSUPPORTED_FLAVOUR", flavour ) );
}
generator.generateCreateScript( createFile );
generator.generateDropScript( dropFile );
}
/**
* Returns a string representation of the object.
*
* @return a string representation of the object.
*/
@Override
public String toString() {
StringBuffer sb = new StringBuffer( Messages.getString( "RELATIONAL_SCHEMA" ) );
sb.append( '\n' );
TableDefinition[] tables = getTables( FEATURE_TYPE_TABLE );
sb.append( '\n' );
sb.append( tables.length );
sb.append( " feature type tables\n\n" );
for ( int i = 0; i < tables.length; i++ ) {
sb.append( tables[i] );
sb.append( '\n' );
}
sb.append( '\n' );
tables = getTables( JOIN_TABLE );
sb.append( tables.length );
sb.append( " join tables\n\n" );
for ( int i = 0; i < tables.length; i++ ) {
sb.append( tables[i] );
sb.append( '\n' );
}
sb.append( '\n' );
tables = getTables( MULTI_PROPERTY_TABLE );
sb.append( tables.length );
sb.append( " property tables\n\n" );
for ( int i = 0; i < tables.length; i++ ) {
sb.append( tables[i] );
sb.append( '\n' );
}
return sb.toString();
}
class TableDefinition {
private int type;
private String tableName;
private Map<String, ColumnDefinition> columnsMap = new LinkedHashMap<String, ColumnDefinition>();
TableDefinition( String tableName, int type ) {
this.type = type;
this.tableName = tableName;
}
String getName() {
return this.tableName;
}
int getType() {
return this.type;
}
ColumnDefinition[] getColumns() {
Collection<ColumnDefinition> columns = new ArrayList<ColumnDefinition>();
Iterator iter = columnsMap.keySet().iterator();
while ( iter.hasNext() ) {
String columnName = (String) iter.next();
columns.add( columnsMap.get( columnName ) );
}
return columns.toArray( new ColumnDefinition[columns.size()] );
}
ColumnDefinition[] getPKColumns() {
Collection<ColumnDefinition> columns = new ArrayList<ColumnDefinition>();
Iterator iter = columnsMap.keySet().iterator();
while ( iter.hasNext() ) {
String columnName = (String) iter.next();
ColumnDefinition column = columnsMap.get( columnName );
if ( column.isPartOfPK() ) {
columns.add( columnsMap.get( columnName ) );
}
}
return columns.toArray( new ColumnDefinition[columns.size()] );
}
ColumnDefinition getColumn( String name ) {
return columnsMap.get( name );
}
void addColumn( ColumnDefinition column ) {
ColumnDefinition oldColumn = columnsMap.get( column.getName() );
if ( oldColumn != null ) {
if ( !( column.getType() == oldColumn.getType() ) ) {
String msg = Messages.format( "ERROR_COLUMN_DEFINITION_TYPES",
column.getName(),
oldColumn.isNullable() ? "NULLABLE"
: "NOT NULLABLE",
column.isNullable() ? "NULLABLE" : "NOT NULLABLE" );
throw new RuntimeException( msg );
}
if ( oldColumn.isPartOfPK() ) {
column = oldColumn;
}
}
columnsMap.put( column.getName(), column );
}
void addColumns( Collection columns ) {
Iterator iter = columns.iterator();
while ( iter.hasNext() ) {
ColumnDefinition column = (ColumnDefinition) iter.next();
addColumn( column );
}
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append( Messages.format( "TABLE", this.tableName ) );
sb.append( Messages.getString( "PRIMARY_KEY" ) );
ColumnDefinition[] pkColumns = getPKColumns();
for ( int i = 0; i < pkColumns.length; i++ ) {
sb.append( '"' );
sb.append( pkColumns[i].getName() );
sb.append( '"' );
if ( i != pkColumns.length - 1 ) {
sb.append( ", " );
}
}
sb.append( '\n' );
Iterator columnNameIter = this.columnsMap.keySet().iterator();
while ( columnNameIter.hasNext() ) {
String columnName = (String) columnNameIter.next();
ColumnDefinition column = this.columnsMap.get( columnName );
try {
sb.append( Messages.format(
"COLUMN",
columnName,
Types.getTypeNameForSQLTypeCode( column.getType() ),
new Boolean( column.isNullable() ) ) );
} catch ( UnknownTypeException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sb.append( '\n' );
}
return sb.toString();
}
}
class ColumnDefinition {
private String columnName;
private int type;
private boolean isNullable;
private boolean isGeometryColumn;
private boolean isPartOfPK;
ColumnDefinition( String columnName, int type, boolean isNullable, boolean isGeometryColumn ) {
this.columnName = columnName;
this.type = type;
this.isNullable = isNullable;
this.isGeometryColumn = isGeometryColumn;
}
ColumnDefinition( String columnName, int type, boolean isNullable, boolean isPartOfPK,
boolean isGeometryColumn ) {
this( columnName, type, isNullable, isGeometryColumn );
this.isPartOfPK = isPartOfPK;
}
String getName() {
return this.columnName;
}
int getType() {
return this.type;
}
boolean isNullable() {
return this.isNullable;
}
boolean isGeometry() {
return this.isGeometryColumn;
}
boolean isPartOfPK() {
return this.isPartOfPK;
}
}
}
/***************************************************************************************************
* $Log: DDLGenerator.java,v $
* Revision 1.25 2006/12/04 18:23:52 mschneider
* Changed spelling for feature type disambiguation columns (FT_XYZ) to uppercase.
*
* Revision 1.24 2006/11/27 09:07:52 poth
* JNI integration of proj4 has been removed. The CRS functionality now will be done by native deegree code.
*
* Revision 1.23 2006/11/23 15:25:03 mschneider
* Javadoc fixed.
*
* Revision 1.22 2006/08/31 14:59:09 mschneider
* Javadoc fixes.
*
* Revision 1.21 2006/08/24 06:43:54 poth
* File header corrected
*
* Revision 1.20 2006/08/23 16:37:52 mschneider
* Added handling of virtual properties. Needs testing.
*
* Revision 1.19 2006/08/22 18:14:42 mschneider
* Refactored due to cleanup of org.deegree.io.datastore.schema package.
*
* Revision 1.18 2006/08/21 16:42:36 mschneider
* Refactored due to cleanup (and splitting) of org.deegree.io.datastore.schema package.
*
* Revision 1.17 2006/08/21 15:49:59 mschneider
* Changes due to removing of (unused + outdated) FeatureArrayPropertyType.
*
* Revision 1.16 2006/04/06 20:25:29 poth
* *** empty log message ***
*
* Revision 1.15 2006/04/04 20:39:43 poth
* *** empty log message ***
*
* Revision 1.14 2006/03/30 21:20:27 poth
* *** empty log message ***
*
* Revision 1.13 2006/01/31 16:27:14 mschneider
* Changes due to refactoring of org.deegree.model.feature package.
*
* Revision 1.12 2006/01/18 19:20:35 mschneider
* Adapted to type code for MappingFields (instead of typeName).
*
* Revision 1.11 2005/12/29 10:55:58 mschneider
* Cleanup. Moved WhereBuilder specific classes to own package.
*
* Revision 1.10 2005/12/22 02:16:19 mschneider
* Changed name of featuretype columns.
*
* Revision 1.9 2005/12/20 14:50:27 mschneider
* Renamed #getFeatureType() to #getFeatureTypeReference().
*
* Revision 1.8 2005/12/13 23:14:36 mschneider
* Added extraction of table definitions need for feature properties.
*
* Revision 1.7 2005/12/12 22:46:32 mschneider
* Cleanup, javadoc, extraction of messages to ResourceBundle.
*
* Revision 1.6 2005/12/12 17:10:09 mschneider
* Moving common functionality to DDLGenerator.
*
* Revision 1.5 2005/12/09 14:52:55 mschneider
* Added creation of Drop-Statements to remove tables again. Cleaned up output.
*
* Revision 1.4 2005/12/08 22:24:24 mschneider
* Added support for feature type fields, so ambigous foreign keys can be resolved properly.
*
* Revision 1.3 2005/12/08 21:45:10 mschneider
* Style fixes.
*
* Revision 1.2 2005/12/08 20:49:28 mschneider
* Fixed error message.
*
* Revision 1.1 2005/12/08 20:48:51 mschneider
* Initial version.
**************************************************************************************************/