/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
*
* 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;
* version 2.1 of the License.
*
* 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.
*/
package org.geotools.data.postgis.fidmapper;
import java.io.IOException;
import java.sql.Connection;
import java.sql.Types;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.geotools.data.jdbc.fidmapper.DefaultFIDMapperFactory;
import org.geotools.data.jdbc.fidmapper.FIDMapper;
import org.geotools.data.jdbc.fidmapper.FIDMapperFactory;
import org.geotools.data.jdbc.fidmapper.TypedFIDMapper;
import org.geotools.data.postgis.VersionedPostgisDataStore;
/**
* A fid mapper factory that makes sure the revision attribute does not become part of the key
* (since users outside are unaware of it).
*
* @author aaime
* @since 2.4
*
* @source $URL$
*/
public class VersionedFIDMapperFactory extends DefaultFIDMapperFactory {
Set versionedTypes = new HashSet();
private FIDMapperFactory unversionedFactory;
public VersionedFIDMapperFactory(FIDMapperFactory unversionedFactory) {
super();
this.unversionedFactory = unversionedFactory;
returnFIDColumnsAsAttributes = true;
returningTypedFIDMapper = false;
}
public void setVersionedTypes(String[] versionedTypes) {
this.versionedTypes.clear();
this.versionedTypes.addAll(Arrays.asList(versionedTypes));
}
/**
* Gets the appropriate FIDMapper for the specified table.
*
* @param catalog
* @param schema
* @param tableName
* @param connection
* the active database connection to get table key information
*
* @return the appropriate FIDMapper for the specified table.
*
* @throws IOException
* if any error occurs.
*/
public FIDMapper getMapper(String catalog, String schema, String tableName,
Connection connection) throws IOException {
// handle changesets as a special one
if(VersionedPostgisDataStore.TBL_CHANGESETS.equals(tableName)) {
PostGISAutoIncrementFIDMapper mapper = new PostGISAutoIncrementFIDMapper(VersionedPostgisDataStore.TBL_CHANGESETS, "revision", Types.NUMERIC, true);
return new TypedFIDMapper(mapper, VersionedPostgisDataStore.TBL_CHANGESETS);
}
// for non versioned types we're good with the standard mappers, but we
// must remember that versioned data store uses typed fids externally
// (only internal ones are non typed)
if (!versionedTypes.contains(tableName)) {
if(tableName.endsWith("_vfc_view")) {
try {
String otn = VersionedPostgisDataStore.getVFCTableName(tableName);
// let's see if the original feature table is there and versioned
VersionedFIDMapper mapper = (VersionedFIDMapper) getMapper(catalog, schema,otn, connection);
return new VersionedFeatureCollectionFidMapper(mapper);
// return new VersionedFeatureCollectionFidMapper(mapper);
} catch(Exception e ) {
// ok, it wasn't a versioned feature collection view
}
}
return unversionedFactory.getMapper(catalog, schema, tableName, connection);
}
ColumnInfo[] colInfos = getPkColumnInfo(catalog, schema, tableName, connection);
if (colInfos.length <= 1)
throw new IOException("Versioned type (" + tableName
+ ") with a primary key with less than 2 columns,"
+ " this cannot be, there's a error");
// assume revision is the last column
if (colInfos.length == 2) {
return buildSingleColumnVersionedFidMapper(schema, tableName, connection, colInfos);
} else {
return buildMultiColumnFIDMapper(schema, tableName, connection, colInfos);
}
}
protected FIDMapper buildSingleColumnVersionedFidMapper(String schema, String tableName,
Connection connection, ColumnInfo[] colInfos) {
ColumnInfo col = colInfos[1];
if (col.isAutoIncrement() && colInfos.length == 2) {
return new VersionedAutoincrementFIDMapper(schema, tableName, col.colName,
col.dataType, colInfos[0].decimalDigits);
} if("uuid".equals(col.getTypeName())) {
return new VersionedUUIDFIDMapper(schema, tableName, col.getColName(), col.dataType, col.size);
} else if (isIntegralType(col.dataType)) {
return buildMultiColumnFIDMapper(schema, tableName, connection, colInfos);
} else {
return buildMultiColumnFIDMapper(schema, tableName, connection, colInfos);
}
}
protected FIDMapper buildMultiColumnFIDMapper(String schema, String tableName,
Connection connection, ColumnInfo[] colInfos) {
String[] colNames = new String[colInfos.length];
int[] colTypes = new int[colInfos.length];
int[] colSizes = new int[colInfos.length];
int[] colDecimalDigits = new int[colInfos.length];
boolean[] autoIncrement = new boolean[colInfos.length];
for (int i = 0; i < colInfos.length; i++) {
ColumnInfo ci = colInfos[i];
colNames[i] = ci.colName;
colTypes[i] = ci.dataType;
colSizes[i] = ci.size;
colDecimalDigits[i] = ci.decimalDigits;
autoIncrement[i] = ci.autoIncrement;
}
return new VersionedMulticolumnFIDMapper(schema, tableName, colNames, colTypes, colSizes,
colDecimalDigits, autoIncrement);
}
}