private AnnoMappingInfo initMapInfo()

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;
	}