/* * 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.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.apache.tuscany.das.rdb.config.Config; import org.apache.tuscany.das.rdb.config.Relationship; import org.apache.tuscany.das.rdb.config.wrapper.MappingWrapper; import org.apache.tuscany.das.rdb.impl.ResultSetShape; import org.apache.tuscany.sdo.api.SDOUtil; import commonj.sdo.Property; import commonj.sdo.Type; import commonj.sdo.helper.HelperContext; import commonj.sdo.impl.HelperProvider; /** */ public class GraphBuilderMetadata { private final Logger logger = Logger.getLogger(GraphBuilderMetadata.class); private MappingWrapper configWrapper; private final Collection resultSets = new ArrayList(); private String typeURI; private Type rootType; private HelperContext defaultHelperContext = HelperProvider.getDefaultContext(); private HelperContext helperContext = HelperProvider.getInstance().getDefaultContext(); public GraphBuilderMetadata(Collection results, Config model, ResultSetShape shape) throws SQLException { this.configWrapper = new MappingWrapper(model); if (model != null) { this.typeURI = model.getDataObjectModel(); } Iterator i = results.iterator(); while (i.hasNext()) { ResultSet rs = (ResultSet) i.next(); ResultMetadata resultMetadata = new ResultMetadata(rs, configWrapper, shape); resultSets.add(resultMetadata); } } /** * Returns the collection of ResultMetadata objects */ public Collection getResultMetadata() { return this.resultSets; } /** * Returns the set of defined relationships */ public Collection getRelationships() { return configWrapper.getConfig().getRelationship(); } /** * Returns the root Type */ public Type getRootType() { if (this.rootType == null) { if (this.typeURI == null) { createDynamicTypes(); } else { createDynamicRoot(); } } return this.rootType; } public MappingWrapper getConfigWrapper() { return this.configWrapper; } /** * Creates a set of SDO Types based on the query results and supplied config information */ private void createDynamicTypes() { Type root = SDOUtil.createType(helperContext, getDefaultURI(), "DataGraphRoot", false); if (this.logger.isDebugEnabled()) { this.logger.debug("GBMD.createDynamicTypes():created Type for "+getDefaultURI()); } Iterator iter = getResultMetadata().iterator(); while (iter.hasNext()) { ResultMetadata resultMetadata = (ResultMetadata) iter.next(); // Create a Type for each Table represented in the ResultSet Iterator names = resultMetadata.getAllTablePropertyNames().iterator(); while (names.hasNext()) { String tableName = (String) names.next(); if (root.getProperty(tableName) == null) { Type tableType = SDOUtil.createType(helperContext, getDefaultURI(), tableName, false); Property property = SDOUtil.createProperty(root, tableName, tableType); SDOUtil.setMany(property, true); SDOUtil.setContainment(property, true); if (this.logger.isDebugEnabled()) { this.logger.debug("GBMD.createDynamicTypes():CREATING NEW TABLE TYPE & PROPERTY :"+tableName); } } } // TODO tablePropertyMap is temporary until Tuscany-203 is fixed Map tablePropertyMap = new HashMap(); for (int i = 1; i <= resultMetadata.getResultSetSize(); i++) { Property ref = root.getProperty(resultMetadata.getTablePropertyName(i)); if (ref == null) { throw new RuntimeException("Could not find table " + resultMetadata.getTablePropertyName(i) + " in the SDO model"); } // TODO Temporary code to check to see if a property has already been added. // Replace when Tuscany-203 is fixed List addedProperties = (List) tablePropertyMap.get(ref.getName()); if (addedProperties == null) { addedProperties = new ArrayList(); tablePropertyMap.put(ref.getName(), addedProperties); } String columnName = resultMetadata.getColumnPropertyName(i); // TODO temporary check until Tuscany-203 is fixed if (!addedProperties.contains(columnName)) { addedProperties.add(columnName); Type atype = resultMetadata.getDataType(i); SDOUtil.createProperty(ref.getType(), columnName, atype); } } } MappingWrapper wrapper = getConfigWrapper(); Iterator i = getRelationships().iterator(); while (i.hasNext()) { Relationship r = (Relationship) i.next(); String parentName = wrapper.getTableTypeName(r.getPrimaryKeyTable()); String childName = wrapper.getTableTypeName(r.getForeignKeyTable()); if (parentName == null) { throw new RuntimeException("The parent table (" + r.getPrimaryKeyTable() + ") in relationship " + r.getName() + " was not found in the mapping information."); } else if (childName == null) { throw new RuntimeException("The child table (" + r.getForeignKeyTable() + ") in relationship " + r.getName() + " was not found in the mapping information."); } Property parentProperty = root.getProperty(parentName); Property childProperty = root.getProperty(childName); if (parentProperty == null) { throw new RuntimeException("The parent table (" + parentName + ") in relationship " + r.getName() + " was not found."); } else if (childProperty == null) { throw new RuntimeException("The child table (" + childName + ") in relationship " + r.getName() + " was not found."); } Type parent = parentProperty.getType(); Type child = childProperty.getType(); Property parentProp = SDOUtil.createProperty(parent, r.getName(), child); Property childProp = SDOUtil.createProperty(child, r.getName() + "_opposite", parent); SDOUtil.setOpposite(parentProp, childProp); SDOUtil.setOpposite(childProp, parentProp); SDOUtil.setMany(parentProp, r.isMany()); } this.rootType = root; } private String getDefaultURI() { return "http:///org.apache.tuscany.das.rdb/das"; } /** * Create a dynamic root Type to act as a container Type for a set of generated Types * */ private void createDynamicRoot() { Type root = SDOUtil.createType(helperContext, getDefaultURI() + "/DataGraphRoot", "DataGraphRoot", false); List types = getDefinedTypes(); if (types == null) { throw new RuntimeException("SDO Types have not been registered for URI " + typeURI); } Iterator i = types.iterator(); while (i.hasNext()) { Type type = (Type) i.next(); Property property = SDOUtil.createProperty(root, type.getName(), type); SDOUtil.setContainment(property, true); SDOUtil.setMany(property, true); } this.rootType = root; } public List getDefinedTypes() { List types = null; List defaultTypes = null; if (this.typeURI == null) { types = SDOUtil.getTypes(helperContext, getDefaultURI()); defaultTypes = SDOUtil.getTypes(defaultHelperContext, getDefaultURI()); if(defaultTypes != null){ if(types == null) { types = defaultTypes; } else { types.addAll(defaultTypes); } } return types; } types = SDOUtil.getTypes(helperContext, typeURI); defaultTypes = SDOUtil.getTypes(defaultHelperContext, typeURI); if(defaultTypes != null){ if(types == null) { types = defaultTypes; } else { types.addAll(defaultTypes); } } if(rootType != null) types.add(rootType); return types; } }