/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.tuscany.das.rdb.graphbuilder.impl; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.tuscany.das.rdb.Converter; import org.apache.tuscany.das.rdb.config.Column; import org.apache.tuscany.das.rdb.config.Config; import org.apache.tuscany.das.rdb.config.Table; import org.apache.tuscany.das.rdb.config.wrapper.MappingWrapper; import org.apache.tuscany.das.rdb.config.wrapper.TableWrapper; import org.apache.tuscany.das.rdb.impl.ResultSetShape; import commonj.sdo.Type; public class ResultMetadata { private Map tableToPropertyMap = new HashMap(); private List typeNames = new ArrayList(); private List propertyNames = new ArrayList(); private final ResultSet resultSet; private final ResultSetShape resultSetShape; private final MappingWrapper configWrapper; private Converter[] converters; private Map tableToPrimaryKeysMap = new HashMap(); //JIRA-952 public ResultMetadata(ResultSet rs, MappingWrapper cfgWrapper, ResultSetShape shape) throws SQLException { this.resultSet = rs; this.configWrapper = cfgWrapper; if (shape == null) { this.resultSetShape = new ResultSetShape(rs.getMetaData(), configWrapper.getConfig()); } else { this.resultSetShape = shape; } this.converters = new Converter[resultSetShape.getColumnCount()]; Map impliedRelationships = new HashMap(); String schemaName = ""; String idSpell = null; for (int i = 1; i <= resultSetShape.getColumnCount(); i++) { String tableName = resultSetShape.getTableName(i); schemaName = resultSetShape.getSchemaName(i); if (( tableName == null ) || ( tableName.equals(""))) { throw new RuntimeException("Unable to obtain table information from JDBC. DAS configuration must specify ResultDescriptors"); } String typeName = null; if(this.configWrapper.getConfig().isDatabaseSchemaNameSupported()){ typeName = configWrapper.getTableTypeName(schemaName+"."+tableName); } else{ typeName = configWrapper.getTableTypeName(tableName); } String columnName = resultSetShape.getColumnName(i); String colName = ""; if (columnName.regionMatches(true, columnName.length()-3, "_ID", 0, 3)) { idSpell = columnName.substring(columnName.length()-3, columnName.length()); if(this.configWrapper.getConfig().isDatabaseSchemaNameSupported()){ colName = schemaName+"."+columnName; impliedRelationships.put(colName, schemaName+"."+tableName); } else{ colName = columnName; impliedRelationships.put(colName, tableName); } } else if (columnName.equalsIgnoreCase("ID")) { configWrapper.addImpliedPrimaryKey(schemaName, tableName, columnName); } String propertyName = null; if(this.configWrapper.getConfig().isDatabaseSchemaNameSupported()){ propertyName = configWrapper.getColumnPropertyName(schemaName+"."+tableName, columnName); } else{ propertyName = configWrapper.getColumnPropertyName(tableName, columnName); } String converterName = null; if(this.configWrapper.getConfig().isDatabaseSchemaNameSupported()){ converterName = configWrapper.getConverter(schemaName+"."+tableName, resultSetShape.getColumnName(i)); } else{ converterName = configWrapper.getConverter(tableName, resultSetShape.getColumnName(i)); } converters[i - 1] = loadConverter(converterName); typeNames.add(typeName); propertyNames.add(propertyName); Collection properties = (Collection) tableToPropertyMap.get(typeName); if (properties == null) { properties = new ArrayList(); } properties.add(propertyName); tableToPropertyMap.put(typeName, properties); } //System.out.println("tableToPropertyMap "+tableToPropertyMap); fillTableToPrimaryKeysMap(); Iterator i = impliedRelationships.keySet().iterator(); while (i.hasNext()) { String columnName = (String) i.next(); String pkTableName = columnName.substring(0, columnName.indexOf(idSpell));//_id, _Id, _iD, _ID anything String fkTableName = (String) impliedRelationships.get(columnName); List pkTableProperties = (List) tableToPropertyMap.get(pkTableName); if ((pkTableProperties != null) && (pkTableProperties.contains("ID"))) { configWrapper.addImpliedRelationship(pkTableName, fkTableName, columnName); } } // Add any tables defined in the model but not included in the ResultSet // to the list of propertyNames Config model = configWrapper.getConfig(); if (model != null) { Iterator tablesFromModel = model.getTable().iterator(); while (tablesFromModel.hasNext()) { TableWrapper t = new TableWrapper((Table) tablesFromModel.next()); if (tableToPropertyMap.get(t.getTypeName()) == null) { tableToPropertyMap.put(t.getTypeName(), Collections.EMPTY_LIST); } } } } //Now fill tableToPrimaryKeysMap.Complete for whichever tables are there in tableToPrimaryKeysMap, //Also case of implied PK and it is not there in SELECT, provide way to still fill it in //tableToPrimaryKeysMap - the column should be present in Config (though not defed as PK) //And consider the classic case, when we assume all columns to be PKs - when no info //in config for table or "all columns" private void fillTableToPrimaryKeysMap(){ Iterator itr = tableToPropertyMap.keySet().iterator(); while(itr.hasNext()){ String curTableName = (String)itr.next(); boolean treatAllPKs = false;//flag for, when all cols need to be treated as PKs if(tableToPrimaryKeysMap.containsKey(curTableName)){ continue;//don't keep refilling same hashset for each ResultMetadata constructor, } List columnsForTable = null; if(configWrapper.getTableByTypeName(curTableName) != null) { columnsForTable = configWrapper.getTableByTypeName(curTableName).getColumn(); } else if(configWrapper.getTable(curTableName) != null){ columnsForTable = configWrapper.getTable(curTableName).getColumn(); configWrapper.getTable(curTableName).setTypeName(curTableName);//keep configWrapper consistent with Type info } else{ treatAllPKs = true;//can not find table/type, need to consider all columns as PKs } if(columnsForTable != null){ for(int ii=0; ii