001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.jdbc;
012:
013: import com.versant.core.metadata.ClassMetaData;
014: import com.versant.core.metadata.MDStatics;
015: import com.versant.core.jdbc.metadata.JdbcField;
016: import com.versant.core.jdbc.metadata.JdbcClass;
017: import com.versant.core.jdbc.metadata.JdbcColumn;
018:
019: import java.util.ArrayList;
020: import java.util.Comparator;
021: import java.util.Collections;
022:
023: /**
024: * This is used by the JdbcMetaDataBuilder to decide which columns are shared
025: * when several fields in a class heirachy are mapped with the same column
026: * names.
027: *
028: */
029: public class SharedColumnChooser implements Comparator {
030:
031: public SharedColumnChooser() {
032: }
033:
034: /**
035: * Select shared columns for cmd and all of its subclasses.
036: */
037: public void chooseSharedColumns(ClassMetaData cmd) {
038: JdbcClass jdbcClass = (JdbcClass) cmd.storeClass;
039: ArrayList fieldList = new ArrayList();
040:
041: for (int i = 0; i < jdbcClass.fields.length; i++) {
042: JdbcField f = jdbcClass.fields[i];
043: if (f == null)
044: continue;
045: JdbcColumn[] mtc = f.mainTableCols;
046: if (mtc == null)
047: continue;
048:
049: // decide on shared for each main table column for this field
050: for (int j = 0; j < mtc.length; j++) {
051: JdbcColumn c = mtc[j];
052: if (c.shared)
053: continue; // already shared
054:
055: // if this column is part of the primary key then any non-pk
056: // fields using it must have their column set shared = true
057: if (c.pk) {
058: jdbcClass
059: .markColumnsShared(c.name, jdbcClass.table);
060: } else {
061:
062: // find all the fields we have that use this column and
063: // sort them so the the only field that will have
064: // shared = false is first in the list
065: fieldList.clear();
066: jdbcClass.findFieldsForColumn(f.fmd.classMetaData,
067: c.name, fieldList);
068: int n = fieldList.size();
069: if (n > 1) {
070: Collections.sort(fieldList, this );
071: for (int k = 1; k < n; k++) {
072: JdbcField kf = ((JdbcField) fieldList
073: .get(k));
074: kf.findMainTableColumn(c.name).setShared(
075: true);
076: }
077: }
078: }
079:
080: // mark the column shared in all subclass fields
081: jdbcClass.markSubclassColumnsShared(c.name);
082: }
083: }
084:
085: if (((JdbcClass) cmd.storeClass).classIdCol != null) {
086: jdbcClass.markColumnsShared(jdbcClass.classIdCol.name,
087: jdbcClass.table);
088: }
089:
090: //if (Debug.DEBUG) dump(jdbcClass);
091:
092: // now do all of our subclasses
093: if (cmd.pcSubclasses != null) {
094: for (int i = 0; i < cmd.pcSubclasses.length; i++) {
095: chooseSharedColumns(cmd.pcSubclasses[i]);
096: }
097: }
098: }
099:
100: /**
101: * Order JdbcField's so the field that should have shared=false for
102: * columns in common is first.
103: */
104: public int compare(Object o1, Object o2) {
105: JdbcField a = (JdbcField) o1;
106: JdbcField b = (JdbcField) o2;
107:
108: // put simple fields first
109: boolean simpleA = a.fmd.category == MDStatics.CATEGORY_SIMPLE;
110: boolean simpleB = b.fmd.category == MDStatics.CATEGORY_SIMPLE;
111: if (simpleA && !simpleB)
112: return -1;
113: if (!simpleA && simpleB)
114: return +1;
115:
116: // put the field with the least columns first
117: int diff = a.mainTableCols.length - b.mainTableCols.length;
118: if (diff != 0)
119: return diff < 0 ? -1 : +1;
120:
121: // order by fieldNo (i.e. alpha sort on name)
122: return a.fmd.fieldNo - b.fmd.fieldNo;
123: }
124:
125: private void dump(JdbcClass jdbcClass) {
126: System.out.println("\nSharedColumnChooser.dump " + jdbcClass);
127: for (int i = 0; i < jdbcClass.fields.length; i++) {
128: JdbcField f = jdbcClass.fields[i];
129: System.out.println("fields[" + i + "] = " + f);
130: if (f == null)
131: continue;
132: JdbcColumn[] mtc = f.mainTableCols;
133: if (mtc == null)
134: continue;
135: for (int j = 0; j < mtc.length; j++) {
136: JdbcColumn c = mtc[j];
137: System.out.println(" mtc[" + j + "] = " + c);
138: }
139: }
140: System.out.println("---\n");
141: }
142:
143: }
|