in ctakes-ytex-uima/src/main/java/org/apache/ctakes/ytex/uima/mapper/DocumentMapperServiceImpl.java [575:752]
private AnnoMappingInfo initMapInfo(final FeatureStructure fs) {
final Type type = fs.getType();
final String annoName = type.getShortName().toLowerCase();
AnnoMappingInfo mapInfoTmp;
final UimaType ut = uimaTypeMap.get(type.getName());
if (this.mapAnnoMappingInfo.containsKey(type.getName())) {
mapInfoTmp = this.mapAnnoMappingInfo.get(type.getName()).deepCopy();
} else {
mapInfoTmp = new AnnoMappingInfo();
}
final AnnoMappingInfo mapInfo = mapInfoTmp;
if (ut != null)
mapInfo.setUimaTypeId(ut.getUimaTypeID());
// first see if the table name has been set in beans-uima.xml
if (Strings.isNullOrEmpty(mapInfo.getTableName())) {
// next see if the table name has been set in ref_uima_type
if (ut != null && !Strings.isNullOrEmpty(ut.getTableName()))
mapInfo.setTableName(ut.getTableName());
else
// default to anno_[short name]
mapInfo.setTableName("anno_" + annoName);
}
final List<Feature> features = type.getFeatures();
// get the non primitive fields
for (Feature f : features) {
if (f.getRange().isArray()
&& !f.getRange().getComponentType().isPrimitive()) {
// add this field to the list of fields to store
this.tl_mapFieldInfo.get()
.put(type.getName(), f.getShortName());
}
}
this.sessionFactory.getCurrentSession().doWork(new Work() {
@Override
public void execute(Connection conn) throws SQLException {
ResultSet rs = null;
try {
DatabaseMetaData dmd = conn.getMetaData();
// get columns for corresponding table
// mssql - add schema prefix
// oracle - convert table name to upper case
rs = dmd.getColumns(
null,
"mssql".equals(dbType) || "hsql".equals(dbType) ? dbSchema
: null,
"orcl".equals(dbType) || "hsql".equals(dbType) ? mapInfo
.getTableName().toUpperCase() : mapInfo
.getTableName(), null);
while (rs.next()) {
String colName = rs.getString("COLUMN_NAME");
int colSize = rs.getInt("COLUMN_SIZE");
int dataType = rs.getInt("DATA_TYPE");
if ("anno_base_id".equalsIgnoreCase(colName)) {
// skip anno_base_id
continue;
}
if ("uima_type_id".equalsIgnoreCase(colName)) {
// see if there is a uima_type_id column
// for FeatureStructures that are not annotations
// there can be a field for the uima_type_id
if (!(fs instanceof Annotation)
&& Strings.isNullOrEmpty(mapInfo
.getUimaTypeIdColumnName())) {
mapInfo.setUimaTypeIdColumnName(colName);
}
} else if ("coveredText".equalsIgnoreCase(colName)) {
// see if there is a coveredText column, store the
// covered
// text here
ColumnMappingInfo coveredTextColumn = new ColumnMappingInfo();
coveredTextColumn.setColumnName(colName);
mapInfo.setCoveredTextColumn(coveredTextColumn);
coveredTextColumn.setSize(colSize);
} else {
// possibility 1: the column is already mapped to
// the field
// if so, then just set the size
if (!updateSize(mapInfo, colName, colSize, dataType)) {
// possibility 2: the column is not mapped - see
// if
// it matches a field
// iterate through features, see which match the
// column
for (Feature f : features) {
String annoFieldName = f.getShortName();
if (f.getRange().isPrimitive()
&& annoFieldName
.equalsIgnoreCase(colName)) {
// primitive attribute
ColumnMappingInfo fmap = new ColumnMappingInfo();
fmap.setAnnoFieldName(annoFieldName);
fmap.setColumnName(colName);
fmap.setSize(colSize);
fmap.setSqlType(dataType);
mapInfo.getMapField()
.put(colName, fmap);
break;
} else if (!f.getRange().isArray()
&& !f.getRange().isPrimitive()
&& annoFieldName
.equalsIgnoreCase(colName)
&& (dataType == Types.INTEGER
|| dataType == Types.SMALLINT
|| dataType == Types.BIGINT
|| dataType == Types.NUMERIC
|| dataType == Types.FLOAT || dataType == Types.DOUBLE)) {
// this feature is a reference to
// another
// annotation.
// this column is numeric - a match
ColumnMappingInfo fmap = new ColumnMappingInfo();
fmap.setAnnoFieldName(annoFieldName);
fmap.setColumnName(colName);
fmap.setSize(colSize);
fmap.setSqlType(dataType);
mapInfo.getMapField()
.put(colName, fmap);
break;
}
}
}
}
}
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
}
}
}
}
});
// don't map this annotation if no fields match columns
if (mapInfo.getMapField().size() == 0
&& mapInfo.getCoveredTextColumn() == null
&& Strings.isNullOrEmpty(mapInfo.getUimaTypeIdColumnName()))
return null;
// generate sql
StringBuilder b = new StringBuilder("insert into ");
b.append(this.getTablePrefix()).append(mapInfo.getTableName());
b.append("(anno_base_id");
// add coveredText column if available
if (mapInfo.getCoveredTextColumn() != null) {
b.append(", coveredText");
}
// add uima_type_id column if available
if (mapInfo.getUimaTypeIdColumnName() != null) {
b.append(", uima_type_id");
}
// add other fields
for (Map.Entry<String, ColumnMappingInfo> fieldEntry : mapInfo
.getMapField().entrySet()) {
b.append(", ").append(dialect.openQuote())
.append(fieldEntry.getValue().getColumnName())
.append(dialect.closeQuote());
}
b.append(") values (?");
// add coveredText bind param
if (mapInfo.getCoveredTextColumn() != null) {
b.append(", ?");
}
// add uimaTypeId bind param
if (mapInfo.getUimaTypeIdColumnName() != null) {
b.append(", ?");
}
// add bind params for other fields
b.append(Strings.repeat(", ?", mapInfo.getMapField().size())).append(
")");
mapInfo.setSql(b.toString());
if (log.isInfoEnabled())
log.info("sql insert for type " + type.getName() + ": "
+ mapInfo.getSql());
if (log.isDebugEnabled())
log.debug("initMapInfo(" + annoName + "): " + mapInfo);
return mapInfo;
}